Redis delete expired key policy for the

Expires Redis database keys are stored in the dictionary expired, you can use the exit key or ttl key or pttl key command to determine whether key expired. If the memory is stored in key-value pairs more, Redis should not affect the query how to ensure the efficiency of the cache can effectively control them? (As far as possible to ensure Redis key is stored in the unexpired key).
This question has three possible answers, representing three different expiration deletion policy:

  • Regularly delete: set expiration time key at the same time, create a timer so that the timer expires key time comes, perform the removal of the key immediately;
  • Inert Delete: faire key expires regardless, but each time get key from the key space, key checks are made has expired, if expired, then it deletes the key, if not overdue return the key;
  • Deleted regularly: every once in a database program to conduct an inspection, which deleted the expired key, as to how much you want to delete expired key, as well as to check the number of databases, the decision by the algorithm.
  • In these three strategies, the first and third are automatically deleted strategy, the second is passive deletion policy.

1. regularly delete:

The timing of the policy to remove memory is the most friendly: by using a timer, the timer deletion strategy can guarantee expired key will be deleted as soon as possible and release the memory occupied by expired key.
On the other hand regularly delete strategy drawback is its CPU time is the most unfriendly: in more expired key, the delete key expired this behavior may consume a considerable amount of CPU time, memory, but not nervous at times very CPU stressful situations, the CPU time on tasks unrelated to delete the current expiration key, undoubtedly server throughput and response time of impact.

2. inert Delete:

Inert policy to remove the CPU time is the most friendly: The program will only remove the key when the target of the key checks were expired, where you can delete the expired key to ensure that the operation will only have to do it in the case, and deleted current treatment is limited to the key, this strategy will not spend any time on the CPU remove other irrelevant expired key.
The disadvantage is inert delete a policy: it is the most unfriendly memory: If a key has expired, but there is still the key remains in the database, as long as this is not expired key is deleted, it will not release the memory occupied .
When using inert delete a policy, if there are a lot of expired key database, which expired key and just have not been accessed, then they may never be deleted (unless the user manually perform FLUSHDB), we can even this situation as a kind of memory leak - useless junk data memory intensive, and the server can not release them themselves, for the operation of the state is very dependent on memory Redis server is certainly not good news.
2.1 inert delete achieve policy:
expired key inert deletion policy implemented by db.c / expireIfNeeded function, all read and write the database Redis commands before executing will call expireIfNeeded function of the input key to check:

  • If the input key has expired, then expireIfNeeded function of the input key is deleted from the database;
  • If the input key is not expired then expireIfNeeded function does nothing.
    ExpireIfNeeded function call as follows:
    Write pictures described here
    expireIfNeeded function like a filter, it can actually execute before the command to filter out expired input key, so as to avoid contact with the expired command key. Moreover, because each key being accessed may be deleted due to expire expireIfNeeded function, the function of the realization of each command must be able to handle key presence and absence:
  • When the key is present: the command executed in the presence of a key;
  • When the key does not exist or is deleted because of expired expireIfNeeded functions, commands executed in case key does not exist.

3. regularly delete:

Regular deletion policy strategies and is regularly delete inert delete a compromise strategy, taking into account both memory usage and CPU time into account, but the difficulty of this strategy is to identify and delete frequency market operations performed:
1) If the delete operation performed too frequently or execution time is too long, regularly delete the policy will degenerate into a timed delete a policy that will consume excessive CPU above the delete key expiration time;
2) If you remove too little execution, or the time is too short to perform the operation, strategy and will regularly delete inactive deletion policy as a waste of memory situation occurs.
3.1 periodically delete implementation strategies of:
periodically delete the policy implemented by the realization expire.c / activeExpireCycle function. Whenever the server periodically performs Redis server.c / activeExpireCycle function, activeExpireCycle function is called, it is within the predetermined time, a plurality of times to traverse each database server, checks a portion of the random key from the dictionary database expires expiration time, and delete the expired key. The whole process can be described in pseudo-code as follows:

#默认每次检查的数据库数量
DEFAULT_DB_NUMBERS = 16
#默认每个数据库检查的键数量
DEFAULT_KEY_NUMBERS = 20
#全局变量,记录检查进度
current_db = 0
def activeExpireCycle():
#初始化要检查的数据库数量
#如果服务榕的数据库数量比DEFAULT DB NUMBERS 要小
#那么以服务器的数据库数量为准
if server.dbnum < DEFAULT_DB_NUMBERS :
db_numbers = server.dbnum
else :
db_numbers = DEFAULT_DB_NUMBERS
#遍历各个数据库
for i in range(db_numbers) :
#如果current_db 的值等于服务榕的数据库数量
#这表示检查程序已经遍历了服务榕的所有数据库一次
#将current_db重置为0 ,开始新的一轮遍历
if current_db == server.dbnum:
current_db = 0
#获取当前要处理的数据库
redisDB = server.db[current db)
#将数据库索引增1 ,指向下一个要处理的数据库
current_db += 1
#检查数据库键
for j in range(DEFAULT_KEY_NUMBERS):
#如果数据库中没有一个键带有过期时间,那么跳过这个数据库
if redisDB.expires.size () == 0: break
# 随机获取一个带有过期时间的键
key with_ttl = redisDb.expires.get_random_key ()
#检查键是否过期,如果过期就删除它
if is_expired (key with ttl):
delete_key (key_with_ttl )
#已达到时间上限,停止处理
if reach_time_limit(): return

activeExpireCycle function mode of operation can be summarized as follows:

  • Function each run, a number key are randomly taken from a number of database and checks and removes outdated key therein;
  • Global variables current_db will record the progress of the current activeExpireCycle function check, and then on the next activeExpireCycle time schedule for processing when it is called.
  • With the implementation of activeExpireCycle function, all database server will be checked again, this time function resets current_db variable to 0, and then start a new round of inspections again.

    When calling strategies need to periodically delete pass a type parameter is used to distinguish the "fast mode" or "normal mode."
    Under "normal mode", it will traverse the library next to each number, and then get up to 20 random key with expiration time (20 is the default macro ACTIVE_EXPIRE_CYCLE_LOOKUPS_PER_LOOP's), if the key is too much of a direct return. Then call redis.c / activeExpireCycleTryExpire function tries to delete it, you can delete the expired successfully re-sent to subscribers to notify pub. Timing length periodically delete is 100ms.

In Redis server actually uses inert deletion policies and strategies on a regular basis to delete two strategies: deleted by the combined use of these two strategies, the server can be very good in the rational use of CPU time and strike a balance between avoiding a waste of memory space.

Published 46 original articles · won praise 13 · views 60000 +

Guess you like

Origin blog.csdn.net/luliuliu1234/article/details/81427587