1、redis的删除策略
Redis 是一种内存级数据库,数据都存在内存中,但是针对于已经过期的数据,reids 不 会立刻删除只是会存储在 expires 中,当执行删除策略的时候,才会从 expires 中寻找对应的数据存储的地址,在存储空间中找到对应的数据进行删除。数据删除其实就是内存和 CPU 占用之间寻找平衡,CPU 才能去处理事情,针对过期数据,要进行删除的时候,一般有三种策略
2、三种删除策略
(1)、定时删除
顾名思义,给Key设置一个时间,时间到了,定时器任务立即执行删除,相当于消 耗 CPU 来减少内存使用,拿时间换空间。
优点:节约内存,到时就删除,快速释放掉不必要的内存占用 缺点:CPU 压力大,无论 CPU 此时负载量多高,都会去占用 CPU 进行 key 的删除 操作,会影响 Redis 服务器响应时间和吞吐量,是一种比较低效的方式 结论:用 CPU 性能换取内存空间,时间换空间
(2)、惰性删除
就是说,数据到达过期时间的时候,先不做处理,等到下次访问数据的时候,进行访问, 如未过期,返回数据,如过期,则删除。这就相当于节约了 CPU 但占用了内存,拿空间换 时间。
优点:不占用 CPU 节约 CPU 性能,只在获取访问 key 的时候才判断是否过期,过期 则删除,只会删除当前获取的这一个 key,其他的 key 还是保持原样
缺点:内存占用大,如果一直没有获取它,那么数据就会长期占用内存空间,当有大量 的 key 没有被使用到,也造成了大量内存浪费,对内存数据库来说,也不太友好 结论:空间换时间
(3)、定期删除
前面说的两种方案 1.时间换空间,2.空间换时间都是两个极端方法,为避免前面方案带 来的问题,Redis 引入了定期删除策略(是他们的一个比较折中的方案)周期性轮询 Redis 库中的时效性数据,采取随机抽取的策略,利用过期数据占比的方式控制删除频度。在 Redis 服务器初始化时,读取 server.hz 的值,默认值为 10。定时轮询服务器,每秒钟执行 server.hz 次 serverCron() 函数。databaseCron() 在后台轮询处理 16 个 redis 数据库的操作,如这里的过期key 的处理activeExpireCycle(),对每个数据库的 expire 空间进行检测,每次执行250ms/server.hz 随机选取一批 expire 空间的 key(redis 有 16 个数据库,从 0 号数据库开始—15号数据库) 删除这批 key 中已过期的。如果这批 key 中已过期的占比超过 25%,那么再重复执行步骤一。(循环到小于 25%结束当前数据库的删除)如果这批 key 中已过期的占比 ≤ 25%,检测下一个数据库的 expire 空间(current_db++) 用 info 命令查看相关配置参数
每秒钟执行 hz 次 serverCron(),对服务器进行定时轮询
3、三种策略对比
1:定时删除: 节约内存,无占用, 不分时段占用 CPU 资源, 频度高,拿时间换空间
2:惰性删除: 内存占用严重 延时执行, CPU 利用率高拿空间换时间
3:定期删除: 内存定期随机清理 每秒花费固定的 CPU 资源维护内存 随机抽查,重点抽查
4、淘汰/逐出策略
在 Redis 中经常会进行数据的增删查改操作,那么如果在添加数据的时候遇到了内存不足,该怎么办?在前面用的删除策略可以避免出现这种情况吗? 实际上,在前面所说的删除策略,它针对的是 expire 命令进行的操作,也就是说那些具有时效性的数据(已经过期,并且还在占用内存的数据) 针对那些并没有过期,或者是内存中的数据没有一个带有有效期,全是永久性数据,这时候删除策略就不起作用了,所以这个时候内存满了我们再去插入数据到内存是怎么做?那就需要用到淘汰策略了。
redis 执行命令之前,都会用 freeMemoryIfNeeded()方法,检测这次内存是否充足,如果不满足加入新数据,则会执行淘汰策略(淘汰未过期的数据)
(1)、淘汰策略分类
检测带有时效性的数据进行淘汰(一般是有定时,会过期的数据的)
volatile-lru:挑选最近最少使用的数据淘汰
volatile-lfu:挑选最近使用次数最少的数据淘汰
volatile-ttl:挑选将要过期的数据淘汰
volatile-random:任意选择数据淘汰
检测全库的数据进行淘汰
allkeys-lru:挑选最近最少使用的数据淘汰
allkeLyRs-lfu:挑选最近使用次数最少的数据淘汰
allkeys-random:任意选择数据淘汰,相当于随机
标签:策略,删除,过期,redis,内存,key,数据,CPU From: https://blog.51cto.com/u_14585161/12030091