3.9Kпросмотров
43.7%от подписчиков
27 февраля 2026 г.
Score: 4.3K
HyperLogLog Это продолжение серии постов про верятностные структуры Redis. Автор серии - Константин Ратвин (МФТИ). Будем рассматривать бизнес-кейс, онлайн-магазин шоколада Wonka ChocoCart! У нас стартовала акция - «Dark Friday»: на темный шоколад скидка. Трафик резко вырос, и вместе с нагрузкой увеличился поток событий. Среди них встречаются повторы, их важно быстро отфильтровать, чтобы не искажать статистику. Вероятностные структуры можно использовать прямо в Redis как обычные ключи, и это удобно: для них работают привычные команды и TTL, а значит, не нужен отдельный сервис. Будем именовать ключи с префиксом choco: и считать по окнам (день/час/15 минут). Формат входного события: Опишем формат входного события:
- event_id — идентификатор события (например, ev:pay:9f2a)
- user_id — идентификатор пользователя (например, u:1042)
- product_id — код товара (например, product:milk_almonds_90g)
- route — ветка/маршрут обработки (например, route:card:pspA или route:sbp:pspA)
- latency_ms — задержка операции (например, /checkout) в миллисекундах На этом потоке хотим быстро получать число уникальных покупателей за сутки, отбрасывать дубли событий, отслеживать тренды и p95/p99 задержек, а также мониторить проблемные платежные ветки. В прошлом посте уже решили, что будем для этого использовать: 🤩 Уникальные покупатели за сутки → HyperLogLog.
🤩 Дедупликация событий → Bloom filter.
🤩 Промокод «уже использован» + отмена → Cuckoo filter.
🤩 Тренды товаров в окнах 5-15 минут → Top-K.
🤩 Частоты по веткам/ошибкам оплаты → Count-Min Sketch.
🤩 p95/p99 задержек → t-digest. Посмотрим, как это применять на практике, начнем с HyperLogLog: уникальные покупатели за день. Задача: оценить сколько уникальных покупателей совершили покупки за сутки.
Во время акции важно понимать, с чем связан рост выручки – с притоком большего числа разных покупателей или с тем, что одни и те же пользователи стали покупать чаще. Для этого полезна метрика «уникальные покупатели за день»: она показывает размер аудитории и не зависит от количества повторных заказов одного и того же пользователя. На каждом событии успешной оплаты добавляем user_id в ключ текущего дня. Один и тот же пользователь может купить несколько раз — но в HLL он будет учтен один раз. Пример: PFADD choco:hll:dau:2026-01-15 "u:1042" "u:887" "u:1042"
PFCOUNT choco:hll:dau:2026-01-15
EXPIRE choco:hll:dau:2026-01-15 93600 # сутки + 2 часа PFCOUNT возвращает приближенную оценку числа уникальных покупателей за день, у Redis типичная относительная ошибка для PFCOUNT — около 0.81% (стандартное отклонение относительной ошибки, не “гарантия ±0.81% всегда”). PFMERGE и агрегация дневных данных. Если вы часто спрашиваете «сколько уникальных за неделю», удобнее не пересчитывать каждый раз набор дней, а собрать сводный ключ: PFMERGE choco:hll:dau:week_ending:2026-01-15 \
choco:hll:dau:2026-01-09 \
choco:hll:dau:2026-01-10 \
choco:hll:dau:2026-01-11 \
choco:hll:dau:2026-01-12 \
choco:hll:dau:2026-01-13 \
choco:hll:dau:2026-01-14 \
choco:hll:dau:2026-01-15 PFMERGE объединяет несколько HyperLogLog в один ключ и позволяет получать оценку уникальных за период, не храня все исходные user_id. Остальные структуры данных рассмотрим в следующих постах. Всем, кому интересно изучить Redis на практике с автором этого поста, приглашаем на курс Devhands: Redis и Valkey, от основ к хайлоаду. Все необходимые структуры данных, масштабирование c Sentinel, кластерные возможности и многое другое.