-
Notifications
You must be signed in to change notification settings - Fork 467
Kvrocks 请求处理框架介绍
Kvrocks 的网络请求处理框架与 redis 的类似,同样都采用 reactor 模式设计,不同之处在于并发访问的实现。Redis 自身封装了多种 I/O 多路复用技术来实现不同平台上的并发访问,而 kvrocks 使用 libevent 库实现。Redis 是单线程实现并发访问,而 kvrocks 是多线程实现,kvrocks 支持同时启动多个 worker,每个 worker 是一个线程,每个 worker 独立使用 libevent 处理网络事件。
Kvrocks 的网络请求处理框架如下图所示,主要可以分为两个层次:网络事件处理层、请求执行层。
网络事件处理层由多个 worker 线程组成,并发的处理客户端与 kvrocks 之间的网络事件。
Kvrocks 创建多个 worker 线程来处理网络请求,默认为 8 个 worker;每个 worker 都监听一个 socket,使用内核的 Ip/Port 复用机制,所有 socket 都绑定在相同的 Ip/Port 上;多个线程同时监听处理网络请求,由操作系统内核实现请求在多个 worker 间的均衡,实现 kvrocks 的 client 建链的并发访问。
每个 worker accept 的连接由该 worker 进行维护,每条连接上网络事件都在同一个 worker 线程中进行处理。也就是说,worker 线程同时负责监听事件处理,还负责请求事件的处理。网络事件的并发处理由 libevent 实现,libevent 有关的内容参见文末附链接。
执行层即为各数据类型的实现,kvrocks 支持 string/hash/set/zset/list/bitmap/sortint 共 7 种 key 类型。请求处理通过解析请求、查询这些命令实现,获取到正确的命令并执行,实现对应数据类型的读取、写入等操作。
Memcached 网络处理模型如下图所示,memcached 是多线程模型,分主线程、worker 线程池子,由主线程监听外部连接请求,当 accept 请求后,就交给某一个 worker 线程进行后续连接的事件处理。worker 线程与主线程之间交互通过 pipe 实现,即 worker 线程同时处理与主线程之间的 pipe 上的事件处理,也处理 worker 自身负责的连接的网络事件处理。
Tendis 网络处理模型如下图所示,与 memcached 类似,都拆分出监听线程负责监听外部连接请求,以及工作线程池进行连接事件处理。不同之处在于将网络 I/O 与事件处理进行了进一步拆分,分为网络 I/O 线程池与 worker 线程池,分别处理网络 I/O 与实际的请求处理。两个线程池之间通过工作队列与 Response 队列进行通信。
Kvrocks 与以上两者之间的主要异同:
- Kvrocks 与以上两者的实现相同之处在于都是采用多线程模型实现并发;
- 主要不同在于 kvrocks 建链请求是由多个 worker 线程同时进行,worker 线程还同时负责管理由其建立的连接,连接上的请求处理也在同一个 worker 中进行;
- Kvrocks 不拆分监听线程与请求处理线程,不需要维护工作队列,也不用维护多个线程池,在实现高效的并发的同时架构更简单易于理解;
libevent 源码: https://github.com/libevent/libevent
libevent 解析参考:https://aceld.gitbooks.io/libevent/content/
- Overview
- Support Commands
- Server Installation
- User Guide
- Tools
- Operations
- Cluster
- Performance & Troubleshooting
- FAQ