a high-performance, large-capacity, multi-tenant, data-persistent, strong data consistency based on raft, Redis-compatible elastic KV data storage system based on RocksDB
BSD 3-Clause "New" or "Revised" License
202
stars
63
forks
source link
feat:Support network read/write separation and command thread pool #164
void CmdSlowWorker::LoadWork() {
{
std::unique_lock lock(pool_->slowMutex_);
while (pool_->slowTasks_.empty() && loopMore) { // loopMore is used to get the fast worker, 定时唤醒去快命令队列中找任务
pool_->slowCondition_.wait_for(lock, std::chrono::milliseconds(waitTime));
loopMore = false;
}
const auto num = std::min(static_cast<int>(pool_->slowTasks_.size()), onceTask_);
std::move(pool_->slowTasks_.begin(), pool_->slowTasks_.begin() + num, std::back_inserter(selfTask));
pool_->slowTasks_.erase(pool_->slowTasks_.begin(), pool_->slowTasks_.begin() + num);
}
fix issue https://github.com/OpenAtomFoundation/pikiwidb/issues/100
加了网络的读写分离,和命令在线程池中执行
这个pr只有 线程池和读写分离功能
后续 还有两个功能, 待开发
sync.pool
libevent
依赖, 使用 最早的 网络库cmd_thread_pool
是命令的线程池, 目前支持了快慢命令分离, 但是因现在命令中没有加对应的flag,就暂时全都按照快命令执行了这是目前我想到的问题
get a
, 这个命令的读线程是线程 R1, 这个线程是 client在连接网络时就确定了. 当这个命令在线程池中执行完成后,会发到写线程中, 这时候, 会轮训 所有写线程, 找到一个写线程, 然后执行写入网络的操作. 可能这次放到 w2 中, 下次会放到 W3 中, 这段代码体现在WorkIOThreadPool::PushWriteTask
这个函数中现在的命令线程池中, 所有线程公用了一把锁, 可能会比较重, 如果这部分是瓶颈, 可以和 IO的写线程中那样, 每个写线程 一个独立的队列,然后通过轮训或者别的策略, 向线程池中每个线程的队列加任务,
现在的命令线程池中, 如果慢命令队列是空闲的, 会尝试从 读线程池中偷取 快命令来执行
这段逻辑在
现在还没做对象缓存池, 现在用的做法是 在命令线程池中, 每个线程单独维护一个 cmdTable, 来做命令的隔离
后面设想的是,在读线程中, 解析出 本次命令的参数, 根据第一个参数区分这个命令是 快 / 慢 命令, 并把所有参数 包装成一个 task 放到对应的线程池中. 在对应的线程池中, 获取这个执行这个命令的对象, 然后执行对应的命令
这样做的考虑是, 在 读线程中就确定命令,并且获取命令的对象, 这样就能做到在向 命令线程池中添加任务时就知道, 当前命令时快命令还是慢命令, 这样就能比较好的做到快慢分离了
每个线程单独维护一个 cmdTable 这个逻辑在