四 Redis6.0多线程支持

支持多线程的 Redis 6.0 版本于 2020-05-02 终于发布了,为什么 Redis 忽然要支持多线程?如何开启多线程?开启后性能提升效果如何?线程数量该如何设置?开启多线程后会不会有线程安全问题?多线程的实现原理是怎样的?

1 6.0 之前真的是单线程吗

Redis 在处理客户端的请求时,包括获取(Socket 读)、解析、执行、内容返回(Socket 写)等都由一个顺序串行的主线程处理,这就是所谓的“单线程”。

但如果严格来讲从 Redis 4.0 之后并不是单线程,除了主线程外,它也有后台线程在处理一些较为缓慢的操作,例如清理脏数据、无用连接的释放、大 Key 的删除等等。


2  6.0 之前为什么一直不使用多线程?

【官方答案】

因为Redis是基于内存的操作,CPU不是Redis的瓶颈,Redis的瓶颈最有可能是机器内存的大小或者网络带宽。既然单线程容易实现,而且CPU不会成为瓶颈,那就顺理成章地采用单线程的方案了。

【单线程优势】

  1. 无需上线文切换:采用单线程,避免了不必要的上下文切换对CPU的消耗;

  2. 无需考虑并发加锁问题:Redis的数据结构并不全是简单的Key-Value,还有list,hash等复杂的结构,并发对这些数据操作就不可避免各种锁操作,比如加锁、释放锁、锁等待等导致性能消耗。

3 6.0 为什么要引入多线程呢?

Redis 将所有数据放在内存中,内存的响应时长大约为100 纳秒,响应速度非常快,但随着越来越复杂的业务场景,有些公司动不动就上亿的交易量,因此需要更大的 QPS。常见的解决方案是在分布式架构中对数据进行分区并采用多个服务器,但该方案有非常大的缺点,例如要管理的 Redis 服务器太多维护代价大,且数据分区无法解决热点读/写问题(无法从根本上解决问题)。

  1. 充分利用CUP资源:目前主线程只能利用一个核。

  2. 提高网络IO性能:从 Redis 自身角度来说,因为读写网络的 Read/Write 系统调用占用了 Redis 执行期间大部分 CPU 时间,瓶颈主要在于网络的 IO 消耗。

4 6.0 多线程配置?

Redis 6.0 的多线程默认是禁用的,只使用主线程。如需开启需要修改 redis.conf 配置文件:io-threads-do-reads yes。

开启多线程后,还需要设置线程数,否则是不生效的。同样修改 redis.conf 配置文件:

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


5 6.0 性能的提升效果如何?

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

国内也有大牛曾使用 unstable 版本在阿里云 esc 进行过测试,GET/SET 命令在 4 线程 IO 时性能相比单线程是几乎是翻倍了。

6  6.0 多线程的实现机制?

 流程简述如下

  • 主线程负责接收建立连接请求,获取 Socket 放入全局等待读处理队列。

  • 主线程处理完读事件之后,通过 RR(Round Robin)将这些连接分配给这些 IO 线程。

  • 主线程阻塞等待 IO 线程读取 Socket 完毕。

  • 主线程通过单线程的方式执行请求命令。

  • 主线程阻塞等待 IO 线程将数据回写 Socket 完毕。

  • 解除绑定,清空等待队列。

该设计有如下特点

  • IO 线程要么同时在读 Socket,要么同时在写,不会同时读或写。

  • IO 线程只负责读写 Socket 解析命令,不负责命令处理。

7 多线程是否会存在线程并发安全问题?

从上面的实现机制可以看出,Redis 的多线程部分只是用来处理网络数据的读写和协议解析,执行命令仍然是单线程顺序执行。

所以我们不需要去考虑控制 Key、Lua、事务,LPUSH/LPOP 等等的并发及线程安全问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值