Set of expired keys
In Redis, all keys with expiration dates are stored in a separate dictionary. The dictionary is scanned periodically to check expired keys and delete them.
Periodic scan Policy
By default redis does 10 expiration scans per second, but does not scan all keys. Instead, it uses a simple greedy strategy, as follows:
-
Randomly select 20 keys from the expired dictionary.
-
Delete expired keys from 20 keys.
-
If more than a quarter of the keys are out of date, repeat the above steps.
The problem
If a large number of expiration dates occur, redis may repeat the above steps for a long time, resulting in an endless loop that affects the redis service’s external response. Therefore, the scan policy has a maximum scan time. The default value is no more than 25ms.
If a large number of keys expire at the same time, Redis will scan the expired dictionary repeatedly in a short period of time, and the number of cyclic scanning will not decrease until the keys in the expired dictionary become sparse, which will lead to online read and write requests running out of time. Of course, it is not only the running out of time caused by the running out of keys. The memory manager will recycle pages frequently, which will also consume CPU resources and cause stuttering.
At the same time, a large number of keys expire, and Redis enters the process of expiration scanning. If there is a request from the client at this time, it will wait at least 25ms for processing.
If the client timeout is set to a short time, such as 10ms, then the connection will be closed due to timeout, the business side will have a timeout exception, and slow queries will not be visible in the slowlog because slow queries refer to logical processing time rather than wait time.
Coping strategies
When setting the expiration time for a large number of keys, try to randomly distribute the expiration time. Do not focus on a single expiration point, but add a random expiration time after the actual expiration time. In this way, a large number of keys expire at the same time.
Redis.expire_at (key, random.randint(86400) + expire_ts)Copy the code
Lazy deletion strategy
The lazy policy means that if a client accesses a key with an expiration date, redis checks to see if the key has expired and deletes it if it has.
The lazy deletion policy can be regarded as scattered deletion, while the periodic scan policy is centralized deletion.
The secondary node expires policy
The slave node will not scan the expired key. When the master node’s key is processed, a DEL instruction will be added to the AOF log and synchronized to all slave nodes. The slave node will delete the key in its own memory through this instruction.
Because instruction synchronization is asynchronous, if the master and slave are not synchronized in time, data inconsistency will occur between the master and slave.