当前位置: 首页 > news >正文

基于Raft分布式Kv存储:Kvserver怎么与上层KvDB沟通?

这里需要先澄清:项目里的“上层 KVDB”并不是独立进程,也没有通过 RPC 与KvServer通信。

KVDB 就是KvServer内部持有的跳表对象

class KvServer { private: SkipList<std::string, std::string> m_skipList; };

因此两者通过普通的 C++ 成员函数调用沟通。

```mermaid flowchart TD C["Clerk 客户端"] -->|"RPC"| K["KvServer RPC 接口"] K -->|"Start(Op)"| R["本机 Raft"] R -->|"已提交 ApplyMsg"| AC["applyChan"] AC --> A["KvServer 应用线程"] A -->|"insert_set_element"| DB["跳表 KVDB"] K -->|"search_element"| DB ```

写操作
客户端发送 Put 后:

Clerk → KvServer::PutAppend() → Raft::Start(op) → Raft 集群复制并提交日志 → applyChan → KvServer::GetCommandFromRaft() → ExecutePutOpOnKVDB() → m_skipList.insert_set_element()

关键代码:

void KvServer::ExecutePutOpOnKVDB(Op op) { m_mtx.lock(); m_skipList.insert_set_element(op.Key, op.Value); m_lastRequestId[op.ClientId] = op.RequestId; m_mtx.unlock(); }

见 [kvServer.cpp (line 66)](/C:/Users/LENOVO/Desktop/KVstorageBaseRaft-cpp-main/src/raftCore/kvServer.cpp:66)。

最重要的一点是:KvServer 收到 Put RPC 后不会立即写跳表,必须等 Raft 日志提交后才能写。

Raft 如何通知 KvServer
KvServer和本机Raft共享一个队列:

std::shared_ptr<LockQueue<ApplyMsg>> applyChan;

初始化 Raft 时传进去:

m_raftNode->init(servers, m_me, persister, applyChan);

Raft 提交日志后执行:

applyChan->Push(message);

KvServer 一直阻塞读取:

void KvServer::ReadRaftApplyCommandLoop() { while (true) { auto message = applyChan->Pop(); if (message.CommandValid) { GetCommandFromRaft(message); } if (message.SnapshotValid) { GetSnapShotFromRaft(message); } } }

见 [kvServer.cpp (line 281)](/C:/Users/LENOVO/Desktop/KVstorageBaseRaft-cpp-main/src/raftCore/kvServer.cpp:281)。

随后GetCommandFromRaft()解析Op并修改 KVDB:

if (!ifRequestDuplicate(op.ClientId, op.RequestId)) { if (op.Operation == "Put") { ExecutePutOpOnKVDB(op); } if (op.Operation == "Append") { ExecuteAppendOpOnKVDB(op); } }

读操作
Get 也先进入 Raft,提交后唤醒等待的 RPC 线程,最后直接查询跳表:

m_skipList.search_element(op.Key, *value);

对应流程:

KvServer::Get() → Raft::Start(GetOp) → 等待该日志提交 → ExecuteGetOpOnKVDB() → m_skipList.search_element() → 返回 value

Get 进入 Raft 的目的,是保证读取发生在之前已经提交的写操作之后,提供线性一致读。

快照通信
KvServer 制作快照时直接调用跳表:

m_serializedKVData = m_skipList.dump_file();

恢复快照时:

m_skipList.load_file(m_serializedKVData);

所以 KvServer 和 KVDB 之间有三类直接调用:

写入:insert_set_element(key, value) 读取:search_element(key, value) 快照:dump_file() / load_file()
http://www.jsqmd.com/news/1290924/

相关文章:

  • 8 月技术阅读清单:值得精读的论文、博客与开源项目
  • Unity 2022 LTS与PICO SDK 4.5.0开发环境搭建全攻略
  • 四足机器人ROS仿真控制:从零到一的完整实战指南
  • 金融AI对决:Qwen3.7-Max屠榜降本60%
  • 什么是导数
  • 2026年近期河南专业的抗菌橡胶发泡料品牌厂商推荐哪家?深度解析新乡励行新材料 - 装修教育财税推荐2026
  • 2026推荐广东面条粉厂商联系方式,专业定制化小麦粉供应商深度解析 - 装修教育财税推荐2026
  • 从0到上线仅72小时:广电级AI字幕生成流水线搭建全流程,含ASR对齐、标点修复、政策合规过滤三重硬核模块
  • 三拓化学:涂料油墨消光粉厂家,布局华南广东等地区,赋能行业升级
  • 铜徽章制作全流程指南:从雕刻到电镀的DIY手工教程
  • 第42讲:嵌入式四段式万能Spec模板——适配所有驱动/任务/协议
  • 2026 最新|微信公众号迁移公证书线上办理完整实操指南(附材料、流程、条件、注意事项 + 校验代码)
  • 深度解密Sunshine游戏串流:构建专业级自托管游戏服务器
  • 【2024最硬核AI视频修复方案】:Stable Video Diffusion + RAFT光流增强,实测PSNR达38.6dB(附可复现Colab脚本)
  • C++矩阵操作:东华OJ题解与算法优化
  • Perlin Noise原理与实现:从梯度噪声到程序化地形生成
  • 未来 6 个月 AI Agent 开发趋势:多模态、长上下文和工具编排的预测
  • 运算放大器内部电路深度解析:从晶体管到关键参数
  • 2026 年当下,井冈山正规的吉安腾米厨电生产商哪家强,厨房的烟火气被重新定义?这款吉安腾米厨电凭什么悄悄成了主妇的心头好?-腾米厨电 - 行业甄选官
  • 蚂蚁S9矿板PS 轮询实现非阻塞IO驱动
  • 现代C++有限元框架Feel++:从数学公式到高性能并行计算的工程实践
  • AI课堂系统师生减负增效落地实践|教育数字化一线观察
  • 告别网盘限速!八大主流网盘直链解析工具 LinkSwift 完全指南
  • C++ 中 explicit 详解:阻止隐式类型转换的利器
  • GB/T 14976-2025《输送流体用不锈钢无缝钢管》完整技术解读(新旧对比 + 落地执行指南)
  • 【绝密级】头部超甲级院AI效果图生产SOP(非公开版):GPU集群调度策略+语义分割后处理链+客户反馈闭环模型
  • DLSS Swapper终极指南:免费开源工具一键升级游戏DLSS/FSR/XeSS版本
  • 2026年优选公寓床上用品实力厂家推荐哪家 - 装修教育财税推荐2026
  • 如何免费解锁9大网盘下载速度:直链解析工具终极指南
  • LE5010蓝牙应用开发实战:从SDK例程到产品级功能实现