Почему команда Redis DBSIZE не обновляется даже после выполнения «ключей *» - PullRequest
0 голосов
/ 07 мая 2020

Обычно мы используем команду dbsize для подсчета элементов с использованием срока действия. Например, чтобы подсчитать, сколько событий типа X произошло за последние 10 секунд, мы выделяем БД для подсчета этих элементов, вставляя их с истечением срока действия, равным 10 секундам. Значение команды dbsize дает количество элементов.

Я знаю, что ключи с истекшим сроком не отражаются в dbsize, и поэтому мы устанавливаем флаг в этой базе данных с истечением срока, например, 1 se c. Каждый раз, когда мы go проверяем размер базы данных, мы сначала проверяем, истек ли этот флаг. Если истек срок, мы запускаем «keys *», чтобы обновить sh статус ключей, и снова устанавливаем флаг. Таким образом мы обновляем sh статус просроченных элементов только каждую секунду, чтобы не перегружать Redis. Элементов не так много, несколько сотен или тысяч.

Однако сейчас это не работает. Может, что-то изменилось в последней реализации. Даже после выполнения «ключей *» значение dbsize все еще не обновляется. Посмотрите:

Я установил три значения с истечением 10 секунд.

127.0.0.1:6379[20]> set kk1 1 ex 10
OK
127.0.0.1:6379[20]> set kk2 1 ex 10
OK
127.0.0.1:6379[20]> set kk3 1 ex 10
OK

Проверить все ключи:

127.0.0.1:6379[20]> keys *
1) "kk1"
2) "kk2"
3) "kk3"

dbsize возвращает 3:

127.0.0.1:6379[20]> dbsize
(integer) 3

Ключи начинают истекать:

127.0.0.1:6379[20]> keys *
1) "kk2"
2) "kk3"
127.0.0.1:6379[20]> dbsize
(integer) 3

Теперь вот проблема:

127.0.0.1:6379[20]> keys *
(empty list or set)

«ключи *» уже отражают, что срок действия всех ключей истек, поэтому в база данных. Однако dbsize не обновлялся.

127.0.0.1:6379[20]> dbsize
(integer) 3

После того, как «ключи *» указали пустую базу данных, требуется очень много времени, чтобы dbsize действительно обновил свое значение.

Это нарушило функциональность многих работающих сценарии, которые у нас есть.

Я тестирую его на Fedora 30: redis-5.0.7-1.fc30.x86_64

Это работало раньше. Что изменилось?

Есть идеи?

Ответы [ 2 ]

1 голос
/ 07 мая 2020

Вы можете попробовать debug object kk1, чтобы узнать, находится ли ключ в памяти, даже если он не был возвращен keys *.

Я могу придумать только один сценарий, при котором произойдет то, что вы описали:

  1. Вы установили конфигурацию lazyfree-lazy-expire yes
  2. Вы сделали debug SET-ACTIVE-EXPIRE 0

Чтобы проверить lazyfree-lazy-expire, попробуйте config get lazyfree-lazy-expire.

Со вторым нельзя проконсультироваться, но вы делаете debug SET-ACTIVE-EXPIRE 1 для обеспечения нормального режима.

0 голосов
/ 07 мая 2020

Ну не нашел способ обновить dbsize.

Итак, я считаю. Вместо использования результата dbsize я использую:

local allKeys = redis.call( "keys", "*" )
totalKeys = #allKeys - 1 -- -1 is for not counting totalKeys itself

И вставляю totalKeys обратно в Redis, чтобы использовать это значение до следующего обновления sh.

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