Redis数据删除方式有哪些

67次阅读
没有评论

共计 2793 个字符,预计需要花费 7 分钟才能阅读完成。

丸趣 TV 小编给大家分享一下 Redis 数据删除方式有哪些,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!

同步和异步删除 1.DEL 和 UNLINK

Redis 服务自身对 Key 的删除,可以分为「同步删除」和「异步删除」。使用 DEL 命令会触发「同步删除」,如果 Key 是一个有很多元素的复杂类型,这个过程可能会堵塞一下 Redis 服务自身,从而影响用户的访问。如果使用 UNLINK 命令,Redis 服务会先计算删除 Key 的成本,从而更智能地做出「同步删除」或「异步删除」的选择。注意,只有 4.0 版本后,才有 UNLINK 命令。

2. 成本计算

那么,成本是如何计算的呢?对于 list,hash,set,zset 的对象类型,如果长度大于 64(由宏 LAZYFREE_THRESHOLD 定义),才会采用异步删除的手段,从当前 db 先释放该 key,再由另外一个线程做异步删除。对于长度不大于 64 的复杂类型,异步删除比同步删除还多了一些函数调用与多线程同步的代价,所以同步删除更好。对于 string 对象,底层的数据结构 sds 是一份连续的内存,内存分配器回收这块内存的复杂度是 O(1),所以采用同步删除也不会堵塞服务。

总的来说,我们作为用户,都能用 UNLINK 替代 DEL。

Key 的驱逐 1. 定义

Redis 处理命令前根据内存容量是否触达上限而进行的 Key 驱逐。

2. 驱逐策略

Redis 通过参数 maxmemory 来选择不同的驱逐策略:

volatile-random 从已设置过期时间的数据集(server.db[i].expires)中任意选择数据驱逐;volatile-lru 从数据集(server.db[i].dict)中挑选最近最少使用的数据驱逐(2.8 默认);

volatile-ttl 从已设置过期时间的数据集 (server.db[i].expires) 中寻找最近即将过期 (ttl 最小) 的 key 来驱逐;

allkeys-random 从数据集(server.db[i].dict)中任意选择数据驱逐;

allkeys-lru 从数据集(server.db[i].dict)中挑选最近最少使用的数据驱逐;

noeviction 禁止驱逐数据,永远不驱逐,仅对写操作返回一个错误(4.0 默认);

在 4.0 版本后,还增加了以下两种驱逐策略。

volatile-lfu 在过期集合中使用 LFU 链来驱逐数据;

allkeys-lfu 从数据集(server.db[i].dict)使用 LFU 算法来驱逐数据;

3. 简述

Redis 在处理命令前,会看看容量是否触达上限。

如果驱逐策略为 noeviction,则不会驱逐 Key,而是返回写失败。4.0 后,在返回写入失败前,还会先检测 lazyfree 线程是否还有待删除的 Key,没有才会给用户返回写入失败。

对于其他策略,都会根据相应定义,进行 Key 的驱逐,这里不再详述。

在 4.0 或以上的版本,Key 的驱逐会基于参数 lazyfree_lazy_eviction,来决定采用 unlink 还是 del。在 2.8 版本,则只会用 del。lazyfree_lazy_eviction 参数在 Qcloud 4.0 上是 no。

这里试问,主从节点都会进行「驱逐」么?

答案是都会的,各自会因应自身的驱逐策略进行驱逐,并且 Master 节点驱逐的删除命令还会传播到 Slave 节点。

Key 的访问淘汰 1. 定义

访问一个已过期的 Key 会触发对其的删除。

2. 简述

与 Key 的驱逐一样,Key 的访问淘汰同样是基于访问事件来触发的。

主从角色的节点在处理访问淘汰上的逻辑是不同的。

对于 Slave 节点,访问到了已过期的 Key,Slave 节点会返回该 Key 不存在,但不会主动删除该 Key。删除的动作,还是会从 Master 上同步过来。

对于 Master 节点,在 4.0 或以上的版本,会根据参数 lazyfree-lazy-expire,来决定用 DEL 还是 UNLINK。对于 2.8 版本,则只能用 DEL 了。这些删除的动作,都会同步到 Slave 与 AOF 文件中。

在 Qcloud 4.0 以上的版本,默认是开启异步删除的,即 lazyfree-lazy-expire=yes

Key 的定时淘汰 1. 定义

Redis 自身的定时调度把已过期 Key 删除。

2. 简述

多久会执行一次定时调度呢?

redis 服务的参数 hz 能控制定时淘汰的频率,hz 默认是 10,即每秒能调度 100 次。

刚才说「访问淘汰」的逻辑只会在 Master 角色上发生,那「访问淘汰」也是吗?

一般来说,Slave 节点不会进行定时淘汰,它只会等待从 Master 节点同步过来的删除命令,这样就保持了主从之间的一致性。然而,有些时候,用户会把 Slave 节点设置成可写,那么 Slave 上写的带有过期时间的 Key,因为 Master 是不知道的,就一直不会淘汰掉。所以在版本 4.0 以后,Redis 增加了单独的逻辑,在定时淘汰中删除这些在 slave 节点上写入的过期 Key。

对于 Master 节点,根据宏 ACTIVE_EXPIRE_CYCLE_SLOW,能选择两种淘汰模式,分别是“FAST 淘汰”和“SLOW 淘汰”,前者每次淘汰只能花 1 毫秒,不能花更多了,后者是 Qcloud 默认的选项,这样能在每次调度中淘汰更多的 Key,但会花更多的 CPU 时间在淘汰上,降低了处理的访问吞吐量。下面我们针对“SLOW 淘汰”展开描述。

SLOW 淘汰模式,以 hz=10 为例,每次调度的总时间是 100ms,这里调度不会 25% 的 cpu 时间,即 25ms。

每淘汰多少个 key,就检测一次是否超 25ms 呢?

如果每淘汰 1 个 Key 就检测一次,无疑代价太大。从源码上看,定时淘汰会尝试遍历每个 db,遍历完了或者时间到了就退出循环。第一层循环是遍历各个 db,第二层循环是遍历 db 里面的一批批 key,一批 key 是 20 个,如果第三层循环结束后有大于 5 个 key 是成功淘汰的(说明这个 db 很多淘汰 key),那么二层就继续循环,如果小于等于 5 个 key,说明这个 db 没有很多 key 需要淘汰,则退出二层循环,第三层循环是一批 key 里面逐个 key 进行淘汰。即最多 320 个 key 进行判断后,就会看看是否已经超过 cpu 占用时间。

在 4.0 或以上的版本,会根据参数 lazyfree-lazy-expire(默认 no)来做 DEL 还是 UNLINK。在 Qcloud 的 4.0 以上版本,这里会特意配置成 yes,以便尽量采用 UNLINK 操作。2.8 版本不支持 lazyfree-lazy-expire,就只能选择 DEL 命令。

这里的定时淘汰,也会以命令的形式,传播到 Slave 节点与记录到 AOF 文件中。

以上是“Redis 数据删除方式有哪些”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注丸趣 TV 行业资讯频道!

正文完
 
丸趣
版权声明:本站原创文章,由 丸趣 2023-07-24发表,共计2793字。
转载说明:除特殊说明外本站除技术相关以外文章皆由网络搜集发布,转载请注明出处。
评论(没有评论)