Лучший способ создать масштабируемую систему хитов / аналитики? - PullRequest
8 голосов
/ 12 апреля 2009

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

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

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

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

Кто-нибудь еще лучше знает, как решить эту проблему?

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

Ответы [ 4 ]

4 голосов
/ 12 апреля 2009

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

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

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

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

РЕДАКТИРОВАТЬ: Оказывается, Катманду +5,45 по Гринвичу, поэтому вам нужно будет хранить данные в 15-минутных, а не 30-минутных.

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

2 голосов
/ 12 апреля 2009

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

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

0 голосов
/ 12 апреля 2009

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

0 голосов
/ 12 апреля 2009

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

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...