Redis6 引入多线程是怎么回事

Redis6引入了多线程来优化网络数据读写和协议解析,以解决单线程在网络IO操作上的瓶颈。主线程负责连接请求,IO线程进行读写,然后返回主线程执行命令。这种设计避免了并发安全问题,且Redis作者表示性能提升至少一倍。与Memcached相比,Redis的多线程模型更复杂,但在线程隔离和安全性上有优势。启用多线程需在配置文件中开启,并合理设置线程数。
摘要由CSDN通过智能技术生成

众所周知,Redis 之前的版本一直都是典型的单线程模型(注意:这里不是指 Redis 单实例中只有一个线程,而是表示核心操作模块由单线程完成,当然另外还有一些辅助线程,比如 LRU的淘汰过程等)。然而最新的Redis 6 却引入了多线程。上一篇文章已经提到, Redis 单线程处理有着很快的速度,那为什么还要引入多线程呢?

先看看单线程的瓶颈在什么地方?在 Redis 中,单线程的性能瓶颈主要在网络IO操作上。也就是在读写网络 read/write 系统调用执行期间会占用大部分 CPU 时间。比如对一些大的键值对进行删除操作的话,在短时间内是删不完的,那么对于单线程来说就会阻塞后边的操作。 Reactor 模式中单线程的处理方式。针对非连接事件,Reactor 会调用对应的 handler 完成 read->业务处理->write 处理流程,也就是说这一步会造成性能上的瓶颈。

Redis 6 引入多线程处理来解决上面的瓶颈,以追求极致性能。在设计上采用将网络数据读写和协议解析通过多线程的方式来处理,对于命令执行来说,仍然使用单线程操作。

流程简述如下:
1、主线程负责接收建立连接请求,获取 socket 放入全局等待读处理队列
2、主线程处理完读事件之后,通过 RR(Round Robin) 将这些连接分配给这些 IO 线程
3、主线程阻塞等待 IO 线程读取 socket 完毕
4、主线程通过单线程的方式执行请求命令,请求数据读取并解析完成
5、主线程阻塞等待 IO 线程将数据回写 socket 完毕
6、解除绑定,清空等待队列

可参考以下流程图。这个图是网上找的,不一定完全准确,但基本能说明问题。

 

该设计有如下特点:
1、IO 线程要么同时在读 socket,要么同时在写,不会同时读或写
2、IO 线程只负责读写 socket 解析命令,不负责命令处理

从上面的实现机制可以看出,Redis的多线程部分只是用来处理网络数据的读写和协议解析,执行命令仍然是单线程顺序执行。所以我们不需要去考虑控制 key、lua、事务,LPUSH/LPOP 等等的并发及线程安全问题。

Redis6.0与Memcached多线程模型对比:
相同点:都采用了 master线程-worker 线程的模型
不同点:Memcached 执行主逻辑也是在 worker 线程里,模型更加简单,实现了真正的线程隔离,符合我们对线程隔离的常规理解。而 Redis 把处理逻辑交还给 master 线程,虽然一定程度上增加了模型复杂度,但也解决了线程并发安全等问题。

Redis6.0的多线程默认是禁用的,只使用主线程。如需开启需要修改redis.conf配置文件:io-threads-do-reads yes。开启多线程后,还需要设置线程数,否则是不生效的。同样修改redis.conf配置文件

在这里插入图片描述

关于线程数的设置,官方有一个建议:4核的机器建议设置为2或3个线程,8核的建议设置为6个线程,线程数一定要小于机器核数。还需要注意的是,线程数并不是越大越好,官方认为超过了8个基本就没什么意义了。

Redis 作者 antirez 在 RedisConf 2019分享时曾提到:Redis 6 引入的多线程 IO 特性对性能提升至少是一倍以上。祝大家好运! 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值