Redis网络模型与通信协议
网络模型
Redis到底是单线程还是多线程?
如果仅仅聊Redis的核心业务部分(
命令处理),答案是单线程如果是聊整个Redis,那么答案就是多线程
在Redis版本迭代过程中,在两个重要的时间节点上引入了多线程的支持:
Redis v4.0:引入
多线程异步处理一些耗时较旧的任务,例如异步删除命令unlinkRedis v6.0:在
核心网络模型中引入多线程,进一步提高对于多核CPU的利用率
因此,对于Redis的核心网络模型,在Redis 6.0之前确实都是单线程,是利用epoll这样的IO多路复用技术在事件循环中不断处理客户端情况。
为什么Redis要选择单线程?
- 抛开持久化不谈,Redis是
纯内存操作,执行速度非常快,它的性能瓶颈是网络延迟而不是执行速度,因此多线程并不会带来巨大的性能提升。 - 多线程会导致过多的
上下文切换,带来不必要的开销。 - 引入多线程会面临
线程安全问题,必然要引入线程锁这样的安全手段,实现复杂度增高,而且性能也会大打折扣。
Redis通过IO多路复用来提高网络性能,并且支持各种不同的多路复用实现,并且将这些实现进行封装,提供了统一的高性能事件库API库 AE:

Redis单线程网络模型的流程:





Redis多线程网络模型的流程:
Redis网络模型整体就是一个IO多路复用+事件派发的结构,通过epoll_create创建一个epoll对象(包含监听FD的红黑树和就绪FD链表),将ServerSocket的FP通过epoll_ctl注册到epoll对象上监听读事件,然后调用epoll_wait等待就绪FD列表,在遍历就绪FD列表中1.如果发现FD是ServerSocket则派发给连接应答处理器tcpAcceptHandler(调用accept函数获得客户端socket并注册到epoll对象上监听读事件),2.如果发现是ClientSocket则根据事件类型派发:2.1读事件则派发给命令请求处理器readQueryFromClient,完成请求数据的解析和命令处理;2.2写事件则派发给命令回复处理器sendReplyToClient完成响应数据的写回。

通信协议

