[redis] 数据库相关 -- 过期键的删除策略

被动删除策略:惰性删除

每次从键空间中获取键时,都检查键是否过期,过期就删除键。否则就返回键
优点:对 cpu 友好
缺点:占用已过期的键,但还没被删除的内存空间。

	实现函数 expireIfNeeded,位置 db.c / expireIfNeeded;

流程:

所有读写数据库的命令
eg: SET, LRANGE, SADD, HGET, KEYS 等
调用 expireIfNeeded 函数
输入键已经过期?
删除键
执行实际的命令流程

GET 命令流程:

GET < KEY >
键不存在?
键已过期?
删除已过期键
返回空回复
返回 KEY 的值

主动删除策略:定期删除

每个一段时间,redis 程序对数据库进行一次检查,删除过期键。
优点:有效减少内存浪费
缺点:占用部分 cpu

	实现函数 activeExpireCycle,位置如下:
	版本 2.8: redis.c    / activeExpireCycle
	版本 5.0: expire.c  / activeExpireCycle

策略如下:内容来源于《Redis 深度历险:核心原理与应用实践 : 扩展4》

	Redis 默认会每秒进行十次过期扫描,过期扫描不会遍历过期字典中所有的 key,而是采用了一种简单的贪心策略。
		1. 从过期字典中随机 20 个 key;
		2. 删除这 20 个 key 中已经过期的 key;
		3. 如果过期的 key 比率超过 25%,那就重复步骤 1;
		同时,为了保证过期扫描不会出现循环过度,导致线程卡死现象,算法还增加了扫描时间的上限,
		默认不会超过 25ms。
	
	若 Redis 实例中所有的 key 在同一时间过期了,会出现怎样的结果?
				毫无疑问,Redis 会持续扫描过期字典 (循环多次),直到过期字典中过期的 key 变得稀疏,
		才会停止 (循环次数明显下降)。这就会导致线上读写请求出现明显的卡顿现象。
		导致这种卡顿的另外一种原因是内存管理器需要频繁回收内存页,这也会产生一定的 CPU 消耗。
			    当客户端请求到来时,服务器如果正好进入过期扫描状态,客户端的请求将会等待至少 25ms 后才会进行处理,
		如果客户端将超时时间设置的比较短,比如 10ms,那么就会出现大量的链接因为超时而关闭,
		业务端就会出现很多异常。而且这时你还无法从 Redis 的 slowlog 中看到慢查询记录,
		因为慢查询指的是逻辑处理过程慢,不包含等待时间。
		         所以业务开发人员一定要注意过期时间,如果有大批量的 key 过期,
		要给过期时间设置一个随机范围,而不宜全部在同一时间过期,分散过期处理的压力。

AOF、RDB 和复制对过期键的处理

  1. AOF
    • AOF 写入:如果过期键未被删除,则会被保存到 AOF 文件中;当过期键被删除时,会向 AOF 文件中追加删除命令,来显式的记录该键被删除;
    • AOF 重写:已过期的键不会保存到重写后的 AOF 文件中;
  2. RDB
    • 执行 SAVE 或 BGSAVE 命令时,已过期的键不会保存到新的 RDB 文件中。
    • 载入 RDB,如果服务器以主服务器模式运行,过期键会被忽略;如果以从服务器模式运行,无论键是否过期都会被载入。
  3. 复制
    • 从服务器的过期键删除动作由主服务器控制;从服务器执行客户端的读命令时,如果读的是过期键,会将其当做未过期键来处理,并不会主动删除它;
    • 主服务器删除过期键时,会显式地向所有从服务器发送一个 DEL 命令,从服务器接收到命令后才会删除过期键。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值