一直以来我们认为 Redis 是单线程的,单线程为 Redis 带来了代码的简洁性和丰富多样的数据结构。不过Redis内部实际上并不是只有一个主线程,它还有几个异步线程专门用来处理一些耗时的操作。

Redis 为什么要懒惰删除(lazy free)?

删除指令 del 会直接释放对象的内存,大部分情况下,这个指令非常快,没有明显延迟。不过如果删除的 key 是一个非常大的对象,比如一个包含了千万元素的 hash,那么删除操作就会导致单线程卡顿。

Redis 为了解决这个卡顿问题,在 4.0 版本引入了 unlink 指令,它能对删除操作进行懒处理,丢给后台线程来异步回收内存。

> unlink key
OK

如果有多线程的开发经验,你肯定会担心这里的线程安全问题,会不会出现多个线程同时并发修改数据结构的情况存在。

关于这点,我打个比方。可以将整个 Redis 内存里面所有有效的数据想象成一棵大树。当 unlink 指令发出时,它只是把大树中的一个树枝别断了,然后扔到旁边的火堆里焚烧 (异步线程池)。树枝离开大树的一瞬间,它就再也无法被主线程中的其它指令访问到了,因为主线程只会沿着这颗大树来访问。

flush

Redis 提供了 flushdb 和 flushall 指令,用来清空数据库,这也是极其缓慢的操作。Redis 4.0 同样给这两个指令也带来了异步化,在指令后面增加 async 参数就可以将整棵大树连根拔起,扔给后台线程慢慢焚烧。

> flushall async
OK

异步队列

主线程将对象的引用从「大树」中摘除后,会将这个 key 的内存回收操作包装成一个任务,塞进异步任务队列,后台线程会从这个异步队列中取任务。任务队列被主线程和异步线程同时操作,所以必须是一个线程安全的队列。

不是所有的 unlink 操作都会延后处理,如果对应 key 所占用的内存很小,延后处理就没有必要了,这时候 Redis 会将对应的 key 内存立即回收,跟 del 指令一样。

AOF Sync也很慢

Redis需要每秒一次(可配置)同步AOF日志到磁盘,确保消息尽量不丢失,需要调用sync函数,这个操作会比较耗时,会导致主线程的效率下降,所以Redis也将这个操作移到异步线程来完成。执行AOF Sync操作的线程是一个独立的异步线程,和前面的懒惰删除线程不是一个线程,同样它也有一个属于自己的任务队列,队列里只用来存放AOF Sync任务。

更多异步删除点

Redis 回收内存除了 del 指令和 flush 之外,还会存在于在 key 的过期、LRU 淘汰、rename 指令以及从库全量同步时接受完 rdb 文件后会立即进行的 flush 操作。

Redis4.0 为这些删除点也带来了异步删除机制,打开这些点需要额外的配置选项。

  1. slave-lazy-flush 从库接受完 rdb 文件后的 flush 操作
  2. lazyfree-lazy-eviction 内存达到 maxmemory 时进行淘汰
  3. lazyfree-lazy-expire key 过期删除
  4. lazyfree-lazy-server-del rename 指令删除 destKey

【Redis】懒惰删除相关推荐

  1. 如履薄冰 —— Redis懒惰删除的巨大牺牲

    前言 之前我们介绍了Redis懒惰删除的特性,它是使用异步线程对已经删除的节点进行延后内存回收.但是还不够深入,所以本节我们要对异步线程逻辑处理的细节进行分析,看看Antirez是如何实现异步线程处理 ...

  2. 如履薄冰:Redis 懒惰删除的巨大牺牲

    作者 | 老钱 责编 | 胡巍巍 大家都知道 Redis 是单线程的,但是 Redis 4.0 增加了懒惰删除功能,懒惰删除需要使用异步线程对已删除的节点进行内存回收,这意味着 Redis 底层其实并 ...

  3. Redis之懒惰删除

    Redis内部有一个异步线程叫做BIO(background io),懒惰删除的内存回收就是使用这个线程异步去做的. 非异步回收 redis最开始实现懒惰删除时,并不是在异步线程里做,而是在异步线程里 ...

  4. 关于 Redis 的 懒惰删除 (十三)

    平波缓进 -- 懒惰删除 一直以来我们认为 Redis 是单线程的,单线程为 Redis 带来了代码的简洁性和丰富多样的数据结构.不过Redis内部实际上并不是只有一个主线程,它还有几个异步线程专门用 ...

  5. Redis 大键值对 Big Key 懒惰删除机制

    一.懒惰删除介绍 在删除元素数量很多的集合(set/hash/list/sortedSet)时,无论是使用DEL命令删除还是redis为了释放内存空间而进行的删除,在删除这些big key的时候,会导 ...

  6. Redis 惰性删除

    文章目录 前言 lazy free flush 异步队列 AOF Sync 更多异步删除点 前言 Redis 虽然是单线程的,但是其内部实际上并不是只有一个主线程,它还有几个异步线程专门用来处理一些耗 ...

  7. 为什么集群要奇数_面试系列 redis数据删除amp;集群

    redis数据删除/内存淘汰 如果我们设置一批key只能存活1小时,那么1小时之后,redis是怎么对这批数据进行删除的? 答案:定期删数+惰性删除 (1)定期删除 指的是redis默认是每隔100m ...

  8. redis批量删除key

    批量删除Key Redis 中有删除单个 Key 的指令 DEL,但好像没有批量删除 Key 的指令,不过我们可以借助 Linux 的 xargs 指令来完成这个动作 1 2 3 redis-cli ...

  9. Redis淘汰删除策略

    Redis淘汰删除策略 Redis淘汰删除策略6种淘汰Key策略3种删除过期键策略定时删除惰性删除定期删除其他模块的淘汰处理RDB 快照持久化创建载入AOF 只追加持久化写入重写主从复模式下对过期键的 ...

最新文章

  1. 1137 - Sin your life sin公式 + 枚举
  2. Python Generators(生成器)——yield关键字
  3. 2018,人工智能在清算中落地
  4. 创建线程方式二 java 1615474026
  5. 云小课|打造企业数据“高内聚,低耦合”--试试GaussDB(DWS)逻辑集群,实现数据物理隔离
  6. [Android开发]zip文件压缩解压缩
  7. 支持向量机回归_机器学习系列17:支持向量机
  8. matlab2c使用c++实现matlab函数系列教程-find函数
  9. java web 学习计划
  10. uri和url的区别与联系(一看就理解)
  11. Linux系统下QT九宫格拼图小游戏
  12. 初级官方卡刷包精简 添加万能ROOT
  13. 搞死SAP系统系列 让PO系统宕机
  14. oracle 截断数据库,Oracle截断表
  15. (DFS)深度优先搜索算法详解
  16. Linux开放80端口
  17. 魔兽世界钓鱼大赛冠军心得
  18. M1 Mac使用Kitty script入库标准音源到Kontakt6
  19. Error starting daemon: error initializing graphdriver: driver not supported
  20. 持续集成(第二版)[来自:Martin Fowler]

热门文章

  1. 014 非常好用的广告净化器
  2. Vista如何安装迅盘驱动以及如何开启迅盘
  3. VSTO C# 操作excel
  4. ModuleNotFoundError: No module named 'torch'(anaconda安装好Pytorch却无法在Jupyter notebook使用)
  5. Mac电脑如何给Finder文件夹更换背景?
  6. [解题报告]11942 - Lumberjack Sequencing
  7. 仿百度首页登陆框拖拽效果(可视窗口内拖动)
  8. 金融行业市场占有率超五成,ZDNS筑牢金融科技网络根基
  9. npm install 报错 - node篇
  10. Linux 查看usb设备信息