关于redis 6.0 IO 多线程探秘,以及我的一些想法

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介: redis 6.0 特性 多线程 IO线程

众所周知 redis 6.0 两个比较大的特性 一个是多线程IO 一个是ACL。

今天主要讲解下 IO 多线程特性,以及我的一些看法。结尾有对阿里云redis的一些调研彩蛋。哈哈


多线程的读IO逻辑

acceptCommonHandlerreadQueryFromClientpostponeClientReadhandleClientsWithPendingReadsUsingThreads/* 大概的io处理逻辑都在 postponeClientRead函数中汇总 所有io读事件,然后在 时间事件stopThreadedIOIfNeeded和beforeSleep函数中进行读事件的分发,然后处理命令。那么看下处理逻辑函数handleClientsWithPendingReadsUsingThreads将所有 postponeClientRead函数中新增的 client 队列分发给 每个io线程对应的io_threads_list[io_nums]这里主线程 mainthread 是当做 第一个IO线程来处理io的。通过io_threads_op来标志这次io线程是 io_threads_op读操作 还是 IO_THREADS_OP_WRITE 写操作。因为只有一个线程来操作这个 io_threads_op遍历,那么MESI可见性来说其他CPU都是可见最新的M变量的。setIOPendingCount(j, count); 设置变量处理标志。然后主线程处理完成自己的IO后 开始傻傻等待所有io处理完成。难道就不能做些其他的操作么,这点需要优化下。。比如:主从同步等操作。cpu空转总归不友好。*/while(1) {
unsignedlongpending=0;
for (intj=1; j<server.io_threads_num; j++)
pending+=getIOPendingCount(j);
if (pending==0) break;
            }
/*但是有一点就是 IO线程真的就是傻傻的看变量部分IOThreadMain 代码*//* Wait for start */for (intj=0; j<1000000; j++) {
if (getIOPendingCount(id) !=0) break;
        }
/* Give the main thread a chance to stop this thread. */if (getIOPendingCount(id) ==0) {
pthread_mutex_lock(&io_threads_mutex[id]);
pthread_mutex_unlock(&io_threads_mutex[id]);
continue;
        }
//最后设置自己完成io的标志setIOPendingCount(0)

写IO是如何调用的

//写的逻辑几乎和读一直这里就简单说下在哪里调用执行beforeSleephandleClientsWithPendingWritesUsingThreads/*总体逻辑和读一样 所有io分发io任务,主线程等待完成,完成后又剩余的主从IO事件*/

总体逻辑


引用一个图,懒得画了,大概就是这样

微信图片_20211225162646.png

彩蛋来了

io_threaded_reads_processed:0io_threaded_writes_processed:0

经过对redis主从高可用的实例 压测,可以看到 这个值标志这 社区版的6.0 也是没有开启io线程的。因为对于io线程来说 太影响cpu使用和 抢占了对云环境的应用不是很友好,因为亲和性这些东西也不是很确定的特性。只有在资源分配的时候 剩余多一点cpu资源减少抢占,从而满足客户的 低延迟等问题。


个人意见就是 虚拟环境下 所有的IO线程和 网卡多队列都放到某个socket的 某些cpu的亲缘性高一点,主线程尽量独立cpu亲缘性,从而让 主线程的抢占概率降低。

相关文章
|
监控 NoSQL 安全
如何在 Redis 中正确使用多线程?
【10月更文挑战第16天】正确使用 Redis 多线程需要综合考虑多个因素,并且需要在实践中不断摸索和总结经验。通过合理的配置和运用,多线程可以为 Redis 带来性能上的提升,同时也要注意避免可能出现的问题,以保障系统的稳定和可靠运行。
343 2
|
存储 NoSQL Redis
Redis 新版本引入多线程的利弊分析
【10月更文挑战第16天】Redis 新版本引入多线程是一个具有挑战性和机遇的改变。虽然多线程带来了一些潜在的问题和挑战,但也为 Redis 提供了进一步提升性能和扩展能力的可能性。在实际应用中,我们需要根据具体的需求和场景,综合评估多线程的利弊,谨慎地选择和使用 Redis 的新版本。同时,Redis 开发者也需要不断努力,优化和完善多线程机制,以提供更加稳定、高效和可靠的 Redis 服务。
294 1
|
9月前
|
存储 网络协议 安全
Java网络编程,多线程,IO流综合小项目一一ChatBoxes
**项目介绍**:本项目实现了一个基于TCP协议的C/S架构控制台聊天室,支持局域网内多客户端同时聊天。用户需注册并登录,用户名唯一,密码格式为字母开头加纯数字。登录后可实时聊天,服务端负责验证用户信息并转发消息。 **项目亮点**: - **C/S架构**:客户端与服务端通过TCP连接通信。 - **多线程**:采用多线程处理多个客户端的并发请求,确保实时交互。 - **IO流**:使用BufferedReader和BufferedWriter进行数据传输,确保高效稳定的通信。 - **线程安全**:通过同步代码块和锁机制保证共享数据的安全性。
366 23
|
9月前
|
缓存 NoSQL 中间件
Redis的线程模型
Redis采用单线程模型确保操作的原子性,每次只执行一个操作,避免并发冲突。它通过MULTI/EXEC事务机制、Lua脚本和复合指令(如MSET、GETSET等)保证多个操作要么全成功,要么全失败,确保数据一致性。Redis事务在EXEC前失败则不执行任何操作,EXEC后失败不影响其他操作。Pipeline虽高效但不具备原子性,适合非热点时段的数据调整。Redis 7引入Function功能,支持函数复用,简化复杂业务逻辑。总结来说,Redis的单线程模型简单高效,适用于高并发场景,但仍需合理选择指令执行方式以发挥其性能优势。
240 6
|
12月前
|
NoSQL Redis
单线程传奇Redis,为何引入多线程?
Redis 4.0 引入多线程支持,主要用于后台对象删除、处理阻塞命令和网络 I/O 等操作,以提高并发性和性能。尽管如此,Redis 仍保留单线程执行模型处理客户端请求,确保高效性和简单性。多线程仅用于优化后台任务,如异步删除过期对象和分担读写操作,从而提升整体性能。
214 1
|
存储 运维 NoSQL
Redis为什么最开始被设计成单线程而不是多线程
总之,Redis采用单线程设计是基于对系统特性的深刻洞察和权衡的结果。这种设计不仅保持了Redis的高性能,还确保了其代码的简洁性、可维护性以及部署的便捷性,使之成为众多应用场景下的首选数据存储解决方案。
206 1
|
NoSQL Redis 数据库
Redis单线程模型 redis 为什么是单线程?为什么 redis 单线程效率还能那么高,速度还能特别快
本文解释了Redis为什么采用单线程模型,以及为什么Redis单线程模型的效率和速度依然可以非常高,主要原因包括Redis操作主要访问内存、核心操作简单、单线程避免了线程竞争开销,以及使用了IO多路复用机制epoll。
385 0
Redis单线程模型 redis 为什么是单线程?为什么 redis 单线程效率还能那么高,速度还能特别快
|
存储 Java
【IO面试题 四】、介绍一下Java的序列化与反序列化
Java的序列化与反序列化允许对象通过实现Serializable接口转换成字节序列并存储或传输,之后可以通过ObjectInputStream和ObjectOutputStream的方法将这些字节序列恢复成对象。
|
2月前
|
Java Unix Go
【Java】(8)Stream流、文件File相关操作,IO的含义与运用
Java 为 I/O 提供了强大的而灵活的支持,使其更广泛地应用到文件传输和网络编程中。!但本节讲述最基本的和流与 I/O 相关的功能。我们将通过一个个例子来学习这些功能。
186 1
|
Java 大数据
解析Java中的NIO与传统IO的区别与应用
解析Java中的NIO与传统IO的区别与应用

热门文章

最新文章