对于Redis中过期key的操作

520次阅读
没有评论

共计 3304 个字符,预计需要花费 9 分钟才能阅读完成。

对于Redis中过期key的操作

redis实例key数量统计信息

使用dbsize查看

127.0.0.1:6379[1]> dbsize
(integer) 2556
127.0.0.1:6379[1]> select 0
OK
127.0.0.1:6379> dbsize
(integer) 1

使用info查看

127.0.0.1:6379> info keyspace
# Keyspace
db0:keys=1,expires=0,avg_ttl=0
db1:keys=2499,expires=65,avg_ttl=69453573
  • db[num]:代表数据库编号
  • keys:代表有多少key
  • expires:代表设置了TTL的keys数量
  • avg_ttl:代表所有含有TTL的key的平均剩余时间,单位为秒
127.0.0.1:6379[1]> info stats
# Stats
total_connections_received:957
total_commands_processed:82588
instantaneous_ops_per_sec:0
total_net_input_bytes:42483858
total_net_output_bytes:408848674
instantaneous_input_kbps:0.00
instantaneous_output_kbps:0.00
rejected_connections:0
sync_full:0
sync_partial_ok:0
sync_partial_err:0
expired_keys:130
expired_stale_perc:0.00
expired_time_cap_reached_count:0
evicted_keys:0
keyspace_hits:96489
keyspace_misses:5594
pubsub_channels:0
pubsub_patterns:0
latest_fork_usec:377
migrate_cached_sockets:0
slave_expires_tracked_keys:0
active_defrag_hits:0
active_defrag_misses:0
active_defrag_key_hits:0
active_defrag_key_misses:0
  • expired_keys:代表已过期但未删除的key

redis的key过期设置

设置过期时间

EXPIRE key seconds
PEXPIRE key milliseconds
  • expire:设置key多少秒过期
  • pexpire:设置key多少毫秒过期

查看key过期时间

TTL mykey
  • 返回值大于0:代表多少秒后过期
  • 返回值-1:表示该key没有设置过期时间
  • 返回值-2:表示该key不存在

redis中key的过期配置

过期key不是立即删除,过期的key会在一定条件下进行惰性删除。具体来说,当一个过期的key被访问时,Redis会检查这个key是否过期,如果过期就删除它(返回空值(nil))。这样做的好处是可以减少Redis服务器在清理过期key时的负担,提高系统性能。但同时也意味着,如果有一些过期的key长时间没有被访问,那么它们可能会一直存在于数据库中,直到Redis服务器进行内存回收时才会被删除。

有几个可能的原因导致 Redis 中的过期键没有被及时删除:

  1. Redis 定期删除过期键的任务未执行。Redis 会以 1s 为单位检查是否有过期键需要删除,并在需要时执行删除操作。如果 Redis 的主线程被阻塞了(比如正在执行一个长时间的命令),那么这个定期删除的任务就可能无法被及时执行。
  2. Redis 机器的内存不足,导致 Redis 没有足够的内存来创建新的键值对。在这种情况下,Redis 会优先删除过期键,但是如果过期键的数量非常大,那么 Redis 可能会因为内存不足而无法创建新的键值对。
  3. Redis 配置了 AOF 持久化,但是 AOF 持久化的刷盘策略为每秒钟刷盘一次,这意味着即使过期键已经被删除了,它们也不会立即从磁盘上删除。如果 Redis 宕机了,那么这些过期键可能会被重新加载到 Redis 中。

如果你的 Redis 中出现了过期键没有被及时删除的情况,你可以通过检查 Redis 的日志和使用 Redis 监控命令来排查问题。

Redis中过期key的删除时间是由配置文件中的两个参数共同决定的:hzmaxmemory

  • hz表示每秒执行多少次过期扫描。它的值默认为10,意味着Redis每秒会执行10次过期扫描。当然,你可以通过修改配置文件来调整这个值,以达到你的需求
  • maxmemory表示Redis可以使用的最大内存。如果Redis的内存使用量超过了这个值,那么就会执行过期扫描以删除过期的key。如果你的系统中有很多过期key需要删除,但是Redis的内存使用量又很高,那么你可以考虑适当调高maxmemory的值,以便更快地删除过期key

需要注意的是,过期key的删除并不是实时进行的,而是通过定期扫描实现的。这也就意味着,有可能某些过期key会被保留一段时间,直到过期扫描定时执行时再被删除。

key过期删除策略参数

  1. noeviction:在达到最大内存限制时,所有写入操作(SET、LPUSH、RPUSH等)都会报错,或者简单地返回一个错误,从而阻止写入操作继续执行。配置参数:maxmemory-policy noeviction
  2. allkeys-lru:当达到最大内存限制时,在所有键中选择最近最少使用的键进行删除。配置参数:maxmemory-policy allkeys-lru
  3. volatile-lru:当达到最大内存限制时,在设置了过期时间的键中选择最近最少使用的键进行删除。配置参数:maxmemory-policy volatile-lru
  4. allkeys-random:当达到最大内存限制时,在所有键中随机选择一个进行删除。配置参数:maxmemory-policy allkeys-random
  5. volatile-random:当达到最大内存限制时,在设置了过期时间的键中随机选择一个进行删除。配置参数:maxmemory-policy volatile-random
  6. volatile-ttl:当达到最大内存限制时,在设置了过期时间的键中,根据键值对象的过期时间,从小到大进行排序,删除过期时间最早的键。配置参数:maxmemory-policy volatile-ttl

如果你需要实时删除过期key,那么可以通过手动执行DEL命令来实现

使用lua脚本批量删除过期key

KEYS_PATTERN:用来匹配设置了TTL的key,因为过期key和未设置过期时间的key的TTL返回值都是-1,所以在操作前,需要过滤设置了TTL的key,这个需要咨询业务开发,避免把没有设置过期的key也删了!!!

local cursor = "0"
repeat
    local keys = redis.call("SCAN", cursor, "MATCH", KEYS_PATTERN, "COUNT", BATCH_SIZE)
    cursor = keys[1]
    local key_batch = keys[2]
    for i, key in ipairs(key_batch) do
        if redis.call("TTL", key) < 0 then
            redis.call("DEL", key)
        end
    end
until cursor == "0"

执行脚本

redis-cli --eval delete_expired_keys.lua

使用python批量延长key的过期时间

import redis

client = redis.Redis(host='localhost', port=6379)

# 过滤匹配的key
# client.scan_iter(match='prefix:*')
# 遍历所有的key
for key in client.scan_iter():
    # 获取key的剩余过期时间
    ttl = client.ttl(key)
    # 如果剩余过期时间小于60秒,则延长过期时间
    if ttl > 0 and ttl < 60:
        client.expire(key, 600)

正文完
 
xadocker
版权声明:本站原创文章,由 xadocker 2021-01-17发表,共计3304字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
评论(没有评论)