хранилище данных в реальном времени для журналов веб-доступа

Мы думаем о создании системы хранилища данных для загрузки журналов веб-доступа, которые генерируются нашими веб-серверами. Идея состоит в том, чтобы загружать данные в режиме реального времени.

Мы хотим представить пользователю линейный график данных и дать ему возможность детализировать данные с помощью измерений.

Вопрос в том, как сбалансировать и спроектировать систему так, чтобы;

(1) данные могут быть получены и представлены пользователю в режиме реального времени (‹2 секунды),

(2) данные можно агрегировать по часам и дням, и

(2) поскольку на складе все еще может храниться большой объем данных, и

Наша текущая скорость передачи данных составляет примерно ~ 10 обращений в секунду, что дает нам ~ 800 тыс. Строк в день. Мои простые тесты с MySQL и простой звездообразной схемой показывают, что мои запросы начинают занимать более 2 секунд, когда у нас более 8 миллионов строк.

Возможно ли получить производительность запросов в реальном времени из «простого» хранилища данных, подобного этому, и при этом сохранить много данных (было бы неплохо иметь возможность никогда не выбрасывать какие-либо данные )

Есть ли способы агрегировать данные в таблицы с более высоким разрешением?

У меня такое чувство, что это не совсем новый вопрос (хотя я довольно много гуглил). Может ли кто-нибудь дать баллы таким решениям для хранилищ данных? На ум приходит Splunk.

Может, я слишком многого хватаю.

ОБНОВЛЕНИЕ

Моя схема выглядит так:

  • Габаритные размеры:

    • client (ip-address)
    • сервер
    • url
  • факты;

    • timestamp (in seconds)
    • байт передано

person jrydberg    schedule 30.12.2009    source источник
comment
очень и очень интересный вопрос. это шикарно, я не знаю, но тоже хотел бы узнать об этом ...   -  person Roland Bouman    schedule 31.12.2009


Ответы (4)


Не похоже, чтобы это было проблемой. MySQL очень быстр.

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

Если вы все еще не в состоянии идти в ногу со временем, приобретите больше памяти, более быстрые диски, RAID или более быструю систему в указанном порядке.

Также: никогда не выбрасывать данные, вероятно, плохая идея. Если каждая строка имеет длину около 200 байтов, вы говорите о минимуме 50 ГБ в год, только для необработанных данных журнала. Умножьте минимум на два, если у вас есть индексы. Снова умножьте (как минимум) на два для резервных копий.

Вы можете сохранить все это, если хотите, но, на мой взгляд, вам следует подумать о хранении необработанных данных в течение нескольких недель и агрегированных данных в течение нескольких лет. Для чего-то более старого просто сохраните отчеты. (То есть, если вы не обязаны по закону находиться рядом. Даже в этом случае, вероятно, не дольше 3-4 лет).

person Seth    schedule 30.12.2009
comment
Спасибо за ответ. Буду исследовать MySQL еще немного. Идея заключалась в использовании звездообразной схемы, в которой отметка времени строки журнала помещалась в таблицу фактов. Это снижает количество данных для каждой записи в журнале, но как агрегировать такие данные? Клиент, скорее всего, никогда больше не запросит одну и ту же сущность, поэтому одна и та же строка (клиент, актив, сервер) никогда не будет существовать дважды в таблице. - person jrydberg; 31.12.2009
comment
Для сбора данных я бы сделал одну таблицу с кучей столбцов - если вы сделаете что-то более интересное, вам придется потратить время на открытие других таблиц и выполнение вычислений, пока ваш сервер находится под нагрузкой. Поскольку вы указали, что у вас уже были проблемы с отслеживанием, вы, вероятно, захотите максимально упростить. Если вы настроили подчиненный сервер для нормализации и агрегации (отделение отчетов от ведения журнала), вы можете еще больше снизить нагрузку на главный сервер. - person Seth; 02.01.2010

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

Mozilla много занимается аналитикой веб-сервисов. Мы ежечасно отслеживаем детали и используем коммерческий продукт БД Vertica. Он отлично подойдет для этого подхода, но, поскольку это проприетарный коммерческий продукт, у него другой набор сопутствующих затрат.

Еще одна технология, которую вы, возможно, захотите изучить, - это MongoDB. Это база данных хранилища документов, которая имеет несколько функций, которые делают ее потенциально очень подходящей для этого варианта использования. А именно, ограниченные коллекции (выполните поиск ограниченных коллекций mongodb для получения дополнительной информации)

И операция быстрого увеличения для таких вещей, как отслеживание просмотров страниц, обращений и т. Д. http://blog.mongodb.org/post/171353301/using-mongodb-for-real-time-analytics

person Community    schedule 31.12.2009
comment
Спасибо, я посмотрел на MongoDB, чтобы хранить мои данные, не связанные с отношениями. Может быть, он подходит и для других вещей. Не является ли плохой практикой иметь уникальное измерение для каждого факта, такого как IP-адрес клиента? На мой взгляд, это делает невозможным агрегирование данных в таблицы с более низким разрешением. Или я что-то упустил? - person jrydberg; 31.12.2009
comment
Если все, что вы хотите сохранить, это IP-адрес клиента, вы можете сохранить его как вырожденное измерение. Это все равно будет некрасиво из-за большой мощности, но это можно сделать. По возможности лучше не выделять его в отдельное измерение, потому что объединение двух таблиц с чрезвычайно высокой мощностью очень сложно для производительности. - person ; 02.01.2010

Также обратите внимание на разделение, особенно если ваши запросы в основном обращаются к последним данным; вы можете, например, создавать еженедельные разделы из ~ 5,5 миллионов строк.

При суммировании за день и за час подумайте о том, чтобы иметь измерения даты и времени - вы не указали их, поэтому я предполагаю, что вы их не используете. Идея состоит в том, чтобы в запросе не было никаких функций, таких как HOUR (myTimestamp) или DATE (myTimestamp). Измерение даты должно быть разделено таким же образом, как и таблицы фактов.

Благодаря этому оптимизатор запросов может использовать сокращение секций, поэтому общий размер таблиц не влияет на ответ на запрос, как раньше.

person Damir Sudarevic    schedule 31.12.2009
comment
Правильно ли я понимаю, что в запросе нельзя использовать какие-либо функции? Они так сильно влияют на производительность? Быстрее ли выполнить соединение с временным измерением? - person jrydberg; 31.12.2009
comment
Да, это правильно - имейте в виду, что функция должна оцениваться для каждой строки данных. При правильной настройке предложение WHERE содержит только поля таблицы измерений, константы и `=‹ ›‹ = ›= AND`; если у вас есть функция, предварительно вычислите ее в таблице измерений. - person Damir Sudarevic; 31.12.2009
comment
Также, чтобы оптимизатор запросов использовал сокращение разделов, разрешено только `=‹ ›‹ = ›= BETWEEN`. Когда оптимизатор использует сокращение разделов, сканируются только разделы, содержащие данные WHERE, другие игнорируются - намного быстрее. - person Damir Sudarevic; 31.12.2009

Это стало довольно распространенным приложением для хранения данных. Я много лет запускал один, который поддерживал 20–100 миллионов строк в день с временем отклика 0,1 секунды (из базы данных), более секунды с веб-сервера. Это даже не на огромном сервере.

Объемы ваших данных не слишком велики, поэтому я не думаю, что вам понадобится очень дорогое оборудование. Но я бы все равно выбрал многоядерный, 64-разрядный с большим объемом памяти.

Но вы захотите использовать в основном агрегированные данные, а не подробные данные - особенно для построения графиков временных рядов по дням, месяцам и т.д. Лучше всего, если ваш процесс ETL, который преобразует ваши данные, создает агрегированные данные. Обратите внимание, что совокупность обычно представляет собой просто группировку вашей таблицы фактов.

Как говорили другие, разбиение на разделы - хорошая идея при доступе к подробным данным. Но для агрегированных данных это менее критично. Кроме того, гораздо лучше полагаться на заранее созданные размерные значения, чем на функции или сохраненные процедуры. Обе эти стратегии являются типичными для хранилищ данных.

Что касается базы данных - на моем месте я бы попробовал Postgresql, а не MySQL. Причина в основном в зрелости оптимизатора: postgresql может лучше обрабатывать типы запросов, которые вы, вероятно, будете выполнять. MySQL с большей вероятностью запутается при пятистороннем объединении, будет идти снизу вверх при запуске подзапроса и т. Д. И если это приложение дорого стоит, то я бы рассмотрел коммерческую базу данных, такую ​​как db2, oracle, sql server. Тогда вы получите дополнительные функции, такие как параллелизм запросов, автоматическое переписывание запросов для агрегированных таблиц, дополнительную сложность оптимизатора и т. Д.

person KenFar    schedule 06.01.2010