Comments 12
А я правильно понимаю, что у вас в итоговом агрегате для одного пользователя осталась только одна строка. Грубо говоря, это результат запроса
select user_id, dt, count(), avg(),…
from table
group by user_id, dt
select user_id, dt, count(), avg(),…
from table
group by user_id, dt
0
Всё верно, в агрегате по пользователям для конкретного сервиса: 1 строка на 1 пользователя на 1 дату.
dt, user_id,… cols_about_user ....,… metrics…
dt, user_id,… cols_about_user ....,… metrics…
+2
И этого уровня достаточно для аналитики?
1) Ведь вы сразу потеряли хотя бы что-то близкое к real-time
2) Теряется возможность посчитать достаточно много метрик, например перцентили, воронки.
1) Ведь вы сразу потеряли хотя бы что-то близкое к real-time
2) Теряется возможность посчитать достаточно много метрик, например перцентили, воронки.
0
Какой прекрасный семейный вечер на КДПВ.
0
Только я вижу на КДПВ трёх зомбяков?
для тех кому лень листать вверх
0
Событие доставляется в буферную таблицу на нужный шард, исходя из остатка от деления некоторого hash от user_id на количество шардов в кластере. Далее буферная таблица сбрасывает данные в локальную ReplicatedReplacingMergeTree
Расскажите поподробнее пожалуйста как это реализовано? Есть какой-то тип буферной таблицы и как он сбрасывает данные периодически?
В общей сложности в каждой таблице у нас от 50 до 200 колонок, при этом во всех таблицах есть сервисные поля. Например, лог ошибки error_log — на самом деле ошибкой мы называем выход за диапазоны типа. На случай, если в поле с возрастом польются странные значения, выходящие за размеры типа
Можно еще поподробнее про это, если не затруднит? Вы как то обрабатываете ошибки? Имеется в виду, как вы ошибку записываете в отдельное поле?
0
Расскажите поподробнее пожалуйста как это реализовано? Есть какой-то тип буферной таблицы и как он сбрасывает данные периодически?
Речь идёт о движке Buffer(database, table, num_layers, min_time, max_time, min_rows, max_rows, min_bytes, max_bytes)
Из документации:
Данные сбрасываются из буфера и записываются в таблицу назначения, если выполнены все min-условия или хотя бы одно max-условие. min_time, max_time — условие на время в секундах от момента первой записи в буфер; min_rows, max_rows — условие на количество строк в буфере; min_bytes, max_bytes — условие на количество байт в буфере.
Обычно мы используем с такими параметрами:
Buffer(database, table, 2, 10, 10, 10000000, 10000000, 100000000, 100000000);
Можно еще поподробнее про это, если не затруднит? Вы как то обрабатываете ошибки? Имеется в виду, как вы ошибку записываете в отдельное поле?
У нас буквально в таблице есть has_errors Int8, который служит для быстрого фильтра на предмет наличия ошибок и их количества. Также есть error_log String — строковое поле…
Когда на бэкенде формируется запрос на вставку, то происходит валидация полей на предмет
а) соответствия заданному типу
б) на то, что значение не выходит за размер типа.
В случае, если что-то не выполняется, в error_log пишется сообщение с указанием, что именно пошло не так, само значение заменяется на default значение для типа данных, а получившаяся строка пытается вставиться.
Пример, если я в поле amount Int64 по каким-то причинам буду пытаться с backend вставить строку, то сам ивент вставится, а я получу has_error = 1, error_log = 'amount not numeric', а в поле amount = 0 — дефолтное значение типа.
0
Отличная статья, спасибо!
Скажите пожалуйста, какое количество типов продуктовых событий вы ожидаете?
Наш опыт проектирования подобной штуки показал, что при наличии более 300 событий начинает сильно деградировать система репликации, zookeeper, и т.д.
0
Sign up to leave a comment.
Продуктовая аналитика ВКонтакте на базе ClickHouse