Stream — апенд-онли журнал записей с монотонными ID, хранящийся в датасете Redis (а значит персистентный и реплицируемый). Это «мини-Kafka» внутри Redis, и почти всё в нём вращается вокруг идеи ID.
Записи и ID
XADD orders * product sku-777 qty 2 total 1980
1717000000000-0 # ID: миллисекунды-секвенция
- Формат ID:
мс-секвенция.*просит Redis сгенерировать ID сам (гарантированно монотонный даже при переводе часов назад); - ID можно задавать вручную:
XADD orders 1717000000005-0 ...— полезно для миграций и реплея; - Запись — это плоский словарь «поле-значение»; не бывает записей без полей;
- Чтение диапазоном:
XRANGE orders - + COUNT 10, а такжеXREVRANGE, и «от времени»:XRANGE orders 1717000000000 +.
Чтение: диапазоны и режим подписки
# Всё, что есть
XRANGE orders - +
# Блокирующее чтение новых записей (как tail -f)
# $ = "только то, что появится ПОСЛЕ текущего момента"
XREAD BLOCK 5000 COUNT 100 STREAMS orders $
# С нескольких потоков разом
XREAD BLOCK 5000 STREAMS orders payments $ $
XREAD — это «голый» tail: каждый читатель сам помнит последний ID. Никто не
мешает десяти читателям прочитать один и тот же поток независимо — поток не «съедается»
чтением.
Удержание размера: MAXLEN и XTRIM
# При записи: обрезать до ~100k записей (тильда = приблизительно, быстрее)
XADD orders MAXLEN ~ 100000 * product sku-1 qty 1
# Периодическая обрезка отдельной командой
XTRIM orders MAXLEN ~ 100000
# Или по времени (Redis 6.2+): хранить последние 7 дней
XTRIM orders MINID ~ $(date -d '7 days ago' +%s)000-0
⚠️ Stream без обрезки растёт бесконечно и выест память. Стратегия retention — обязательная часть дизайн-дока потока: сколько записей/дней вам реально нужно.
Внутреннее устройство
Записи упакованы в listpack'и по ~100 штук, а дерево по префиксам ID (radix tree) ведёт к ним.
Отсюда: дешёвый append в конец, эффективные диапазоны, компактное хранение. Счётчик длины —
XLEN — O(1).
Ограничения самого потока
- Полей в записи может быть много, но крупные значения раздувают память — тот же принцип, что и для ключей;
- Нет «топиков» с динамическими подписками — канал вы создаёте сами ключом
(
orders— это просто ключ типа stream); - Конкуренция потребления и ACK — это consumer groups (следующий урок): один XREAD без групп не даёт «взять задание».
Практика
- Создайте поток, добавьте 100 записей скриптом, прочитайте диапазоны: последние 10
(XREVRANGE + COUNT 10), «за последнюю минуту» (XRANGE от
now-60000). - Запустите
XREAD BLOCK 0 STREAMS s $и добавляйте записи из другого терминала — убедитесь в realtime-поведении. - Настройте retention: XADD с MAXLEN ~ 100 и убедитесь, что XLEN не растёт дальше ~120.
Мини-квиз
1. Что означает ID 1717000000000-0? — Миллисекунда Unix + секвенция
внутри этой миллисекунды.
2. Двое читателей через XREAD — мешают друг другу? — Нет: чтение не удаляет записи, каждый читает поток независимо.
3. Зачем тильда в MAXLEN ~ 100000? — Приблизительная обрезка целыми узлами дерева — быстрее и почти не превышает лимит.