arana-db / arana-db/kiwi-cpp

kiwi 线程模型,以及改进方案

Open
#87 9 comments 0 reactions 0 assignees View on GitHub
Dominant language
C++
Stars
49
Forks
8
PR merge metrics
No merged PRs in 30d

Description

### 线程模型

![无标题-2024-01-13-2209](https://github.com/user-attachments/assets/6bef2368-fdc7-412f-865b-9d3f7fd1baa2)

这是目前的线程模型,分为IO线程和worker线程,其中

IO线程可以分为 **读线程** 和 **写线程**

worker线程分为 **快** **慢** 命令线程

如果没有开启读写分离,那么IO线程就只有读线程,此时读线程也会处理server向client写数据的功能

---

### 当前的命令处理逻辑

当一个client 使用 tcp连接的server时,这个client会被操作系统内核分配到一个IO线程(fd会分别放到对应的IO读和IO写线程)

当client向server发送数据的时候,会在IO读线程处理,然后解析resp协议,把得到的参数包装成一个 **task** 然后发到 worker线程池中
现在没有区分快慢命令,所有的命令(除了pipeline的命令)都会放到快线程中,pipeline的一组命令会放到 慢线程中

然后在对应的worker线程中,或者对应的命令对象,然后处理命令(操作rocksdb)

命令处理完成后,把数据放到 IO写线程中,然后发回client中

现在每个worker线程中到会有一份 命令对象,也就是 `CmdTable` 这个结构。

---

### 问题

- 首先是内存浪费问题,如果线程池特别大,会有很多份命令对象
- 命令无法在 IO线程处理,如果是一些简单的命令,比如不涉及读写 rocksdb的命令可以直接在IO线程中处理,没必要放到线程池中执行。如果引入缓存层,读写缓存也可以在IO线程完成

### 改进设想

在IO线程就能获取命令对象,并把命令对象放到 **task** 中以前传到线程池中

#### 面临问题

1. 如果每个IO线程都有一份 **CmdTable** 一样会有内存占用问题
2. 如果使用全局唯一的 **CmdTable** 会有多线程锁竞争
3. 每次执行命令初始化初始化一个 **CmdTable** 会频繁 `new` `delete`
4. 全局 **CmdTable** + 线程缓存,实现复杂,功能太复杂了,性能不一定会提升

还请集思广益,想一个好的实现方案

Contributor guide

No contributing guide indexed for this repository

Research direction

Start by tracing the existing CmdTable, task handoff, IO read/write threads, and worker pool described in the issue. Done would require an agreed implementation plan addressing command-object memory duplication, IO-thread handling, locking, and allocation costs; no file or test is identified here.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
backend, databases
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.