Redis 6.0为什么引入多线程
Posted Shi Peng
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Redis 6.0为什么引入多线程相关的知识,希望对你有一定的参考价值。
一、前言
Redis 6.0首次引入了多线程。
看下官方发布的新版和旧版的性能对比:
1)get的性能对比:
2)set的性能对比:
可以看出,无论读还是写,多线程性能都远好于单线程,几乎翻倍了。上图仅是简单验证,仅作为参考,不能作为线上生成环境的指标。
二、Redis多线程
2.1、Redis 6.0之前的版本真的是单线程吗?
Redis是基于Reactor模式开发了网络事件处理器,这个处理器被称为文件事件处理器。他的组成分4部分:
- 多个socket
- IO 多路复用
- 文件事件分派器
- 事件处理器
正因为文件事件分派器是单线程的,所以Redis才叫做单线程模型。
Redis之前用单线程模型,是因为性能不在CPU,而在内存和网络。如要用到CPU多核,可搭建多个Redis实例来解决。
其实,Redis 4.0开始就有了多线程概念了,比如Redis通过多线程在后台删除对象。
2.1.1、Redis 6.0之前为什么一直不用多线程?
多线程引入了程序执行顺序不确定的问题,且带来了线程切换、加锁等性能问题。
Redis通过Reactor模型,性能已经非常好,没必要使用多线程。
且单线程使得redis内部实现复杂度大大降低,Hash的惰性Rehash, lpush等线程不安全的命令,都不必加锁。
2.1.2、Redis 6.0为什么要引入多线程呢?
Redis的性能瓶颈不在CPU,而在内存和网络。
内存不够,可以做数据结构优化。所以网络才是关键,网络IO在执行期间大量占用了CPU,所以如果网络IO时引入多线程,对性能提升很大。
所以总结起来,Redis6.0支持多线程有两个原因:
1)充分利用CPU多核,6.0之前主线程只能利用一个核
2)多线程任务可以分摊Redis同步IO读写负荷。
2.2、Redis 6.0是否默认开启了多线程?
没有,默认关闭。但可以在conf文件中配置。
官方建议:4核的机器建议设置为2或3个线程,8核的建议设为6个线程,线程数一定要小于机器核数,尽量不要超过8个。
三、Redis 6.0多线程的实现机制
流程简述为:
1)主线程负责接收并建立连接请求,获取socket放入全局等待读处理队列
2)主线程处理完读事件后,通过Round Robin讲这些连接分配给这些IO线程
3)主线程阻塞等待IO读取socket完毕
4)主线程通过单线程的方式执行请求命令,请求数据读取并解析完成,但并不执行。
5)主线程阻塞等待IO线程将数据回写socket完毕
6)解除绑定,清空等待队列
也就是说,真正执行redis命令时,还是单线程的,如步骤4.
多线程,发生在网络IO,步骤三和步骤五
见上图的红字。
3.1、开启多线程后,是否会存在线程并发安全问题?
不会:
1)Redis多线程部分仅用于处理网络IO和协议解析
2)Redis执行命令仍然是单线程的
以上是关于Redis 6.0为什么引入多线程的主要内容,如果未能解决你的问题,请参考以下文章
Redis单线程已经很快,为何6.0要引入多线程?有啥优势?