基于Raft共识算法的分布式KV存储
WW-RaftKV是一个基于Raft共识算法实现的分布式KV存储系统,支持节点容错、高可用部署和一致性日志复制。该项目为WW系列的分布式学习项目。
- 系统:64位
Linux操作系统 C++版本:C++14- 第三方库:
Protobuf3muduoconcurrentqueue
该实现包含了几个核心模块:KVStore,Logger,Memory-Pool,Raft-Rpc,Raft-Core和Raft-App
- 位于:
raftkv/kvstore/ - 功能:是使用跳表实现的
KV存储,用于提供存分布式存储系统所需要的KV存储功能,提供常见的get,put,update和remove操作。
- 位于:
raftkv/logger - 功能:是一个轻量化的异步日志库,支持自定义格式化输出、同步和异步日志、轮转日志等,用于提供
Raft运行时必要的日志输出。
- 位于:
raftkv/memory-pool - 功能:是一个三级缓存的内存池。它由线程缓存、中心缓存、页缓存三层构成,用于在高频的
Rpc网络通信中,减小new/delete动态分配带来的内存碎片和开销。 - 应用场景:在本项目中,内存池用于
Raft节点的客户端部分内存管理;服务端部分由于本Raft实现的异步设计,请求和响应并不在一个线程中,因此暂不使用内存池,交由Protubuf的Arena管理。
- 位于:
raftkv/raft-rpc - 功能:用于提供
Raft实现中所需要的Rpc功能,该模块是基于Google Rpc框架的扩展。
- 位于:
raftkv/raft-core - 功能:实现了
Raft的核心算法,包括状态机切换、选举、日志复制和推进、心跳等。其核心功能包括:- 节点状态管理:支持
Follower、Candidate、Leader三种角色的状态切换; - 选举机制:实现了基于任期的投票逻辑,支持随机超时选举触发与投票限制;
- 日志复制:
Leader将客户端请求转化为日志条目并同步给其他节点; - 日志一致性保障:通过
prevLogIndex和prevLogTerm保证日志匹配性; - 日志提交与应用:日志在被大多数节点确认后提交,并推送给状态机应用;
- 心跳机制:
Leader定期发送心跳保持领导地位并触发空日志复制; - 任期与投票状态持久化:防止重启后错误行为;
- 快照与日志压缩支持:适用于长时间运行场景下的日志膨胀问题。
- 节点状态管理:支持
- 位于:
raftkv/raft-app - 功能:实现了
Raft的应用层,负责节点间的网络通信,并与Raft算法层交互。
测试代码位于example/中,包含了以下程序和脚本:
raft_example:用于模拟启动集群;raft_client:用于模拟客户端操作;run.sh:启动节点2-6;stop.sh:关闭所有raft_example进程;clean.sh:清理上一次运行痕迹。
raft_example使用方法:
./raft_example n其中n为节点号,该集群中包含0-6共7个节点。example/中还有两个shell脚本,run.sh和stop.sh,其中,run.sh用于启动2-6共5个节点,其日志会重定向到logs/中;stop.sh强制关闭所有raft_example进程;clean.sh清理上一次运行产生的痕迹。
raft_client使用方法:
./raft_client put a b
./raft_client get a
./raft_client update a c
./raft_client remove araft_client默认连接node 0,确保在启动集群时,先启动该节点,再启动剩余节点,以保证node 0能够当选Leader,当node 0不为Leader时,raft_client请求会返回当前Leader的IP地址和端口用于重定向。
当前存储系统支持的操作有:
put:不允许重复的插入键值对,使用方法为put {key} {value}update:更新或插入键值对,使用方法为update {key} {value}get:读取已存在的键值对,使用方法为get {key}remove:删除已存在的键值对,使用方法为remove {key}
mkdir build && cd build
cmake ..
make -j4以下需按顺序启动。
- 窗口1,启动用于观察
Leader日志的节点:
cd build/example/
./raft_example 0- 窗口2,启动用于观察
Follower日志的节点:
cd build/example/
./raft_example 1- 窗口3,启动剩余节点:
cd build/example/
./run.sh- 窗口4,进行客户端操作:
cd build/example/
./raft_client put hello ww-raftkv
./raft_client get hello使用perf工具测试Leader节点的性能,测试基于Debug模式,-O2优化,火焰图如下: