网站后台补丁如何做,衡水网站建费用,义乌商城集团网站建设,哪个网站可以免费下载ppt模板1 介绍
Redis 是一个kv型数据库#xff0c;我们所有的数据都是存放在内存中的#xff0c;但是内存是有大小限制的#xff0c;不可能无限制的增量。 想要把不需要的数据清理掉#xff0c;一种办法是直接删除#xff0c;这个咱们前面章节有详细说过#xff1b;另外一种就是…1 介绍
Redis 是一个kv型数据库我们所有的数据都是存放在内存中的但是内存是有大小限制的不可能无限制的增量。 想要把不需要的数据清理掉一种办法是直接删除这个咱们前面章节有详细说过另外一种就是设置过期时间缓存过期后由Redis系统自行删除。 这边需要注意的是缓存过期之后并不是马上删除的那Redis是怎么删除过期数据的呢主要通过两个方式
惰性删除通过定时任务定期选取部分数据删除
2 Redis缓存过期命令
我们通过以下指令给指定key的缓存设置过期时间如果都没设置过期时间 key 将一直存在直到我们使用 Del 的命令明确删除掉。
# 缓存时间过期命令参考如下
EXPIRE key seconds [ NX | XX | GT | LT] Redis 7.0 开始EXPIRE 添加了 NX、XX和GT、LT 选项分别代表如下
NX仅当Key没有过期时设置过期时间XX仅当Key已过期时设置过期时间GT仅当新到期时间大于当前到期时间时设置到期时间LT仅当新到期时间小于当前到期时间时设置到期时间
其中GT、LT和NX选项是互斥的下面是官方的测试用例
redis SET mykey Hello
OK
redis EXPIRE mykey 10
(integer) 1
redis TTL mykey
(integer) 10
redis SET mykey Hello World
OK
redis TTL mykey
(integer) -1
redis EXPIRE mykey 10 XX
(integer) 0
redis TTL mykey
(integer) -1
redis EXPIRE mykey 10 NX
(integer) 1
redis TTL mykey
(integer) 10
3 两种过期数据的删除方式
我们前面说过Redis删除过期数据主要通过以下两个方式我们一个个来看
惰性删除通过定时任务定期选取部分数据删除
3.1 惰性删除
惰性删除比较简单当客户端请求过来查询我们的key的时候先对key做一下检查如果没过期则返回缓存数据如果过期则删除缓存重新从数据库中获取数据。 这样我们就把删除过期数据的主动权交给了访问请求的客户端如果客户端一直没请求那这个过期缓存可能就长时间得不到释放。
Redis的源码 src/db.c 中的 expireIfNeeded 方法 就是实现以上惰性删除逻辑的我们来看看
int expireIfNeeded(redisDb *db, robj *key, int force_delete_expired) {// 对于未过期的key直接 return 0if (!keyIsExpired(db,key)) return 0; /* If we are running in the context of a slave, instead of* evicting the expired key from the database, we return ASAP:* the slave key expiration is controlled by the master that will* send us synthesized DEL operations for expired keys.** Still we try to return the right information to the caller,* that is, 0 if we think the key should be still valid, 1 if* we think the key is expired at this time. */if (server.masterhost ! NULL) {if (server.current_client server.master) return 0;if (!force_delete_expired) return 1;}/* If clients are paused, we keep the current dataset constant,* but return to the client what we believe is the right state. Typically,* at the end of the pause we will properly expire the key OR we will* have failed over and the new primary will send us the expire. */if (checkClientPauseTimeoutAndReturnIfPaused()) return 1;/* Delete the key */deleteExpiredKeyAndPropagate(db,key);return 1;
}3.2 定期删除
刚才前面说过了仅靠客户端访问来对过期缓存执行删除远远不够因为有的 key 过期了但客户端一直没请求那这个过期缓存可能就长时间甚至永远得不到释放。 所以除了惰性删除Redis 还可以通过定时任务的方式来删除过期的数据。定时任务的发起的频率由redis.conf配置文件中的hz来进行配置
# 代表每1s 运行 10次
hz 10Redis 默认每 1 秒运行 10 次也就是每 100 ms 执行一次每次随机抽取一些设置了过期时间的 key这边注意不是检查所有设置过期时间的key而是随机抽取部分检查是否过期如果发现过期了就直接删除。 该定时任务的具体流程如下
定时serverCron方法去执行清理执行频率根据redis.conf中的hz配置的值执行清理的时候不是去扫描所有的key而是去扫描所有设置了过期时间的keyredisDb.expires如果每次去把所有过期的key都拿过来那么假如过期的key很多就会很慢所以也不是一次性拿取所有的key根据hash桶的维度去扫描key扫到20(可配)个key为止。假如第一个桶是15个key 没有满足20继续扫描第二个桶第二个桶20个key由于是以hash桶的维度扫描的所以第二个扫到了就会全扫总共扫描35个key找到扫描的key里面过期的key并进行删除删除完检查过期的 key 超过 25%继续执行4、5步 其他注意点
为何不扫描所有key进行过期缓存元素删除Redis本身就是高速缓存如果每次检查大量的key无论在CPU和内存的的使用率上都会特别高Redis集群越大风险越大。分片模式下的删除同步无论定时删除还是惰性删除。master 会生成删除的指令记录到 AOF 和 slave 节点。