4.2Kпросмотров
46.7%от подписчиков
9 марта 2026 г.
Score: 4.6K
Cuckoo filter в Redis: учет использования промокодов с возможностью удаления. Продолжаем серию постов про верятностные структуры Redis. Автор серии - Константин Ратвин (МФТИ). На этот раз смотрим на Cuckoo-фильтр. Задача: промокод должен применяться один раз. Если заказ отменили или оплата не прошла, промокод нужно снова сделать доступным. В ChocoCart используются миллионы одноразовых промокодов. Нам важно быстро проверять, не применялся ли код ранее, и при этом уметь «снимать» отметку об использовании при отмене заказа. Архитектурное решение — «Два слоя»:
🤩 Оперативный слой (Cuckoo filter): быстрый предфильтр «похоже, код уже использовали». Хранит компактные отпечатки и снижает накладные расходы по памяти по сравнению с хранением полного списка использованных кодов.
🤩 Точный слой (Источник истины): атомарная фиксация факта использования (в БД или через SET … NX в Redis). Инициализация фильтра на период (например, месяц акции) CF.RESERVE choco:cf:coupons_used:2026-01 1000000
EXPIRE choco:cf:coupons_used:2026-01 2764800 # ~32 дня с запасом Применение промокода. Проверка в фильтре (быстро, с возможными ложноположительными ответами): CF.EXISTS choco:cf:coupons_used:2026-01 "coupon:DARK_FRIDAY:u:1042" Если фильтр отвечает «возможно, использован», это повод сделать точную проверку/фиксацию в источнике истины.
Точная фиксация (решение принимаем по атомарной записи): SET choco:coupon_used:DARK_FRIDAY:u:1042 1 EX 2764800 NX Если SET … NX вернул OK, промокод применен впервые — добавляем отметку в фильтр: CF.ADD choco:cf:coupons_used:2026-01 "coupon:DARK_FRIDAY:u:1042" Откат (отмена заказа/реверс). При отмене снимаем точную фиксацию и удаляем отметку из фильтра: DEL choco:coupon_used:DARK_FRIDAY:u:1042
CF.DEL choco:cf:coupons_used:2026-01 "coupon:DARK_FRIDAY:u:1042" Cuckoo filter может давать ложноположительные ответы: иногда он сообщает «уже использовано», хотя точной фиксации нет. Поэтому фильтр используется как оперативная подсказка/предфильтр, а окончательное решение опирается на точный слой (SET … NX или БД). Важное правило: удалять (CF.DEL) можно только те элементы, которые вы точно добавляли. Если попытаться удалить «фантомный» ключ (результат ошибки False Positive), то это может привести к ложноотрицательным ответам. Всем, кому интересно изучить Redis на практике с автором этого поста, приглашаем на курс Devhands: Redis и Valkey, от основ к хайлоаду. Все необходимые структуры данных, масштабирование c Sentinel, кластерные возможности и многое другое. Предыдущие посты этой серии:
• Вероятностные структуры в Redis
• HyperLogLog
• Bloom-фильтр