|
1 | 1 | # KVstorageBaseRaft-cpp |
2 | 2 |
|
3 | | -> ⭐️ 本项目为[【代码随想录知识星球】](https://programmercarl.com/other/kstar.html) 教学项目 |
4 | | -> ⭐️ 在 [分布式KV存储项目文档](https://www.programmercarl.com/other/project_fenbushi.html) 里详细讲解:**项目前置知识 + 项目细节 + 代码解读 + 项目难点 + 面试题与回答 + 简历写法 + 项目拓展**。 全面帮助你用这个项目求职面试! |
| 3 | +本项目目前只在[知识星球](https://programmercarl.com/other/kstar.html)答疑并维护。 |
5 | 4 |
|
| 5 | +[代码随想录知识星球](https://programmercarl.com/other/kstar.html)分布式存储项目目前已经做了全面升级: |
6 | 6 |
|
7 | | -> notice:本项目的目的是学习Raft的原理,并实现一个简单的k-v存储数据库。因此并不适用于生产环境。 |
| 7 | +<div align="center"><img src='https://file1.kamacoder.com/i/algo/20241209105519.png' width=500 alt=''></img></div> |
8 | 8 |
|
9 | | -## 分支说明 |
10 | | -- main:最新内容,已经实现一个简单的clerk |
11 | | -- rpc:基于muduo和rpc框架相关内容 |
12 | | -- raft_DB:基于Raft的k-v存储数据库,主要用于观察选举过程 |
| 9 | +相对于第一版补充如下内容: |
13 | 10 |
|
14 | | -## 使用方法 |
| 11 | +学习这个项目的前提知识: |
15 | 12 |
|
16 | | -### 1.库准备 |
17 | | -- muduo |
18 | | -- boost |
19 | | -- protoc |
20 | | -- clang-format(可选) |
| 13 | +* 学习这个项目需要掌握的技能部分,做了更详细的说明。比如c++基础要求、raft的学习博客、KV的学习博客、RPC的博客提供学习。 |
| 14 | +* 补充了学习raft或rpc的连接、视频等,以及RPC在本项目中运用的测试文件提供学习。 |
21 | 15 |
|
22 | | -**安装说明** |
| 16 | +代码模块讲解补充: |
23 | 17 |
|
24 | | -- clang-format,如果你不设计提交pr,那么不用安装,这里也给出安装命令:`sudo apt-get install clang-format` |
25 | | -- protoc,本地版本为3.12.4,ubuntu22使用`sudo apt-get install protobuf-compiler libprotobuf-dev`安装默认就是这个版本 |
26 | | -- boost,`sudo apt-get install libboost-dev libboost-test-dev libboost-all-dev` |
27 | | -- muduo,https://blog.csdn.net/QIANGWEIYUAN/article/details/89023980 |
28 | | -> 如果库安装编译本仓库的时候有错误或者需要确认版本信息,可以在issue页面查看其他人遇到的问题和分享: [链接](https://github.com/youngyangyang04/KVstorageBaseRaft-cpp/issues) |
| 18 | +* 补充了部分注释,简化了原文档冗余的注释。 |
| 19 | +* 增加了部分关键函数的流程解释。 |
| 20 | +* 做了更清晰的目录。 |
| 21 | +* 补充了RPC部分在原文档中的仓库位置,实现了方便阅读方便查看。 |
| 22 | +* 对原文的内容进行整合基本原文档的部分内容有关代码部分全在该模块,并且通过目录就可以学习你想要的。 |
29 | 23 |
|
30 | | -### 2.编译启动 |
| 24 | +## 项目背景相关 |
31 | 25 |
|
32 | | -#### 先启动rpc |
33 | | -``` |
34 | | -cd KVstorageBaseRaft-cpp // 进入项目目录 |
35 | | -mkdir cmake-build-debug |
36 | | -cd cmake-build-debug |
37 | | -cmake .. |
38 | | -make |
39 | | -``` |
40 | | -之后在目录bin就有对应的可执行文件生成: |
| 26 | +### 背景 |
41 | 27 |
|
42 | | -* provider |
43 | | -* consumer |
| 28 | +在当今大规模分布式系统的背景下,需要可靠、高可用性的分布式数据存储系统。 |
44 | 29 |
|
45 | | -``` |
46 | | -./provider |
47 | | -``` |
| 30 | +传统的集中式数据库在面对大规模数据和高并发访问时可能面临单点故障和性能瓶颈的问题。 |
48 | 31 |
|
49 | | - |
| 32 | +为了解决这些问题,本项目致力于构建一种基于Raft一致性算法的分布式键值存储数据库,以确保数据的一致性、可用性和分区容错性。 |
50 | 33 |
|
| 34 | +### 目的 |
51 | 35 |
|
52 | | -换一个窗口,在执行 consumer |
| 36 | +学习了Raft算法之后手动实现,**并基于此搭建了一个k-v存储的分布式数据库**。 |
53 | 37 |
|
54 | | -``` |
55 | | -./consumer |
56 | | -``` |
| 38 | +### 解决的问题 |
57 | 39 |
|
58 | | - |
| 40 | +- **一致性:** 通过Raft算法确保数据的强一致性,使得系统在正常和异常情况下都能够提供一致的数据视图。 |
| 41 | +- **可用性:** 通过分布式节点的复制和自动故障转移,实现高可用性,即使在部分节点故障的情况下,系统依然能够提供服务。 |
| 42 | +- **分区容错:** 处理网络分区的情况,确保系统在分区恢复后能够自动合并数据一致性。 |
59 | 43 |
|
60 | | -运行即可,注意先运行provider,再运行consumer,原因很简单:需要先提供rpc服务,才能去调用。 |
| 44 | +### 技术栈 |
61 | 45 |
|
| 46 | +- **Raft一致性算法:** 作为核心算法,确保数据的一致性和容错性。 |
| 47 | +- **存储引擎:** 使用适当的存储引擎作为底层存储引擎,提供高效的键值对操作。目前选择的是跳表,但是可以替换为任意k-v数据库。 |
62 | 48 |
|
63 | | -#### 使用raft集群 |
64 | | -之后在目录bin就有对应的可执行文件生成, |
65 | | -``` |
66 | | -// make sure you in bin directory ,and this has a test.conf file |
67 | | -./raftCoreRun -n 3 -f test.conf |
68 | | -``` |
| 49 | +### 项目范围 |
69 | 50 |
|
70 | | - |
| 51 | +项目的初始版本将实现基本的Raft协议和键值存储功能。 |
71 | 52 |
|
72 | | -这里更推荐一键运行,使用clion/clion nova,点击这个按钮即可: |
| 53 | +后续版本可能包括性能优化、安全性增强、监控和管理工具的开发等。 |
73 | 54 |
|
74 | | - |
| 55 | +## 前置知识储备 |
75 | 56 |
|
76 | | -正常运行后,命令行应该有如下raft的运行输出: |
77 | | -``` |
78 | | -20231228 13:04:40.570744Z 615779 INFO TcpServer::newConnection [RpcProvider] - new connection [RpcProvider-127.0.1.1:16753#2] from 127.0.0.1:37234 - TcpServer.cc:80 |
79 | | -[2023-12-28-21-4-41] [Init&ReInit] Sever 0, term 0, lastSnapshotIncludeIndex {0} , lastSnapshotIncludeTerm {0} |
80 | | -[2023-12-28-21-4-41] [Init&ReInit] Sever 1, term 0, lastSnapshotIncludeIndex {0} , lastSnapshotIncludeTerm {0} |
81 | | -[2023-12-28-21-4-41] [Init&ReInit] Sever 2, term 0, lastSnapshotIncludeIndex {0} , lastSnapshotIncludeTerm {0} |
82 | | -[2023-12-28-21-4-41] [ ticker-func-rf(1) ] 选举定时器到期且不是leader,开始选举 |
| 57 | +在学习该项目之前,必须知道的内容有: |
83 | 58 |
|
84 | | -[2023-12-28-21-4-41] [func-sendRequestVote rf{1}] 向server{1} 發送 RequestVote 開始 |
85 | | -[2023-12-28-21-4-41] [func-sendRequestVote rf{1}] 向server{1} 發送 RequestVote 開始 |
86 | | -[2023-12-28-21-4-41] [func-sendRequestVote rf{1}] 向server{1} 發送 RequestVote 完畢,耗時:{0} ms |
87 | | -[2023-12-28-21-4-41] [func-sendRequestVote rf{1}] elect success ,current term:{1} ,lastLogIndex:{0} |
| 59 | +* 语言基础,比如:`mutex` ,什么是序列化和反序列化 |
| 60 | +* RPC相关,至少要知道什么是RPC |
88 | 61 |
|
89 | | -[2023-12-28-21-4-41] [func-sendRequestVote rf{1}] 向server{1} 發送 RequestVote 完畢,耗時:{0} ms |
90 | | -[2023-12-28-21-4-41] [func-Raft::doHeartBeat()-Leader: {1}] Leader的心跳定时器触发了 |
| 62 | +最好知道的内容有: |
91 | 63 |
|
92 | | -[2023-12-28-21-4-41] [func-Raft::doHeartBeat()-Leader: {1}] Leader的心跳定时器触发了 index:{0} |
| 64 | +- c11的部分新特性:`auto` 、`RAII`等 |
| 65 | +- 分布式的基础概念:容错、复制等 |
93 | 66 |
|
94 | | -[2023-12-28-21-4-41] [func-Raft::doHeartBeat()-Leader: {1}] Leader的心跳定时器触发了 index:{2} |
| 67 | +## 你的收获 |
95 | 68 |
|
96 | | -[2023-12-28-21-4-41] [func-Raft::sendAppendEntries-raft{1}] leader 向节点{0}发送AE rpc開始 , args->entries_size():{0} |
97 | | -[2023-12-28-21-4-41] [func-Raft::sendAppendEntries-raft{1}] leader 向节点{2}发送AE rpc開始 , args->entries_size():{0} |
98 | | -[2023-12-28-21-4-41] [func-Raft::doHeartBeat()-Leader: {1}] Leader的心跳定时器触发了 |
99 | | -``` |
| 69 | +- Raft共识算法的快速理解 |
| 70 | +- 基于共识算法怎么搭建一个分布式的k-v数据库 |
100 | 71 |
|
101 | | -#### 使用kv |
102 | | -在启动raft集群之后启动`callerMain`即可。 |
| 72 | +需要注意的是,分布式式的共识算法实现本身是一个比较严谨的过程。 |
103 | 73 |
|
| 74 | +因为其本身的存在是为了多个服务器之间通过共识算法达成一致性的状态,从而避免单个节点不可用而导致整个集群不可用。 |
104 | 75 |
|
105 | | -## Docs |
106 | | -- 如果你想创建自己的rpc,请参考example中rpc的md文件和friendRPC相关代码.此外可以见rpc分支 |
107 | | -- 各个文件夹文件内容说明:[这里](./docs/目录导览.md) |
108 | | -> notice:在代码编写过程中可能有一些bug改进,其他分支可能并没有修复这些bug以及相应的改进。注意甄别 |
109 | | ->同时欢迎issue提出这些bug或者pr改进。 |
| 76 | +因此在学习过程中必须要考虑不同情况下节点宕机、断网情况下的影响。 |
110 | 77 |
|
111 | | -## todoList |
| 78 | +许多情况需要仔细思考并实验以验证算法正确性,其中的思考别人无法代替,本项目的内容**只能作为分布式共识算法Raft的一个入门的实现,方便大家快速理解Raft算法**,从而写到简历上,如果想全部理解分布式算法的精髓只能多思考多看多总结。 |
112 | 79 |
|
113 | | -- [x] 完成raft节点的集群功能 |
114 | | -- [ ] 去除冗余的库:muduo、boost |
115 | | -- [ ] 代码精简优化 |
116 | | -- [x] code format |
117 | | -- [ ] 代码解读 maybe |
| 80 | +mit6.824课程,如果你已经学习过该课程,那么已经不需要本项目了,本项目的难度和内容小于该课程。 |
118 | 81 |
|
119 | | -## 贡献者列表 |
| 82 | +## 最佳食用指南 |
120 | 83 |
|
121 | | -<!-- readme: contributors -start --> |
122 | | -<!-- readme: contributors -end --> |
| 84 | +**关注Raft算法本身**:首先整个项目最重点也是最难点的地方就是Raft算法本身的理解与实现,其他的部分都是辅助,因此在学习的过程中也最好关注Raft算法本身的实现与Raft类对外暴露的一些接口。 |
| 85 | + |
| 86 | +**多思考错误情况下的算法正确性**:Raft算法本身并不难理解,代码也并不多,但是简单的代码如何保证在复杂情况下的容错呢?需要在完成代码后多思考在代码不同运行阶段如果发生宕机等错误时的正确性。 |
| 87 | + |
| 88 | +## 项目大纲 |
| 89 | + |
| 90 | +项目的大概框图如下: |
| 91 | + |
| 92 | +<div align="center"><img src='https://file1.kamacoder.com/i/algo/20240314115639.png' width=500 alt=''></img></div> |
| 93 | + |
| 94 | +项目大概可以分为以下几个部分: |
| 95 | + |
| 96 | +- **raft节点**:raft算法实现的核心层,负责与其他机器的raft节点沟通,达到 分布式共识 的目的。 |
| 97 | +- **raftServer**:负责raft节点与k-v数据库中间的协调服务;负责持久化k-v数据库的数据(可选)。 |
| 98 | +- **上层状态机**(k-v数据库):负责数据存储。 |
| 99 | +- **持久层**:负责相关数据的落盘,对于raft节点,根据共识算法要求,必须对一些关键数据进行落盘处理,以保证节点宕机后重启程序可以恢复关键数据;对于raftServer,可能会有一些k-v数据库的东西需要落盘持久化。 |
| 100 | +- **RPC通信**:在 领导者选举、日志复制、数据查询、心跳等多个Raft重要过程中提供多节点快速简单的通信能力。 |
| 101 | + |
| 102 | +> 目前规划中没有实现节点变更功能或对数据库的切片等更进阶的功能,后面考虑学习加入。 |
| 103 | +
|
| 104 | +在多个机器启动后,各个机器之间通过网络通信,构建成一个集群,对这样的集群,其对外表现的就像一台单机的k-v数据库一样,且少数节点出现故障不会影响整个集群的工作。 |
| 105 | + |
| 106 | +因此有了Raft算法的集群k-v数据库相对于单机的k-v数据库: |
| 107 | + |
| 108 | +优势:集群有了容错的能力,可以理解成Raft算法可以保证各个机器上的k-v数据库(也称状态机)以相同的顺序执行外部命令。 |
| 109 | + |
| 110 | +劣势:容错能力需要算法提供,因此程序会变得复杂;需要额外对数据进行备份;需要额外的网络通信开销。 |
| 111 | + |
| 112 | +也是因此,其实上层的k-v数据库可以替换成其他的组件,毕竟只是一个状态机而已。 |
| 113 | + |
| 114 | +目前设计的后续主要内容: |
| 115 | + |
| 116 | +1.`Raft`算法的一些概念性内容,比如:Raft算法是什么?Raft算法怎么完成公式?完成Raft算法需要哪几个主要函数?需要哪几个主要的变量维护? |
| 117 | + |
| 118 | +2.`Raft`算法的主要函数实现思路及代码,主要函数包括:`AppendEntries` `sendRequestVote` `sendAppendEntries` `RequestVote` 等 |
| 119 | + |
| 120 | +3.其他部分组件,包括:RPC通信组件、k-v数据库、中间沟通数据库和raft节点的`raftServer` |
| 121 | + |
| 122 | +## 项目难点 |
| 123 | + |
| 124 | +难点就是项目主要的几个功能模块的实现。 |
| 125 | + |
| 126 | +- Raft算法的理解与实现 |
| 127 | +- RPC通信框架的理解与实现 |
| 128 | +- k-v数据库 |
| 129 | + |
| 130 | +## 简历写法 |
| 131 | + |
| 132 | +学习完本项目,如何写到简历上呢? |
| 133 | + |
| 134 | +在知识星球专栏里会给出本项目的简历写法,为了不让 这些写法重复率太高,所以公众号上是打码的。 |
| 135 | + |
| 136 | +<div align="center"><img src='https://file1.kamacoder.com/i/algo/20241209105923.png' width=500 alt=''></img></div> |
| 137 | + |
| 138 | +## 本项目常见问题 |
| 139 | + |
| 140 | +同时项目专栏也会针对本项目的常见问题,经行归类总结,并持续更新 |
| 141 | + |
| 142 | +<div align="center"><img src='https://file1.kamacoder.com/i/algo/20241209105858.png' width=500 alt=''></img></div> |
| 143 | + |
| 144 | +## 项目优化点 |
| 145 | + |
| 146 | +大家做这个项目,完成基础功能之后,可以按照如下方向继续优化这个项目: |
| 147 | + |
| 148 | +<div align="center"><img src='https://file1.kamacoder.com/i/algo/20241215174241.png' width=500 alt=''></img></div> |
| 149 | + |
| 150 | +## 项目专栏部分截图 |
| 151 | + |
| 152 | +<div align="center"><img src='https://file1.kamacoder.com/i/algo/20241209105756.png' width=500 alt=''></img></div> |
| 153 | + |
| 154 | +<div align="center"><img src='https://file1.kamacoder.com/i/algo/20241209105815.png' width=500 alt=''></img></div> |
| 155 | + |
| 156 | +<div align="center"><img src='https://file1.kamacoder.com/i/algo/20241209105829.png' width=500 alt=''></img></div> |
| 157 | + |
| 158 | +------------------- |
| 159 | + |
| 160 | +## 分布式存储项目专栏 |
| 161 | + |
| 162 | +**本文档仅为星球内部专享,大家可以加入[知识星球](https://programmercarl.com/other/kstar.html)里获取,在星球置顶一** |
123 | 163 |
|
124 | 164 | ## Star History |
125 | 165 |
|
|
0 commit comments