追求性能极致:Redis6.0的多线程模型( 二 )


追求性能极致:Redis6.0的多线程模型

文章插图
既然读写网络的 read/write 系统调用占用了Redis 执行期间大部分CPU 时间,那么要想真正做到提速,必须改善网络IO性能 。我们可以从这两个方面来优化:
  • 提高网络 IO 性能,典型实现方式比如使用 DPDK 来替代内核网络栈的方式
  • 使用多线程 , 这样可以充分利用多核CPU,同类实现案例比如 Memcached 。
协议栈优化的这种方式跟 Redis 关系不大,所以最便捷高效的方式就是支持多线程 。总结起来,redis支持多线程就是以下两个原因:
  • 可以充分利用服务器CPU的多核资源,而主线程明显只能利用一个
  • 多线程任务可以分摊 Redis 同步 IO 读写负荷 , 降低耗时
6.0版本优化之后 , 主线程和多线程网络IO的执行流程如下:
追求性能极致:Redis6.0的多线程模型

文章插图
具体步骤如下:
  • 主线程建立连接,并接受数据,并将获取的 socket 数据放入等待队列;
  • 通过轮询的方式将 socket读取出来并分配给 IO 线程;
  • 之后主线程保持阻塞,一直等到 IO 线程完成 socket 读取和解析;
  • I/O 线程读取和解析完成之后,返回给主线程 ,主线程开始执行 Redis 命令;
  • 执行完Redis命令后,主线程阻塞 , 直到IO 线程完成 结果回写到socket 的工作;
  • 主线程清空已完成的队列,等待客户端新的请求 。
本质上是将主线程 IO 读写的这个操作 独立出来,单独交给一个I/O线程组处理 。这样多个 socket 读写可以并行执行,整体效率也就提高了 。同时注意 Redis 命令还是主线程串行执行 。
开启多线程的方式Redis6.0的多线程默认是禁用的,只使用主线程 。如需开启需要修改redis.conf配置文件:
# io-threads-do-reads noio-threads-do-reads yes开启多线程后,还需要设置线程数,否则是不生效的 。同样修改redis.conf配置文件 。关于线程数的设置,官方有一个建议:4 核的机器建议设置为 2 或 3 个线程 , 8核的建议设置为 6 个线程 , 线程数一定要小于机器核数 。线程数并不是越大越好,官方认为超过了 8 个就很难继续提效了,没什么意义 。
# 假设你的CPU核数是8核,尽量配置成 5~6io-threads 5总结
  • 6.0之前,Redis所谓的单线程并不是所有工作都是只有一个线程在执行,而是指Redis的网络IO和读写是由一个线程来完成的 。其他诸如持久化、异步删除、集群数据同步等,其实是由额外的线程执行的 。
  • 互联网飞速发展 , 开发人员面临的线上流量场景越来越大 , 再使用单线程模式会导致在网络 I/O 浪费太多时间 , 极大的降低吞吐量,而普遍多核的cpu又没有得到有效的利用 。
  • 使用多线程,这样可以充分利用多核CPU,提高网络的 read/write 效率 。
  • 配置 Threaded I/O 多线程模式的时候,线程数一定要小于机器核数,否着意义不大 。
【追求性能极致:Redis6.0的多线程模型】

推荐阅读