Раздел 37 · Redis с нуля

Продвинутые структуры: HyperLogLog, Bitmaps, Streams, Stack

junior~20 мин

без входаВойди, чтобы отмечать прогресс, вести заметки и решать задачи в редакторе. войти

Строки, списки, множества, хеши и sorted sets закрывают большую часть задач. В прошлом уроке мы собрали на них блокировку. Но у Redis есть ещё несколько структур для особых случаев. Каждая решает одну задачу, зато так, как обычные структуры не умеют: в тысячи раз экономнее по памяти или с готовыми командами. Этот урок обзорный: пробуем каждую на зубок, а три из них дальше разберём подробно.

Набор инструментов

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

Со структурами Redis так же. Посчитать уникальных посетителей можно множеством: SADD, потом SCARD. Но миллион посетителей в множестве займёт десятки мегабайт, а специальная структура уложится в 12 килобайт. Вот четыре таких «коронки», все они есть в обычном Redis 7.

Bitmaps: строка из битов

Задача: отметить, какие пользователи заходили в магазин сегодня. Пользователей миллион, у каждого номер.

Битовая карта это строка, в которой каждый бит отвечает за одного пользователя. Номер пользователя это номер бита. Зашёл пользователь 7, ставим бит 7 в единицу:

127.0.0.1:6379> SETBIT visits:2026-10-10 7 1
(integer) 0
127.0.0.1:6379> SETBIT visits:2026-10-10 42 1
(integer) 0
127.0.0.1:6379> SETBIT visits:2026-10-10 7 1
(integer) 1
127.0.0.1:6379> GETBIT visits:2026-10-10 42
(integer) 1
127.0.0.1:6379> BITCOUNT visits:2026-10-10
(integer) 2

SETBIT возвращает старое значение бита: при втором визите пользователя 7 бит уже был единицей. BITCOUNT считает единицы, это число пользователей, заходивших сегодня. Миллион пользователей это миллион битов, около 125 килобайт на день. TYPE для такого ключа ответит string: битовая карта это не отдельный тип, а способ работать со строкой. Подробно в уроке про битовые карты.

HyperLogLog: уникальные приблизительно

Задача: сколько разных людей посмотрели страницу книги. Множество хранило бы каждого посетителя. HyperLogLog самих посетителей не хранит. Он запоминает только сводку, по которой можно оценить их число:

127.0.0.1:6379> PFADD uniq:book:1 user:7 user:9 user:7 user:12
(integer) 1
127.0.0.1:6379> PFCOUNT uniq:book:1
(integer) 3

user:7 пришёл дважды, а посчитан один раз. Цена экономии в точности: на больших числах PFCOUNT ошибается в среднем на 0,81%. Для счётчика «страницу посмотрели 1,2 млн человек» это неважно, а вот достать список посетителей уже нельзя. Подробно в уроке про HyperLogLog.

Geo: точки на карте

Задача: показать покупателю ближайшие магазины. Гео-команды хранят точки с координатами и ищут по расстоянию. Долгота идёт первой, потом широта:

127.0.0.1:6379> GEOADD shops 37.6173 55.7558 center 30.3141 59.9386 nevsky
(integer) 2
127.0.0.1:6379> GEODIST shops center nevsky km
"634.3729"
127.0.0.1:6379> GEOSEARCH shops FROMLONLAT 37.62 55.75 BYRADIUS 5 km ASC
1) "center"

От магазина в центре Москвы до магазина на Невском 634 километра. В радиусе 5 километров от точки покупателя нашёлся только center. Внутри это обычный sorted set: TYPE shops ответит zset. Подробно в уроке про гео-команды.

урок из курса

Урок из курса «Redis с нуля». Курс покупается один раз и остаётся навсегда: 500 ₽.

Оплата пока не подключена: премиум и курсы открываются промокодом.