pulsedb

212 views
Skip to first unread message

Evgeny M

unread,
Jan 25, 2014, 7:21:47 AM1/25/14
to erlang-...@googlegroups.com
Максим, как у этой базы дела с производительностью? Если допустим в нее собирать статистику по посещениям сайта, она потянет 500-1000 записей в секунду на SSD? Сохранять при этом данные о стране посетителя, странице, времени посещения. 
Что потом будет со скоростью выборки, например "получить статистику хитов для определенной страницы за день аггрегированную по часам" или "получить все страны, с которых был заход на определенную страницу в течение заданного часа" - как долго будет думать БД при таких запросах и самое главное сколько она при этом съест памяти, если в БД сохранено 50 миллионов событий? Вообще есть способ указать ей параметры, по которым делать автоматическую аггрегацию за час/день?

Max Lapshin

unread,
Jan 25, 2014, 7:55:39 AM1/25/14
to erlang-...@googlegroups.com
Поясню, что речь идет про https://github.com/flussonic/pulsedb

Это база данных для равномерных временных рядов (хранится всё с шагом в секунду), которая укладывается примерно в два байта на один тик. Она может встраиваться как либа и запускаться как отдельный сервер.


С производительностью сейчас ситуация такая:  машина на 2 cpu взятая на digitalocean пишет примерно 200 записей в секунду, требует для этого около 10% от двух ядер и 40 мегабайт памяти.

утилизация диска по iostat не превышает 0.5% и это не предел, совершенно точно понятно как ещё уменьшать дисковую запись ценой надежности.


Важно понимать, что pulsedb — это не анализатор лога, это прежде всего база данных для _равномерных_ временных рядов. Подробнее я про это рассказывал тут: http://levgem.livejournal.com/460103.html
Т.е. если у вас идет поток запросов, вам нужна какая-то штука, которая в памяти склеит данные по запросам за одну секунду, посчитает всякие медианы, средние и перцентили и выдаст из себя 1000 разных метрик.

Причем, метрики могут быть такого вида:

hits 1390654145  10 page=/goods/cameras/canon-ios5d,group=goods/cameras,website=photo.ru,vendor=canon
hits 1390654145  25 page=/goods/cameras/olympus-a1,group=goods/cameras,website=photo.ru,vendor=olympus


после чего можно будет сделать выборки вида:

sum:hits{vendor=canon}

или 

sum:hits{website=photo.ru}

Тут важно не забыть и не запихнуть агрегат в базу:

hits 1390654145  10 page=/goods/cameras/canon-ios5d,group=goods/cameras,website=photo.ru,vendor=canon
hits 1390654145  25 website=photo.ru,vendor=canon


если сделать вот так, то будете считать одно и то же.



Алгоритм чтения достаточно топорный:  вычитываются целые сутки по метрикам, которые удовлетворяют, склеиваются, данные идут в аккумулятор.  Мы уменьшим гранулярность до одного часа, но в целом расход памяти считается примерно так:  M*86400*C + D*C, где M — количество метрик, которые удовлетворили запросу, D — количество точек, которое ожидается в результирующем ряду, C — некая эмпирическая константа на размер инта в эрланге и сборщик мусора.


При этом подписка на запрос столько памяти не жрет, потому что считает только из памяти.


Возможности сохранить агрегат на диск и держать там, скажем, минутные тики, пока нет.

Evgeny M

unread,
Jan 25, 2014, 8:49:53 AM1/25/14
to erlang-...@googlegroups.com
Ясно, спасибо!
Было бы замечательно, если бы можно было настраивать гранулярность. Иногда нужна статистика только по часам и дням и выборки только по одному параметру, количесто вариаций которого ограничено, как в моем случае - выборка по странице (точнее по URL API). 
Сильно бы сэкономило ресурсы, особенно RAM. Сейчас у меня все это делается вручную через пул gen_server с ets-таблицами, которые собирают аггрегаты для кажой страницы, раз в три минуты дампают себя на диск на случай внезапной кончины ноды, и по истечении часа и суток записывают агрегаты в отдельную талицу hanoidb с автоматическим экспайром 30 дней. Работает очень быстро, но хотелось бы упростить.

суббота, 25 января 2014 г., 16:55:39 UTC+4 пользователь Max Lapshin написал:

Max Lapshin

unread,
Jan 25, 2014, 9:11:56 AM1/25/14
to erlang-...@googlegroups.com
О, про hanoidb я совсем забыл, клевая же штука.

Надо понимать, что у нас очень и очень узкозаточенная штука, которая умеет крайне компактно писать данные.

Одна метрика за сутки занимает 192 килобайта (86400 замеров любого размера).

Max Lapshin

unread,
Jan 25, 2014, 12:37:54 PM1/25/14
to erlang-...@googlegroups.com
Ты бы показал пример, как пользуешься hanoidb

Evgeny M

unread,
Jan 25, 2014, 1:33:32 PM1/25/14
to
там особо нечего показывать

Открываю в Init gen_server:
{ok, Ref} = hanoidb:open("database/db1.hanoidb"),

где-то в handle_call или handle_cast
Key = <<...>>, %%- тут Id страницы + дата + час в binary
hanoi_db:put(Ref, Key, term_to_binary(Data))


ну и читать
case hanoidb:get(Ref) of
        not_found -> {reply, not_found, State};
        {ok, Bin} -> {reply, {ok,  binary_to_term(Bin)}, State}
      end;

Соответственно если надо показать агрегаты за каждый из 24 часов - делается 23 запроса get к hanoidb и один к gen_server, который держит в памяти данные за текущий час. Пользователь админки один, поэтому нагрузка незаметна.

Но подобная статистика это все мелочи
Реальная нагрузка - это отслеживание уникальных IP за 24 часа начиная от сотни запросов в секунду и больше, вот там уже даже не знаю что делать, чтобы увеличить скорость работы на слабых VPS.

суббота, 25 января 2014 г., 21:37:54 UTC+4 пользователь Max Lapshin написал:

Max Lapshin

unread,
Jan 25, 2014, 1:54:39 PM1/25/14
to erlang-...@googlegroups.com
В смысле, сколько уникальных IP заходило на сайт?

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

М?

Evgeny M

unread,
Jan 25, 2014, 2:05:50 PM1/25/14
to erlang-...@googlegroups.com
Нет, не просто сколько уникальных
А на каждый запрос проверять является ли этот IP уникальным для данного url и для всего приложения в целом, и в зависимости от этого делать некие действия. Хэш-таблица это хорошо, когда есть много памяти и данных немного. А при 100 хитах в секунду получаем уже восемь с половиной миллионов записей в день, причем для каждого IP надо хранить сам IP и на каких url он уже сегодня был. Если все хранить в памяти, то с аппетитами эрланга она быстро лопнет. hanoidb с такой нагрузкой кое-как справляется.

суббота, 25 января 2014 г., 22:54:39 UTC+4 пользователь Max Lapshin написал:

Max Lapshin

unread,
Jan 25, 2014, 2:07:54 PM1/25/14
to erlang-...@googlegroups.com
Не знаю, чем именно тут помочь, но pulsedb это не о том. Оно именно для хранения временных рядов. Это лишь часть статистики.

Reply all
Reply to author
Forward
0 new messages