Настройка redis для последовательного выселения старых данных сначала

Я храню кучу данных в реальном времени в redis. Я устанавливаю TTL 14400 секунд (4 часа) на всех клавишах. Я установил maxmemory в 10G, которого в настоящее время недостаточно для размещения 4 часов данных в памяти, и я не использую виртуальную память, поэтому redis выдает данные до истечения срока их действия.

Я в порядке с redis, выдворяя данные, но я бы хотел, чтобы он сначала вырезал самые старые данные. Поэтому, даже если у меня нет полных 4 часов данных, по крайней мере, у меня может быть некоторый диапазон данных (3 часа, 2 часа и т.д.) Без пробелов. Я попытался выполнить это, установив maxmemory-policy=volatile-ttl, считая, что самые старые ключи будут выселены первыми, так как все они имеют один и тот же TTL, но он не работает таким образом. Похоже, что redis выдает данные несколько произвольно, поэтому в итоге я получаю пробелы. Например, сегодня данные с 2012-01-25T13: 00 были выселены до данных с 2012-01-25T12: 00.

Можно ли настроить redis для последовательного выселения более старых данных?

Вот соответствующие строки из моего файла redis.cnf. Дайте мне знать, если вы хотите больше увидеть конфиги:

maxmemory 10gb
maxmemory-policy volatile-ttl
vm-enabled no

Ответы

Ответ 1

AFAIK, невозможно настроить Redis для последовательного выключения старых данных.

Когда опции * -ttl или * -lru выбраны в политике maxmemory, Redis не использует точный алгоритм для выбора ключей, которые нужно удалить. Для точного алгоритма потребуется дополнительный список (для * -lru) или дополнительная куча (для * -ttl) в памяти и перекрестная ссылка на него с нормальной структурой данных словаря Redis. Это было бы дорого с точки зрения потребления памяти.

В текущем механизме выселения происходят в цикле основного события (т.е. потенциальные выселения проверяются на каждой итерации цикла перед каждой командой). Пока память не вернется к пределу maxmemory, Redis случайно выбирает образец из n ключей и выбирает для истечения самый простой (для * -lru) или тот, который ближе всего к его пределу истечения (для * -ttl). По умолчанию рассматриваются только 3 выборки. Результат не детерминирован.

Один из способов повысить точность этого алгоритма и уменьшить проблему - увеличить количество рассмотренных образцов (параметр maxmemory-samples в файле конфигурации). Не устанавливайте его слишком высоко, так как он будет потреблять некоторый процессор. Это компромисс между точностью выселения и потреблением процессора.

Теперь, если вам действительно требуется последовательное поведение, одним из решений является реализация вашего собственного механизма выселения поверх Redis. Например, вы можете добавить список (для не обновляемых ключей) или отсортированный набор (для обновляемых ключей), чтобы отслеживать ключи, которые должны быть выселены первыми. Затем вы добавляете демона, цель которого - периодически проверять (используя INFO) потребление памяти и запрашивать элементы списка/отсортированного набора для удаления соответствующих ключей.

Обратите внимание, что другие системы кэширования имеют свой собственный способ решения этой проблемы. Например, с memcached существует одна структура LRU на плиту (которая зависит от размера объекта), поэтому порядок выселения также не является точным (хотя и более детерминированным, чем с Redis на практике).