Redis删除策略
过期数据
什么是过期数据
Redis中的数据特征:redis是内存数据库、数据存在内存、内存中的数据可以通过TTL指令获取其状态
①XX:具有时效性的数据;②-1:永久有效的数据;③-2:已经过期的数据 或 被删除的数据 或 未定义的数据
核心即为:已经删除的数据
我们试想一下,过期的数据是否已经删了???
比如大并发的情况下,多台客户端同时发起请求、cpu自然就会有压力、这个时候肯定有删除指令、那么cpu会立马去删除吗?其实是不会的。redis客户端也会告诉cpu让他过会再删。
下面我们看看时效性数据的数据结构:
EXPIRE的作用就是独立有一块空间:数据结构为hash、key即为数据的内存地址、值即为过期时间,在进行数据的过期处理的时候,其实是对EXPIRE的操作、通过key找到数据、然后再对数据进行操作。所以我们一旦删除的/过期的数据,通过name得到的是nil呢,其实是已经“被干掉”了。
那么针对这样的数据结构,该如何操作呢???
有三种策略:
- 定时删除
- 惰性删除
- 定期删除
在了解删除策略之前、数据删除策略的目标/目的是什么?
在内存占用与CPU占用之间寻找一种平衡,顾此失彼都会造成整体redis性能的下降,甚至引发服务器宕机或内存泄漏。
数据删除策略
- 定时删除---->时间换空间
创建一个定时器,当key设置有过期时间,且过期时间到达时,由定时器任务立即执行对键的删除操作。这个定时器会和expires空间的某个键值对的值进行比对,如果一样,就要开始工作了,那么是如何工作的呢?————根据这个值的key(内存地址)找到对应的数据,然后进行删除。
优点:节约内存、到点删除、快速释放
缺点:CPU压力大,无论CPU此时负载量多高,均占用CPU,会影响redis服务器响应时间和指令吞吐量。
- 惰性删除---->空间换时间
数据到达过期时间,不进行处理。数据即便是过期了,也不会进行处理,下次访问的时候,才会处理(删除–nil)。那他是怎么知道这个数据是否过期的呢。其实我们在执行getName操作的时候,会有一个expireNeeded()操作。这个操作就是用来判断是否过期的。执行getName之前,一定会执行这个操作。
下次访问数据时--------》如果未过期,返回数据;如果过期了,删除,返回不存在。
优点:节约CPU性能,发现必须删除的时候才删除。
缺点:内存压力较大、出现长期占用内存的数据
- 定期删除---->周期性抽查存储空间(随机抽查,重点抽查)
周期性轮询redis库中的时效性数据,采用随机抽取的策略,利用过期数据占比的方式控制删除频度。
redis启动服务的时候,初始化,读取配置server.hz的值,默认是10
每秒执行server.hz次。serverCron()调用了一个databasesCron()方法—》挨个遍历数据库直到16个库过完。然后在其内部,还调用了acticeExpireCycle()方法–》对每个expires(*)逐一进行检测,每次执行250ms/server.hz(cpu性能的四分之一),对某个expire(**)检测时,随机挑选W个key检测
如果key超时,删除;
如果一轮中删除的key 的数>W*25%,循环该流程;
如果一轮中删除的key的数<=W*25%,检查下一个expire,0-15循环;
W是什么呢,W=ACTIIVE_EXPIRE_CYCLE_LOOKUPS_PER_LOOP属性值。
参数current_db用于记录acticeExpireCycle()进入那个expire执行
如果acticeExpireCycle()执行时间到期,下次从current_db继续向下执行
那么,这种定期删除的策略有哪些特点呢?
- CPU性能占用设置有峰值,检测频度可以自定义设置
- 内存压力不是很大,长期占用内存的冷数据会被持续清理
以上就是redis删除策略的描述,感谢阅读!!!