Skip to content

Kvrocks 请求处理框架介绍

Wang Yuan edited this page Jul 22, 2021 · 3 revisions

一、综述

Kvrocks 的网络请求处理框架与 redis 的类似,同样都采用 reactor 模式设计,不同之处在于并发访问的实现。Redis 自身封装了多种 I/O 多路复用技术来实现不同平台上的并发访问,而 kvrocks 使用 libevent 库实现。Redis 是单线程实现并发访问,而 kvrocks 是多线程实现,kvrocks 支持同时启动多个 worker,每个 worker 是一个线程,每个 worker 独立使用 libevent 处理网络事件。

二、Kvrocks 网络请求处理框架

Kvrocks 的网络请求处理框架如下图所示,主要可以分为两个层次:网络事件处理层、请求执行层。 kvrocks请求处理框架

2.1 网络事件处理层

网络事件处理层由多个 worker 线程组成,并发的处理客户端与 kvrocks 之间的网络事件。

Kvrocks 创建多个 worker 线程来处理网络请求,默认为 8 个 worker;每个 worker 都监听一个 socket,使用内核的 Ip/Port 复用机制,所有 socket 都绑定在相同的 Ip/Port 上;多个线程同时监听处理网络请求,由操作系统内核实现请求在多个 worker 间的均衡,实现 kvrocks 的 client 建链的并发访问。

每个 worker accept 的连接由该 worker 进行维护,每条连接上网络事件都在同一个 worker 线程中进行处理。也就是说,worker 线程同时负责监听事件处理,还负责请求事件的处理。网络事件的并发处理由 libevent 实现,libevent 有关的内容参见文末附链接。

2.2 请求执行层

执行层即为各数据类型的实现,kvrocks 支持 string/hash/set/zset/list/bitmap/sortint 共 7 种 key 类型。请求处理通过解析请求、查询这些命令实现,获取到正确的命令并执行,实现对应数据类型的读取、写入等操作。

三、业界多线程模型对比

3.1 Memcached

Memcached 网络处理模型如下图所示,memcached 是多线程模型,分主线程、worker 线程池子,由主线程监听外部连接请求,当 accept 请求后,就交给某一个 worker 线程进行后续连接的事件处理。worker 线程与主线程之间交互通过 pipe 实现,即 worker 线程同时处理与主线程之间的 pipe 上的事件处理,也处理 worker 自身负责的连接的网络事件处理。

memcached网络处理模型

3.2 Tendis

Tendis 网络处理模型如下图所示,与 memcached 类似,都拆分出监听线程负责监听外部连接请求,以及工作线程池进行连接事件处理。不同之处在于将网络 I/O 与事件处理进行了进一步拆分,分为网络 I/O 线程池与 worker 线程池,分别处理网络 I/O 与实际的请求处理。两个线程池之间通过工作队列与 Response 队列进行通信。 tendis网络处理模型

3.3 Kvrocks

Kvrocks 与以上两者之间的主要异同:

  1. Kvrocks 与以上两者的实现相同之处在于都是采用多线程模型实现并发;
  2. 主要不同在于 kvrocks 建链请求是由多个 worker 线程同时进行,worker 线程还同时负责管理由其建立的连接,连接上的请求处理也在同一个 worker 中进行;
  3. Kvrocks 不拆分监听线程与请求处理线程,不需要维护工作队列,也不用维护多个线程池,在实现高效的并发的同时架构更简单易于理解;

附:

libevent 源码: https://github.com/libevent/libevent
libevent 解析参考:https://aceld.gitbooks.io/libevent/content/

Clone this wiki locally