背景
有一个东西叫io模型、还一个东西叫线程模型。
io主要讲的是通过多路复用技术通过一个进程或者线程接受成千上万请求,你接受到了请求怎么处理就是我们今天聊到的线程模型。你到底是只有一个进程/线程,还是多个进程/线程就看你自己的。
reactor
reactor叫反应堆,还一个外号叫dispatcher。
dispatcher分配的意思,分配什么啊?当然是你有事件来了我给你分配啊,这里的事件不就是io请求么,通过多路复用来了一个io事件,我给你分配一个方法处理一下。
单reactor单线程
说白了就是又当爹又当妈,爹妈是一个进程,通过select获取到事件后,如果是accpet就分配给acceptor,如果是读写事件呢就调用handle处理请求(读、处理、写)。就好像一个while循环,来一件事干一件事。
while{
读
处理(处理时一直阻塞)
写
}
单reactor多线程
那聪明的你也能想到,干嘛不多线程啊,现在cpu都是多核干嘛不用啊,爹妈双全,爹是一个进程,通过select获取到事件后,如果是accpet就分配给acceptor,如果是读写事件呢就调用handle处理请求,但是这里妈就出现了,妈是一线程池负责处理事件,之前在handle中包含 读、处理、写,最费时间的就是处理,到处理这步就交给线程池处理,处理完再交给爸。
while{
读
交给线程池处理(不阻塞)
写
}
多reactor多线程(主从reactor多线程)
只有有单的架构就容易出现瓶颈,例如单reactor,虽然处理交给了多线程去处理,但是读写都还是在一个线程/进程中,那就多reactor呗!但是这里不是说把单reactor多线程中的reactor直接变成多reactor,还是有点区别的,多reactor多线程中的多reactor是一种主从关系。
主reactor负责接收accept事件,收到accept后分配给子reactor,这里的子reactor可以很多,子reactor通过select监听链接的读写事件,假设有1个主reactor4个子reactor ,主reactor收到1000个accept事件分配给4个子reactor,每个子reactor处理250个读写事件,性能一下就上来了。
子reactor收到读写事件后又开始有区别了,第一种子reactor单个线程/进程处理读 、处理 、写 类似单reactor单线程的模式。第二种子reactor处理读 、写 ,处理交给线程池处理,类似单reactor多线程。
更多的还是第一种,因为相对来说比较简单,不要觉得线程越多越好。
聊一聊redis
尽然都说到这里了就聊聊redis吧,以前一直说redis是单线程,后来从6.0以后说redis是多线程了,其实指的就是线程模型。6.0以前redis的线程模型就是单reactor单线程,也就是说redis的 接受请求 读请求 处理请求 写请求都是由一个线程完成,因为redis认为因为基于内存cpu不是瓶颈所以没必要引入多线程,反而麻烦,到了6.0以后redis的线程模型变成了类似多reactor多线程(主从reactor多线程),我们知道多reactor多线程每个线程都会进行 读 处理 写,但是redis的多reactor多线程 子reactor只进行读写,所有处理还都是在主reactor,为什么这样呢?因为redis尽量想向6.0之前的版本靠拢。