感觉作为paxos的升级精简版 Raft在设计之初就以容易理解为目标 看完资料 脑海里都有了大概的轮廓。
有了这些详细的资料甚至是动画演示在前 起始都没多少好说的,本篇知识作为记录下学习点,作为日后回顾提示
在分布式系统中,一致性指的是集群中的多个节点在状态上达成一致.但是在现实场景中,由于程序崩溃、网络故障、硬件故障、断电等原因,节点间的一致性很难保证,这样就需要Paxos、Raft等一致性协议。
Paxos协议是Leslie Lamport在1990年提出的一种基于消息传递的、具有高度容错特性的一致性算法.但是Paxos有两个明显的缺点:第一个缺点就是Paxos算法难以理解.第二个缺点就是并没有提供构建现实系统的良好基础,
有很多工程化Paxos算法的尝试,但是他们对Paxos算法本身做了较大改动,彼此之间的实现差距都比较大
Raft算法是一种用于管理复制日志的一致性算法,在设计Raft算法时设计者就将易于理解作为目标之一,是的Raft算法更易于构建实际的系统,大幅度减少了工程化的工作量。
1 Leader选举
Raft协议的模式是一个Leader节点和多个Follower节点的模式。就是常说的Leader-Follower模式.每个节点有三个状态Leader Follower Candidate状态
Leader负责处理客户端请求 并且将处理结果以log形式同步到其他Follower节点上
在Raft协议中有两个时间控制Leader选举的进度。
一个Leader定时向Follower发送心跳包。
一个是选举超时控制(election timeout),选举超时控制就是一个处于Follower节点等待进入Candidate状态的时间限制。
选举超时控制(election timeout)一般在选择150ms到300ms之间的随机值(概率上避免多个节点同时进入Candidate状态)
若某个节点election timeout进度完成之前都没收到Leader的心跳包,则说明没有Leader,该节点进入Candidate状态.给自己投票,然后给其他节点发送选举请求.
其他节点收到选举请求后,若在当前请求中标记的任期(term)内比自己记录的term相等或者更大,且未进行过投票,则回复答应该投票请求,重置自己的选举超时控制
选举者获取一半以上投票,进入Leader状态,开始给其他节点Follower发送心跳,维持自己的权威
下面来看看多个节点 选择的情况 节点B D同时发起选举投票,并且每个节点都获取一张选票,最后的结果就是随机选举超时时间,选举超时控制(election timeout)一般在选择150ms到300ms之间的随机值(概率上避免多个节点同时进入Candidate状态) 。
最终,重复多次选举投票后(概率很小),某个节点获取一半以上投票,成为Leader。
1 #pragma once 2 #include <iostream> 3 #include <fstream> 4 #include <cassert> 5 #include <string> 6 #include <iostream> 7 #include <vector> 8 #include <map> 9 using namespace std; 10 /* 11 *作 者: itdef 12 *欢迎转帖 请保持文本完整并注明出处 13 *技术博客 http://www.cnblogs.com/itdef/ 14 *技术交流群 群号码:432336863 15 *欢迎c c++ windows驱动爱好者 服务器程序员沟通交流 16 *部分老代码存放地点 17 *http://www.oschina.net/code/list_by_user?id=614253 18 */ 19 const string FILE_NAME = "config.txt"; 20 class ReadConfig { 21 public: 22 ReadConfig(string filename = "") { 23 if (filename.empty()) { 24 file_name = FILE_NAME; 25 } 26 else { 27 file_name = filename; 28 } 29 } 30 ~ReadConfig() {} 31 map<string, string> Do() { 32 tar_path.clear(); 33 ifstream fin; 34 fin.open(file_name); 35 if (false == fin.is_open()) { 36 std::cerr << "open file failed!!" << std::endl; 37 return tar_path; 38 } 39 string s; 40 while (getline(fin, s)) 41 { 42 if ('#' == s[0] || ('/' == s[0] && '/' == s[1])) 43 continue; 44 size_t pos = s.find_first_of("="); 45 if (pos == std::string::npos || pos + 1 >= s.size()) 46 continue; 47 string targetName = s.substr(0, pos); 48 string path = s.substr(pos + 1); 49 std::cout << targetName << " = " << path << std::endl; 50 if (path[0] != ' ') 51 tar_path[targetName] = path; 52 } 53 fin.close(); 54 return tar_path; 55 } 56 private: 57 map<string, string> tar_path; 58 string file_name; 59 };