Ограниченный лог активности на LIST
Предпосылки: Клиенты и соединения, LIST.
Нужно хранить последние 100 действий пользователя: логины, изменения настроек, действия в интерфейсе. Данные эфемерные — нужны для отображения в личном кабинете, аналитика строится по другим источникам.
PostgreSQL справится, но каждое действие — это INSERT + обновление индексов + VACUUM мёртвых строк при удалении старых записей. Для данных, которые нужны только «последние 100 штук» и потеря которых при перезагрузке Redis не критична, это избыточная нагрузка на базу. Redis LIST решает задачу проще: LPUSH добавляет элемент в начало списка, LTRIM обрезает список до заданной длины.
def log_activity(user_id, action)
key = "user:#{user_id}:activity"
REDIS.with do |r|
r.lpush(key, { action: action, at: Time.now.iso8601 }.to_json)
r.ltrim(key, 0, 99)
end
end
def recent_activity(user_id, limit: 20)
key = "user:#{user_id}:activity"
REDIS.with do |r|
r.lrange(key, 0, limit - 1).map { |json| JSON.parse(json) }
end
endLPUSH + LTRIM — две команды, а не одна, но порядок гарантирует корректность: после LPUSH список может быть на 1 элемент длиннее лимита, LTRIM тут же обрезает. Даже если процесс упадёт между ними, список будет содержать 101 элемент вместо 100 — не критично.
LRANGE(key, 0, limit - 1) возвращает элементы с начала списка (самые свежие) без удаления. LPUSH и LTRIM выполняются за O(1) (LTRIM удаляет элементы с конца, и при обрезке на 1 элемент это константа). LRANGE — O(limit).