redis 6.0
可以通过如下参数配置多线程模型
io-threads 4<br>
有三个IO 线程,还有一个线程是main线程,main线程负责IO读写和命令执行操作
这三个IO线程只会执行 IO中的write 操作<br>
io-threads-do-reads yes // 将支持IO线程执行 读写任务。
引入多线程的原因
内存的响应时长大约为100纳秒,对于小数据包,Redis服务器可以处理80,000到100,000 QPS,一般来说单线程的Redis已经足够使用
读写网络的read/write系统调用占用了Redis执行期间大部分CPU时间,瓶颈主要在于网络的 IO 消耗
可以充分利用服务器 CPU 资源,目前主线程只能利用一个核
多线程任务可以分摊 Redis 同步 IO 读写负荷
配置
多线程部分只是用来处理网络数据的读写和协议解析,执行命令仍然是单线程顺序执行
不需要去考虑控制 key、lua、事务,LPUSH/LPOP 等等的并发及线程安全问题
io-threads-do-reads yes
多线程默认是禁用的,只使用主线程。如需开启需要修改redis.conf
设置线程数
官方建议4核的机器建议设置为2或3个线程,8核的建议设置为6个线程,线程数一定要小于机器核数
线程数并不是越大越好,官方认为超过了8个基本就没什么意义了
如果开启多线程,至少要4核的机器,且Redis实例已经占用相当大的CPU耗时的时候才建议采用,否则使用多线程没有意义
多线程的实现机制
主线程负责接收建立连接请求,获取 socket 放入全局等待读处理队列
主线程处理完读事件之后,通过 RR(Round Robin) 将这些连接分配给这些 IO 线程
主线程阻塞等待 IO 线程读取 socket 完毕
主线程通过单线程的方式执行请求命令,请求数据读取并解析完成,但并不执行
主线程阻塞等待 IO 线程将数据回写 socket 完毕
解除绑定,清空等待队列
设计特点
IO 线程要么同时在读 socket,要么同时在写,不会同时读或写
IO 线程只负责读写 socket 解析命令,不负责命令处理
IO多路复用
经典的Reactor设计模式,有时也称为异步阻塞IO
多路指的是多个socket连接,复用指的是复用一个线程
多路复用主要有三种技术:select,poll,epoll
epoll是最新的也是目前最好的多路复用技术
采用多路 I/O 复用技术可以让单个线程高效的处理多个连接请求(尽量减少网络IO的时间消耗)
Redis在内存中操作数据的速度非常快(内存内的操作不会成为这里的性能瓶颈),所以造就了Redis具有很高的吞吐量