Настройка Redis для последовательного удаления старых данных в первую очередь - PullRequest
16 голосов
/ 26 января 2012

Я храню кучу данных в реальном времени в 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 Ответ

30 голосов
/ 30 января 2012

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

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

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

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...