栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Redis核心技术-异步机制

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Redis核心技术-异步机制

  Redis单线程处理网络IO、key-value操作、加载RDB文件等,但是部分操作会导致Redis主线程阻塞。那么都有哪些阻塞主线程的操作,以及哪些操作可以异步处理呢?

Redis实例交互式操作 client和Redis的操作

  client和Redis的操作包含:网络 IO,键值对增删改查操作,清空数据库操作。

  另外,bgsave、bgrewriter等操作时主线程fork子进程处理,如果Redis实例不是大内存(32G以上)Redis主线程阻塞时间较短。

网络 IO

  Redis采用多路复用I/O机制,避免主线程一直阻塞在网络连接上,网络 IO不会导致Redis主线程阻塞

key-value增删改查操作

  时间复杂度大的key-value操作是Redis主线程主要执行的任务,不同的操作命令时间复杂度不一样,MGET、HMGET、HGETALL等操作时间复杂度O(N),GET、SET等操作时间复杂度O(1)。所以key-value操作有可能导致Redis主线程阻塞(时间复杂度大Redis主线程阻塞)。

  删除操作也可能导致Redis主线程阻塞,删除操作的本质是要释放键值对占用的内存空间。释放内存只是第一步,为了更加高效地管理内存空间,在应用程序释放内存时,操作系统需要把释放掉的内存块插入一个空闲内存块的链表,以便后续进行管理和再分配。这个过程本身需要一定时间,而且会阻塞当前释放内存的应用程序,所以,如果一下子释放了大量内存,空闲内存块链表操作时间就会增加,相应地就会造成 Redis 主线程的阻塞(bigKey删除Redis主线程阻塞)。

  例如一次性删除大量key、删除大hash表、删除大list 等bigKey。

  清空数据库操作,FLUSHDB、FLUSHALL操作释放所有key-value(与删除bigKey类型)可能造成 Redis 主线程的阻塞(清空数据库操作Redis主线程阻塞)。

磁盘

  磁盘的操作包含:生成 RDB 快照,记录 AOF 日志,AOF 日志重写;

  生成 RDB 快照、AOF日志重写
生成 RDB 快照、AOF日志重写是Redis主线程fork子进程异步处理,不会阻塞Redis主线程。

  记录 AOF 日志
记录 AOF 日志以及AOF日志同步写盘(通过写入策略控制)由Redis主线程进行,磁盘的写入速度远低于内存的,大量的AOF日志写盘时会导致Redis主线程阻塞。

主从节点

  master生成、传输 RDB 文件,slave接收 RDB 文件、清空数据库、加载 RDB 文件;

  master生成、传输 RDB 文件有子进程处理,不会阻塞Redis主线程。
  但是slave接受RDB文件包含写磁盘操作,RDB文件接收结束后,slave需要FLUSHDB清空数据库,并且把RDB文件加载到内存,如果RDB文件很大,接收、加载RDB文件有可能阻塞slave主线程。

cluster集群

  cluster集群新增、删除节点时,Redis实例向其他Redis实例传输哈希槽信息,数据迁移。

  如果使用了 Redis Cluster 方案,而且同时正好迁移的是 bigkey 的话,就会造成主线程的阻塞,因为 Redis Cluster 使用了同步迁移。

Redis异步机制 创建子线程

  Redis 主线程启动后,会使用操作系统提供的 pthread_create 函数创建 3 个子线程,分别由它们负责 AOF 日志写操作、key-value删除以及文件关闭的异步执行。

  主线程通过一个链表形式的任务队列和子线程进行交互。

异步解决主线程阻塞操作

  前面说到时间复杂度高的操作、删除bigKey操作、FLUSHDB和FLUSHALL操作、AOF日志写盘、加载RDB文件操作、cluster迁移bigKey操作会导致主线程阻塞。

删除bigKey操作、FLUSHDB和FLUSHALL操作异步执行

  当Redis实例收到key-value删除和清空数据库的操作时,主线程会把这个操作封装成一个任务,放入到任务队列中,然后给客户端返回一个完成信息,表明删除已经完成。

  这个时候删除操作还没有执行,等到后台子线程从任务队列中读取任务后,才开始实际删除键值对,并释放相应的内存空间。因此,我们把这种异步删除也称为惰性删除(lazy free)。此时,删除或清空操作不会阻塞主线程,这就避免了对主线程的性能影响。

  Redis 4.0开始提供惰性删除,由两个新的命令支持:

1.key-value删除:当你的集合类型中有大量元素(例如有百万级别或千万级别元素)需要删除时,我建议你使用 UNlink 命令。

2.清空数据库:可以在 FLUSHDB 和 FLUSHALL 命令后加上 ASYNC 选项,这样就可以让后台子线程异步地清空数据库,如下所示:

> flushdb async
OK
> flushall async
OK
AOF日志写盘

  和惰性删除类似,当 AOF 日志配置成 everysec 选项后,主线程会把 AOF 写日志操作封装成一个任务,也放到任务队列中。后台子线程读取任务后,开始自行写入 AOF 日志,这样主线程就不用一直等待 AOF 日志写完了。

加载RDB文件操作 cluster迁移bigKey操作
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/697729.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号