Upload
valentin-logvinskiy
View
416
Download
0
Embed Size (px)
DESCRIPTION
Big Data aggregation techniques
Citation preview
Big Data aggregation techniques
by Valentin Logvinskiy
А кто ты такой ?● 5 лет опыта в web (кроме фриланса)● 3 года в highload (3k+ request/min)
● 5k requests/min● >1Tb raw data● Real time analytic
Проект
«Big Data как секс у подростков: - все говорят об этом, - никто реально не знает что это такое и что с этим делать, - каждый думает, что другие уже успешно это делают и - каждый заявляет что тоже успешно это делает.» (с) просторы интернета
“Данные становятся большими тогда, когда их размер превращается в самостоятельную проблему” (с) Роджер Магулас
Для нас Big Data началась с 10 млн. записей
И что ? Сколько данных это Big Data ?
➔ HLL (Hyper Log Log)➔ Суммирующие таблицы➔ Partitioning, Sharding
HyperLogLog (HLL)
SELECT COUNT(id) FROM tbl WHERE {...}
SELECT COUNT(DISTINCT token) FROM tbl WHERE {...}
Суммарное количество ивентов по фильтрам
Уникальное количество пользователей по фильтрам
400 msg/second = 24000 msg/minute
1440000 msg/hour = 34560000 msg/day
1 036 800 000 msg/month ( 1 млрд )
Да сколько там тех ивентов !
Мы используем Postgres.Структура таблиц (изначальная)
Фильтры ?
Distinct ?
SELECT COUNT(DISTINCT token) FROM tbl WHERE {...}in 40220 ms -> 11194 unique from 3489541 recordsin 340220 ms -> 27616 unique from 9658465 records
SELECT COUNT(*) FROM ( SELECT token,COUNT(token) FROM tbl WHERE {...} GROUP BY token) q111194 ms -> 27616 unique from 9658465 records
Оптимизация запроса через группировку
Как жить дальше ?
MapReduce !!!!
Проблемы работы с исспользованием MapReduce
● Пользователь должен получить результат за допустимый промежуток времени (5-10 секунд)
● Если использовать препроцессинг (подсчитать все возможные варианты которые может выбрать пользователь) то это будет очень долго
HyperLogLog (HLL)
http://blog.aggregateknowledge.com/tag/hyperloglog/http://metamarkets.com/2012/fast-cheap-and-98-right-cardinality-estimation-for-big-data/https://github.com/aggregateknowledge/postgresql-hll
● Bit observable patterns
● Stochastic averaging
● Harmonic averaging
● KMV (K minimum value)
Как это работает
Postgres + HLL
--- Make a dummy table
CREATE TABLE helloworld (
id integer,
set hll
);
--- Insert an empty HLL
INSERT INTO helloworld(id, set) VALUES (1,
hll_empty());
--- Add a hashed integer to the HLL
UPDATE helloworld SET set = hll_add(set,
hll_hash_integer(12345)) WHERE id = 1;
--- Or add a hashed string to the HLL
UPDATE helloworld SET set = hll_add(set, hll_hash_text
('hello world')) WHERE id = 1;
--- Get the cardinality of the HLL
SELECT hll_cardinality(set) FROM helloworld WHERE id =
1;
SELECT ceil(hll_cardinality(hll_union_agg(set))) FROM unique_hll WHERE (...)
125 ms
42012237 unique, >8000000000 records (80 млрд)
А поможет ?
Но есть нюанс ...
● Занимает много места на жестком диске
● Погрешность до 3%
Суммирующие таблицы
Справимся и так !
Amazon EC2, c1.xlarge (4 CPU, 420Gb)
SELECT COUNT(id) FROM event WHERE {...}
Да, да, да. Индексы стоят, работают. Да, partitioning тоже включен и работает.
55 ms -> 342282 records 1714 ms -> 4014783 records7524 ms -> 20109099 records
Что делать ?
Для связывания этих таблиц исспользуется тригер OnInsert который делает +1 в поле cnt, если совпадают event_type,campaign_id,item_id,date.
Но есть нюанс...
Batch insert
2014-02-10 00:20:39 UTC [21166]: [3-1] user=****,db=**** ERROR: deadlock detected2014-02-10 00:20:39 UTC [21166]: [4-1] user=****,db=**** DETAIL: Process 21166 waits for ShareLock on transaction 1623260082; blocked by process 21162. Process 21162 waits for ShareLock on transaction 1623260084; blocked by process 21164. Process 21164 waits for ExclusiveLock on tuple (16351,53) of relation 87300951 of database 16422; blocked by process 21166.
INSERT INTO tbl VALUES (...),(...),(...),(...)
Выход ?1. Переписать код на UPDATE и убрать тригерры
2. Игнорировать ошибку, уменьшив уровень изолированости транзакций
3. Ваш вариант
Partitioning
Для чего это нужно?
SELECT COUNT(*) FROM events WHERE date > ‘2014-01-01’ AND date < ‘2014-02-01’
20569s -> 66527031 from 200109099 records
Partitioning by date
Postgres partitioningCREATE TABLE events_01_2014 ( CHECK ( event_date >= DATE ‘2014-01-01’ AND event_date < DATE ‘2014-02-01’ )) INHERITS (events);
+ триггер, окончание которого:RETURN NULL;
Что делать если нет таблицы ?Добавляем в триггер
IF NOT EXISTS( SELECT * FROM information_schema.tables WHERE table_name = tableName) THEN EXECUTE 'CREATE TABLE '||tableName||' (...) INHERITS (‘||TG_TABLE_NAME||’);';END IF;
Поможет ?
2569s -> 66527031 from 66703033 records
Sharding
Зачем это нужно ?
Sharding by event type
Таблицы каждого типа находятся на своих серверах БД, что существенно уменьшает загрузку CPU
Q & A
Thank you !