Skip to content

liuxuzxx/raft

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

73 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

# Raft
## 总结
```
Raft协议是一个一致性的协议,算是简单版本的Paxos协议的变通实现,需要真实的使用Go代码
来实现一下,帮助理解,也揭开这些个所谓协议的神秘面纱!
```

# In Search of an Understandable Consensus Algorithm (Extend Version)

## 概述
Raft是一个共识的算法!
```
如何理解达成共识这个单词啊,其实就是一致性的另外一种说法而已,例如:开会研究达成了共识,意思
就是说意见统一了!
```
## leader的选举(Leader election)
### leader选举的规定
1. Election Safety:在某个时代,最多一个leader被选出出来
2. Leader Append-Only:leader不能覆盖或者是删除他自己的log,他只能新增新的log
3. Log Matching:如果两条log一样,那么他们之前的log都一样
4. Leader Completeness:凡是写入到log的,必须是大部分节点都已经写入成功的时候才会写入到log
5. State Machine Safety:如果一个index所指引的log被应用到状态机了,那么其他的服务不允许使用这个index了
### leader的选举过程
1. 各个node采用心跳的机制出发leader的选举
2. 当node启动的时候是Follower角色
3. Follower给自己的term+1,然后修改自己的角色为candidate,并且给自己投一票
4. 在此之后接收到别的RPC投票请求一律投递不同意
5. 宣传自己,朝向各个node发送投票的请求
6. 遇到以下三种情形决定生死:
```
1.这个node赢得了这次选举(超过半数的node投了他的票)
2.其他node获得了选举,并朝向他发送了通知(leader广而告之)
3.一个周期时间过后,没有任何胜者(预示着开始新一轮投票的开始)
```

### leader可能遇到的问题
#### 1.随机时间太短
##### 描述
```
当设置触发投票的时间过短的时候,容易出现vote平均的问题,例如:设置定时的时间在2ms内的时候,5个节点,
就会出现投票被平均分配的概率很大,当然这个也和网速和启动的时间有关系。
```
##### 解释
```
原因是触发时间较短,导致每个节点都首先投递了自己一票,造成了投票的均分的概率很大!
不过在启动的时候,也需要时间,第一轮投票基本上无法决定leader,需要第二轮投票!
```
## 日志复制(Log Replication)
### 解释
```
一旦Leader被elected被选举出来之后,Leader节点开始服务于客户端的请求.客户端发送带有一定
类型的命令请求到Leader节点.Leader添加命令到自己的log(这个log不是我们的INFO ERROR这种
记录类型的log日志,而是数据库.),然后开始并行的发送给下面所有Follower Node节点,只有当被
安全的复制到Follower Node集群的时候(这个安全的意思是大部分Follower Node都已经复制成功了)
才会被应用到Leader的state machine当中,并且归还结果给客户端(如果一直不成功,岂不是卡死了!)
.如果出现网络包丢失,Followers挂掉,或者运行很慢,那么就循环发送,直到回复为止.
```
### 如何持久化log
#### 问题描述
```
由于Leader接收到的客户请求很多,这个时候不能一直保存在内存当中,不然内存迟早会爆掉?
```
#### 解决方案
```
解决方案很多,因为存储的是不规则的信息,所以可以一行一行的存储,或者是模仿Redis了,RocketMQ等等
持久化数据的方案:实体数据长度+实体数据字节(可以是JSON字符串,也可以是经过序列化之后压缩的都行)
```
## 安全性(Safety)

## 测试案例
### 描述
因为Raft协议是由多个独立的进程来实现的,所以,这中间就需要测试很多种情况下,集群是如何处理的
### 测试案例
#### Leader节点宕机了
#### 有Follower节点断网了
#### 日志复制缓慢
#### 新节点加入
#### log过大
```
log信息的持久化,刚开始的时候选用的是JSON,但是出现的问题是:文件体积过大,解析速度等待验证!
100w信息,大概需要56MB的空间!当使用JSON进行序列化的时候.
使用pb之后,大小确实减少了不少,请求50w次的数据量是:10MB空间,对比之前的28MB/50w,约等于1/3的空间

```