xiaolincoder / xiaolincoding_comment

7 stars 0 forks source link

[Vssue]Redis 过期删除策略和内存淘汰策略有什么区别? | 小林coding #141

Open xiaolincoder opened 2 years ago

xiaolincoder commented 2 years ago

https://xiaolincoding.com/redis/module/strategy.html

divisionblur commented 2 years ago

根据 lazyfree_lazy_expire 参数配置决定(Redis 4.0版本开始提供参数),然后返回 null 给客服端;

客户端

xiaolincoder commented 2 years ago

@divisionblur

根据 lazyfree_lazy_expire 参数配置决定(Redis 4.0版本开始提供参数),然后返回 null 给客服端;

客户端

已修正

small-xiexu commented 2 years ago

所以,Redis 在访问 key 时,对于 logc 是这样变化的:

  1. 先按照上次访问距离当前的时长,来对 logc 进行衰减;
  2. 然后,再按照一定概率增加 logc 的值

上面说的第二点,增加 logc 的值也是所有数据都会增加吗,只是根据上次上次访问距离当前的时长来增加这个值,上次访问距离当前的时长越近,增加的值就越大,如果上次访问距离当前的时长越远,增加的值就越小,是这样吗?

xiaolincoder commented 2 years ago

@small-xiexu

所以,Redis 在访问 key 时,对于 logc 是这样变化的:

  1. 先按照上次访问距离当前的时长,来对 logc 进行衰减;
  2. 然后,再按照一定概率增加 logc 的值

上面说的第二点,增加 logc 的值也是所有数据都会增加吗,只是根据上次上次访问距离当前的时长来增加这个值,上次访问距离当前的时长越近,增加的值就越大,如果上次访问距离当前的时长越远,增加的值就越小,是这样吗?

  1. 增加 logc 的值只针对当前访问的key。
  2. redis 源码里 LFULogIncr 函数会计算一个阈值 p,以及一个取值为 0 到 1 之间的随机概率值 r。如果概率 r 小于阈值 p,那么 LFULogIncr 函数才会将访问次数加 1。否则的话,LFULogIncr 函数会返回当前的访问次数,不做更新。
JooKS-me commented 2 years ago

LFU淘汰也是用的随机采样吗

muleimulei commented 2 years ago

特别强调下,每次检查数据库并不是遍历过期字典中的所有 key,而是从数据库中随机抽取一定数量的 key 进行过期检查。

为什么后面又说 是从过期字典中选取?

zclorne commented 2 years ago

@JooKS-me

LFU淘汰也是用的随机采样吗

看了下7.0.4的源码,确实也是随机采样,好像代码就是同一段。 结合redis的设计思路从理论上推测,也应该是随机采样,否则要不然要遍历,要不然额外维护链表,都会影响性能。

zclorne commented 2 years ago

@muleimulei

特别强调下,每次检查数据库并不是遍历过期字典中的所有 key,而是从数据库中随机抽取一定数量的 key 进行过期检查。

为什么后面又说 是从过期字典中选取?

根据我的理解,在这里数据库=过期字典(内存淘汰策略里还是有区分的),过期删除只会考虑过期字典里的key。这里的重点是“不是遍历而是随机抽取”。

xiaolincoder commented 2 years ago

@muleimulei

特别强调下,每次检查数据库并不是遍历过期字典中的所有 key,而是从数据库中随机抽取一定数量的 key 进行过期检查。

为什么后面又说 是从过期字典中选取?

struct redisDb 是redis数据库的结构体,结构体包含过期字典的信息,所以我这里数据库=过期字典。

2firenut commented 1 year ago

原处:”在 Redis 中,默认每秒进行 10 次过期检查一次数据库“ 这段话写得有点怪怪的,应该是 默认每秒进行 10 次过期检查

2firenut commented 1 year ago

Redis集群什么时候更新呀

xiaolincoder commented 1 year ago

@2firenut

原处:”在 Redis 中,默认每秒进行 10 次过期检查一次数据库“ 这段话写得有点怪怪的,应该是 默认每秒进行 10 次过期检查

struct redisDb 是redis数据库的结构体,结构体包含过期字典的信息,所以我这里数据库=过期字典。

2firenut commented 1 year ago

原文:"过期字典的 key 是一个指针,指向某个键对象;过期字典的 value 是一个 long long 类型的整数,这个整数保存了 key 的过期时间;"
过期字典是不是redisDb结构体里面的dict *expires?

xiaolincoder commented 1 year ago

@2firenut

原文:"过期字典的 key 是一个指针,指向某个键对象;过期字典的 value 是一个 long long 类型的整数,这个整数保存了 key 的过期时间;"
过期字典是不是redisDb结构体里面的dict *expires?

对的。

IvanChen1989 commented 1 year ago

redis对性能追求到了极致,而且数据结构上也玩的这么溜, 对设置了过期时间的key如果用一个”heap“来额外保存, 那删除的时候就可以不用随机取了, 而且可以做到类似定时删除的能力。堆顶元素就是最早需要删除的元素。 这块是不是还有改进的空间

lixichongAAA commented 1 year ago

@xiaolincoder

@small-xiexu

所以,Redis 在访问 key 时,对于 logc 是这样变化的:

  1. 先按照上次访问距离当前的时长,来对 logc 进行衰减;
  2. 然后,再按照一定概率增加 logc 的值

上面说的第二点,增加 logc 的值也是所有数据都会增加吗,只是根据上次上次访问距离当前的时长来增加这个值,上次访问距离当前的时长越近,增加的值就越大,如果上次访问距离当前的时长越远,增加的值就越小,是这样吗?

  1. 增加 logc 的值只针对当前访问的key。
  2. redis 源码里 LFULogIncr 函数会计算一个阈值 p,以及一个取值为 0 到 1 之间的随机概率值 r。如果概率 r 小于阈值 p,那么 LFULogIncr 函数才会将访问次数加 1。否则的话,LFULogIncr 函数会返回当前的访问次数,不做更新。

小林哥

所以,Redis 在访问 key 时,对于 logc 是这样变化的:

先按照上次访问距离当前的时长,来对 logc 进行衰减;
然后,再按照一定概率增加 logc 的值

对logc衰减是对所有key(这个所有key是指:如果是在设置了过期时间的数据中策略下,则是对设置了过期时间的所有key;如果是所有数据范围内的策略,则是所有数据范围内的key)进行衰减,对logc增加是对被访问key增加. 这样的是正确的吗?如果不正确,应该是怎样的呢?

dfjfj commented 1 year ago

小林哥,你在生产中是怎么配置内存淘汰策略的呢?

linkypi commented 1 year ago

定期删除策略好像漏了东西,里面分Fast模式 (过期比例10% ) 和 Slow模式(过期比例 25% )

zhuay-a commented 5 months ago

如果操作系统发生缺页中断时要把磁盘页读入内存,然后又发现内存不足,此时redis占用的内存并没有到达redis设置的最大内存,那操作系统有没有可能会把redis里的数据置换到磁盘

buhalin commented 4 months ago

阅毕,感谢分享