-
Notifications
You must be signed in to change notification settings - Fork 0
liuxuzxx/raft
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
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的空间 ```