Лучший способ разработать масштабируемую систему просмотров / аналитики?

StackOverflow https://stackoverflow.com/questions/742073

Вопрос

Компания, в которой я работаю, создает приложения для платформы Blackberry.

Мы работаем над собственной "системой аналитики", которая позволяет нам встраивать код в наши приложения и заставлять приложения сообщать некоторую статистику нашим центральным серверам при каждом запуске.В настоящее время система работает нормально;однако это только в бета-версии со 100-200 посещениями в час."Обращения" отправляются на серверы без проблем.Мы создали очень надежный API для обработки приема и хранения обращений (в базе данных MySQL).Мы протестировали загрузку, и мы должны быть в состоянии без проблем обрабатывать сотни тысяч обращений в час.На самом деле это не проблема.

Проблема в том, чтобы показывать статистику.Мы создали панель отображения, похожую на Mint (haveamint.com), она показывает хиты за каждый час, прошедшие дни, месяцы, недели, годы ... и т.д.Первая версия выполняла прямые запросы, извлекая данные из таблицы обращений и интерпретируя их "на лету".Это работало не очень долго.Наше текущее решение заключается в том, что обращения ставятся в "очередь" для обработки, и каждые 5 минут у нас появляется cron, который собирает обращения и сортирует их по "кэшам" для каждого часа, дня, недели, месяца, года ... и т.д.Это работает потрясающе и невероятно масштабируемо;однако это работает только для 1 часового пояса.Поскольку доступ к этому есть у всей компании, мы имеем дело с несколькими сотнями пользователей в разных часовых поясах.То, что я определяю как "Сегодня" в Сан-Хосе, СИЛЬНО отличается от того, что мой коллега в Лондоне определяет как "Сегодня".Поскольку текущее решение кэшируется только в 1 часовом поясе, это кошмар для всех, кто проверяет данные за пределами нашего часового пояса.

Наш текущий план по исправлению этого заключается в создании кэшей для каждого часового пояса (всего 40).;однако это означало бы, что мы умножаем объем данных на 40 ... для меня это ужасно, и, учитывая, что кэши могут быть очень большими, умножение просто звучит как плохая идея;кроме того, когда мы перейдем к обработке очереди, потребуется намного больше процессорного времени, чтобы поместить их в 40 различных кэшей.

У кого-нибудь еще есть лучшее представление о том, как решить эту проблему?

(Извините за такой длинный question..it не совсем легко объяснить.Спасибо всем!)

Это было полезно?

Решение

Решение, которое вы предлагаете, имеет слишком много избыточности.Я бы посоветовал вам хранить данные как минимум в 30-минутных сегментах вместо почасовых, а часовой пояс нормализовать к UTC.

С помощью 30-минутных сегментов, если пользователь запрашивает почасовые данные за 1-2 часа дня с -4.5 UTC, вы можете извлечь данные за 5:30 - 6:30 вечера из вашей системы и показать это.Если вы храните данные с шагом в один час, вы не сможете обслуживать запросы пользователей в часовых поясах с разницей N + 0,5 часа.

Для ежедневных номеров вам потребуется объединить 48 получасовых интервалов.Выбор слотов будет определяться часовым поясом пользователя.

Это становится интересным, когда вы переходите к годовым данным, потому что в конечном итоге вам приходится агрегировать 17 520 получасовых сегментов.Чтобы упростить это вычисление, я бы посоветовал вам получить предварительно агрегированные годовые данные по времени UTC и вычесть агрегированные данные за первые 4,5 часа года и добавить агрегированные данные за первые 4,5 часа следующего года.Это, по сути, сдвинет весь год на 4,5 часа, а работы не так уж много.Работая отсюда, вы можете дополнительно настроить систему.

Редактировать:Оказывается, в Катманду + 5.45 по Гринвичу, поэтому вам нужно будет хранить данные в 15-минутных пакетах вместо 30-минутных.

ПРАВКА 2:Еще одно простое улучшение связано с ежегодным агрегированием, поэтому вам не нужно каждый раз добавлять 17 520 корзин и не требуется использовать один агрегат для каждой страны.Объедините годовые данные за период с 02 января по 30 декабря.Поскольку максимальная разница в часовых поясах между любыми двумя странами составляет 23 часа, это означает, что вы можете взять годовые данные (02 января - 30 декабря) и при необходимости добавить несколько сегментов до и после.Например, для часового пояса -5 UTC вы бы добавили все сегменты 01 января после 05.00, все сегменты 31 декабря и 01 января следующего года до 05.00 часов.

Другие советы

При разработке программного обеспечения, которое затрагивает несколько часовых поясов, я бы посоветовал всегда сохранять вашу дату / время в UTC с другим полем для исходного часового пояса и имеют функцию, которая принимает время и преобразует его в UTC / часовой пояс и обратно.Вы избавите себя от множества хлопот, связанных с различными случаями перехода на летнее время, людьми, просматривающими статистику из страны с другой стороны земли, и так далее....

В вашем случае наличие кэшей в UTC и простая настройка запросов для преобразования в UTC должны помочь.Не сохраняйте статистику как "сегодняшнюю", сохраняйте ее с 00:00:00 по Гринвичу до 23:59: 59 по Гринвичу, и когда кто-нибудь запросит статистику за сегодняшний день в Нью-Йорке, выполните преобразование.

Насколько я могу судить, вы ищете здесь часть хранилища системы хранилища данных (ваши отчеты будут внешним интерфейсом).

На самом деле, способ, которым коммерческие системы делают это, - это кэш, который вы описали:Предварительно сгруппируйте свои таблицы и создайте из них кэши.Единственный способ ускорить ваши запросы - это заставить систему баз данных делать для них меньше.Это означает меньше данных, что, в свою очередь, означает меньше времени, затрачиваемого на повторение данных, или меньше данных в индексах.

Тем не менее, я бы либо предложил "решение для кэша 40" (действительно ли существует более 24 часовых поясов).Вы должны быть в состоянии тривиально распараллелить очередь сортировки, создав копии данных.

Другим способом сделать это было бы кэшировать с детализацией по часам, а затем объединить часы в дни (или 30 минут, если этого требуют ваши часовые пояса).Это означает, что вы кэшируете с более высокой степенью детализации, чем ваш ежедневный кэш, но с более грубой детализацией, чем исходные данные.

такого рода данные обычно хранятся с использованием циклических баз данных.проверьте это http://www.shinguz.ch/MySQL/mysql_20070223.html и это http://techblog.tilllate.com/2008/06/22/round-robin-data-storage-in-mysql/ чтобы знать, как они работают и как это реализовать под MySQL

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top