0

0

Redis的异步机制是什么

王林

王林

发布时间:2023-06-01 20:14:40

|

1501人浏览过

|

来源于亿速云

转载

一、Redis 的阻塞点

redis 实例交互的对象,以及交互时会发生的操作:

  • 客户端:网络 IO,键值对增删改查操作,数据库操作;

  • 磁盘:生成 RDB 快照,记录 AOF 日志,AOF 日志重写;

  • 主从节点:主库生成、传输 RDB 文件,从库接收 RDB 文件、清空数据库、加载 RDB 文件;

  • 切片集群实例:向其他实例传输哈希槽信息,数据迁移。

4 类交互对象和具体的操作之间的关系:

Redis的异步机制是什么

和客户端交互时的阻塞点:

网络 IO 有时候会比较慢,但是 Redis 使用了 IO 多路复用机制,避免了主线程一直处在等待网络连接或请求到来的状态,所以网络 IO 不是导致 Redis 阻塞的因素。

Redis 主线程的主要任务是执行与客户端交互的键值对的增删改查操作。复杂度高的增删改查操作肯定会阻塞 Redis。

判断操作复杂度高低的标准:看操作的复杂度是否为 O(N)

Redis 的第一个阻塞点:集合全量查询和聚合操作:

Redis 中涉及集合的操作复杂度通常为 O(N),使用时需重视起来。
例如集合元素全量查询操作 HGETALL、SMEMBERS,以及集合的聚合统计操作,例如求交、并和差集。

Redis 的第二个阻塞点 :bigkey 删除操作

集合自身的删除操作同样也有潜在的阻塞风险。删除操作的本质是要释放键值对占用的内存空间。 释放内存只是第一步,为了更加高效地管理内存空间,在应用程序释放内存时,操作系统需要把释放掉的内存块插入一个空闲内存块的链表,以便后续进行管理和再分配。

这个过程本身需要一定时间,而且会阻塞当前释放内存的应用程序,如果一下子释放了大量内存,空闲内存块链表操作时间就会增加,相应地就会造成 Redis 主线程的阻塞。

释放大量内存的时机:在删除大量键值对数据的时候,删除包含了大量元素的集合,也称为 bigkey 删除

不同元素数量的集合在进行删除操作时所消耗的时间:

Redis的异步机制是什么

得出三个结论:

  • 当元素数量从 10 万增加到 100 万时,4 大集合类型的删除时间的增长幅度从 5 倍上升到了近 20 倍;

  • 集合元素越大,删除所花费的时间就越长;

  • 删除一个包含100万个元素的集合时,Hash类型的最大删除时间已经达到了1.98秒的绝对值。一般情况下,Redis 响应时间在微秒级别,但如果某个操作需要近2秒的执行时间,则会阻塞主线程,这是无法避免的。

Redis 的第三个阻塞点:清空数据库

既然频繁删除键值对都是潜在的阻塞点了,在 Redis 的数据库级别操作中,清空数据库(例如 FLUSHDB 和 FLUSHALL 操作)也是一个潜在的阻塞风险,因为它涉及到删除和释放所有的键值对。

Redis 的第四个阻塞点:AOF 日志同步写

磁盘 IO 一般都是比较费时费力的,需要重点关注。 Redis 开发者早已认识到磁盘 IO 会带来阻塞,所以把 Redis 设计为采用子进程的方式生成 RDB 快照文件、执行 AOF 日志重写操作。由子进程负责执行,慢速的磁盘 IO 就不会阻塞主线程了。

如果 Redis 直接记录 AOF 日志,它会利用不同的写入策略将数据写入磁盘。一个同步写磁盘的操作的耗时大约是 1~2ms,如果有大量的写操作需要记录在 AOF 日志中,并同步写回的话,会阻塞主线程。

Redis 的第五个阻塞点:从库加载 RDB 文件

在主从集群中,主库需要生成 RDB 文件,并传输给从库。

主库在复制的过程中,创建和传输 RDB 文件都是由子进程来完成的,不会阻塞主线程。
但是从库在接收了 RDB 文件后,需要使用 FLUSHDB 命令清空当前数据库,正好撞上了第三个阻塞点。

从库在清空当前数据库后,需要把 RDB 文件加载到内存,这个过程的快慢和 RDB 文件的大小密切相关,RDB 文件越大,加载过程越慢。

易优制冷机械设备网站源码1.6.9
易优制冷机械设备网站源码1.6.9

易优制冷机械设备网站源码是基于易优cms开发,适合企业进行制冷设备展示使用。程序内核为Thinkphp5.0开发,后台简洁,为企业网站而生。 这是一套安装就能建站的程序,不定期更新程序BUG,更新网站功能。 我们提供的不仅是模板这么简单,我们还提供程序相关咨询、协助安装等服务。 默认不包含小程序插件,需要另外单独购买插件。 模板安装步骤 1、请将安装包ZIP上

下载

切片集群实例交互时的阻塞点

部署 Redis 切片集群时,每个 Redis 实例上分配的哈希槽信息需要在不同实例间进行传递,当需要进行负载均衡或者有实例增删时,数据会在不同的实例间进行迁移。不过哈希槽的信息量不大,而数据迁移是渐进式执行的,这两类操作对 Redis 主线程的阻塞风险不大。

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

五个阻塞点:

  • 集合全量查询和聚合操作;

  • bigkey 删除;

  • 清空数据库;

  • AOF 日志同步写;

  • 从库加载 RDB 文件。

二、可以异步执行的阻塞点

为了避免阻塞式操作,Redis 提供了异步线程机制:

Redis 会启动一些子线程,然后把一些任务交给这些子线程,让它们在后台完成,而不再由主线程来执行这些任务。可以避免阻塞主线程。

异步执行对操作的要求:

一个能被异步执行的操作并不是 Redis 主线程的关键路径上的操作(客户端把请求发送给 Redis 后,等着 Redis 返回数据结果的操作)。

Redis的异步机制是什么

主线程接收到操作 1 后,操作 1 并不用给客户端返回具体的数据,主线程可以把它交给后台子线程来完成,同时只要给客户端返回一个“OK”结果就行。
在子线程执行操作 1 的时候,客户端又向 Redis 实例发送了操作 2,客户端是需要使用操作 2 返回的数据结果的,如果操作 2 不返回结果,那么客户端将一直处于等待状态。

操作 1 就不算关键路径上的操作,因为它不用给客户端返回具体数据,所以可以由后台子线程异步执行。
操作 2 需要把结果返回给客户端,它就是关键路径上的操作,所以主线程必须立即把这个操作执行完。

  • Redis 读操作是典型的关键路径操作,因为客户端发送了读操作之后,就会等待读取的数据返回,以便进行后续的数据处理。而 Redis 的第一个阻塞点“集合全量查询 和聚合操作”都涉及到了读操作,不能进行异步操作。

  • 不需要将具体的数据结果返回给客户端的删除操作不属于关键路径操作。"Both 'bigkey deletion' and 'database clearance' involve deleting data, but they are not on the critical path."。可以使用后台子线程来异步执行删除操作。

  • “AOF 日志同步写”,为了保证数据可靠性,Redis 实例需要保证 AOF 日志中的操作记录已经落盘,这个操作虽然需要实例等待,但它并不会返回具体的数据结果给实例。所以可以启动一个子线程来执行 AOF 日志的同步写。

  • 为了向客户端提供数据存取服务,必须加载完整的 RDB 文件。这个操作也属于关键路径上的操作,必须让从库的主线程来执行。

除了“集合全量查询和聚合操作”和“从库加载 RDB 文 件”,其他三个阻塞点涉及的操作都不在关键路径上,可以使用 Redis 的异步子线程机制来实现 bigkey 删除,清空数据库,以及 AOF 日志同步写。

三、异步的子线程机制

Redis 主线程启动后,会使用操作系统提供的 pthread_create 函数创建 3 个子线程,负责AOF 日志写操作、键值对删除、文件关闭的异步执行。

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

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

但实际上,这个时候删除还没有执行,等到后台子线程从任务队列中读取任务后,才开始实际删除键值对,并释放相应的内存空间。这种异步删除也称为惰性删除 (lazy free)。

当 AOF 日志配置成 everysec 选项后,主线程会把 AOF 写日志操作封装成一个任务,也放到任务队列中。一种重写方式是: 当后台子线程读取到任务后,即开始自行记录到AOF日志,主线程即可脱离对AOF日志的依赖而继续运行。

Redis 中的异步子线程执行机制:

Redis的异步机制是什么

异步的键值对删除和数据库清空操作是 Redis 4.0 后提供的功能,Redis 也提供了新的命令来执行这两个操作:

  • 键值对删除:集合类型中有大量元素(例如有百万级别或千万级别元素)需要删除时,建议使用 UNLINK 命令;

  • 清空数据库:可以在 FLUSHDB 和 FLUSHALL 命令后加上 ASYNC 选项,让后台子线程异步地清空数据库。

FLUSHDB ASYNC 
FLUSHALL AYSNC

相关专题

更多
线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

480

2023.08.10

线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

480

2023.08.10

go语言 数组和切片
go语言 数组和切片

本专题整合了go语言数组和切片的区别与含义,阅读专题下面的文章了解更多详细内容。

46

2025.09.03

discuz database error怎么解决
discuz database error怎么解决

discuz database error的解决办法有:1、检查数据库配置;2、确保数据库服务器正在运行;3、检查数据库表状态;4、备份数据;5、清理缓存;6、重新安装Discuz;7、检查服务器资源;8、联系Discuz官方支持。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

208

2023.11.20

常用的数据库软件
常用的数据库软件

常用的数据库软件有MySQL、Oracle、SQL Server、PostgreSQL、MongoDB、Redis、Cassandra、Hadoop、Spark和Amazon DynamoDB。更多关于数据库软件的内容详情请看本专题下面的文章。php中文网欢迎大家前来学习。

970

2023.11.02

内存数据库有哪些
内存数据库有哪些

内存数据库有Redis、Memcached、Apache Ignite、VoltDB、TimesTen、H2 Database、Aerospike、Oracle TimesTen In-Memory Database、SAP HANA和ache Cassandra。更多关于内存数据库相关问题,详情请看本专题下面的文章。php中文网欢迎大家前来学习。

631

2023.11.14

mongodb和redis哪个读取速度快
mongodb和redis哪个读取速度快

redis 的读取速度比 mongodb 更快。原因包括:1. redis 使用简单的键值存储,而 mongodb 存储 json 格式的数据,需要解析和反序列化。2. redis 使用哈希表快速查找数据,而 mongodb 使用 b-tree 索引。因此,redis 在需要高性能读取操作的应用程序中是一个更好的选择。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

474

2024.04.02

redis怎么做缓存服务器
redis怎么做缓存服务器

redis 作为缓存服务器的答案:redis 是一款开源、高性能、分布式的键值存储,可作为缓存服务器使用。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

398

2024.04.07

php与html混编教程大全
php与html混编教程大全

本专题整合了php和html混编相关教程,阅读专题下面的文章了解更多详细内容。

1

2026.01.13

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
进程与SOCKET
进程与SOCKET

共6课时 | 0.3万人学习

Redis+MySQL数据库面试教程
Redis+MySQL数据库面试教程

共72课时 | 6.3万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号