正式支持多线程!Redis 6.0与老版性能对比评测

导读:Redis 6.0将在今年年底发布,其中引入的最重大的改变就是多线程IO。本文作者深入阅读并解析了关键代码,并且做了基准测试,揭示多线程 IO 特性对Redis性能的提升,十分值得一读。

640?wx_fmt=jpeg林添毅,美图技术经理, 主要负责 NoSQL/消息队列/中间件等基础服务相关研发。在加入美图之前,曾就职于新浪微博架构平台从事基础服务的研发。

前天晚上不经意间看到 Redis 作者 Salvatore 在 RedisConf 2019 分享,其中一段展示了 Redis 6 引入的多线程 IO 特性对性能提升至少是一倍以上,内心很是激动,迫不及待地去看了一下相关的代码实现。

目前对于单线程 Redis 来说,性能瓶颈主要在于网络的 IO 消耗, 优化主要有两个方向:

  1. 提高网络 IO 性能,典型的实现像使用 DPDK 来替代内核网络栈的方式

  2. 使用多线程充分利用多核,典型的实现像 Memcached

协议栈优化的这种方式跟 Redis 关系不大,多线程特性在社区也被反复提了很久后终于在 Redis 6 加入多线程,Salvatore 在自己的博客 An update about Redis developments in 2019 也有简单的说明。但跟 Memcached 这种从 IO 处理到数据访问多线程的实现模式有些差异。Redis 的多线程部分只是用来处理网络数据的读写和协议解析,执行命令仍然是单线程。之所以这么设计是不想因为多线程而变得复杂,需要去控制 key、lua、事务,LPUSH/LPOP 等等的并发问题。整体的设计大体如下:

640?wx_fmt=png

代码实现

多线程 IO 的读(请求)和写(响应)在实现流程是一样的,只是执行读还是写操作的差异。同时这些 IO 线程在同一时刻全部是读或者写,不会部分读或部分写的情况,所以下面以读流程作为例子。分析过程中的代码只是为了辅助理解,所以只会覆盖核心逻辑而不是全部细节。如果想完全理解细节,建议看完之后再次看一次源码实现。

加入多线程 IO 之后,整体的读流程如下:

  1. 主线程负责接收建连请求,读事件到来(收到请求)则放到一个全局等待读处理队列

  2. 主线程处理完读事件之后,通过 RR(Round Robin) 将这些连接分配给这些 IO 线程,然后主线程忙等待(spinlock 的效果)状态

  3. IO 线程将请求数据读取并解析完成(这里只是读数据和解析并不执行)

  4. 主线程执行所有命令并清空整个请求等待读处理队列(执行部分串行)

上面的这个过程是完全无锁的,因为在 IO 线程处理的时主线程会等待全部的 IO 线程完成,所以不会出现 data race 的场景。

注意:如果对于代码实现没有兴趣的可以直接跳过下面内容,对了解 Redis 性能提升并没有伤害。

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值