[etcd]raftpd protobuf

Raft中的序列化是借助于Proto buff来实现的,这个文件夹就定义了需要序列化的几个数据结构,Proto buff(https://github.com/protocolbuffers/protobuf/releases/tag/v3.7.1)是序列化和结构化数据的方法,常用于用于通信协议,数据存储,实现跨平台的数据结构转换。

Raft中的序列化数据结构在raftpb/raft.proto文件中。

syntax = "proto2"; 使用proto2版本进行转换

1、枚举Entry类型有三种: Entry在Raft中是状态机,其类型反映了当前状态机的运行状态,Normal是普通状态,EntryConfChange   EntryConfChangeV2 分别对应配置变化的两种状态

enum EntryType {

    EntryNormal       = 0;

    EntryConfChange   = 1; // corresponds to pb.ConfChange

    EntryConfChangeV2 = 2; // corresponds to pb.ConfChangeV2

}

2、Entry有4个数据,leader的任期Term,任期中的第几个消息Index,Entry的类型Type,消息的数据Data

message Entry {

    optional uint64     Term  = 2 [(gogoproto.nullable) = false]; // must be 64-bit aligned for atomic operations

    optional uint64     Index = 3 [(gogoproto.nullable) = false]; // must be 64-bit aligned for atomic operations

    optional EntryType  Type  = 1 [(gogoproto.nullable) = false];

    optional bytes      Data  = 4;

}

3、SnapshotMetadata 是snaoshot的元信息(包括集群当前的配置状态、日志索引、该条索引日志对应的任期号)有三个参数,conf_state是配置状态信息(配置状态信息里面包括了voters和learners,在paxos中,Learners可以看做是所有被确认消息的执行器,一旦有Client的消息请求被Acceptors确认之后,Learners会做相应的处理(如:执行消息内容,发送回复给Client)。Learner可以有多个。Acceptor (Voters)可以看做是消息请求的存储器。一般来说Acceptors是由一定数量的服务组成的,当消息被发送给Acceptor, 只有大部分Acceptor确认接收此消息,该消息才会被存储,否则该消息将被丢弃。),index是日志索引,term是任期号

message SnapshotMetadata {

    optional ConfState conf_state = 1 [(gogoproto.nullable) = false];

    optional uint64    index      = 2 [(gogoproto.nullable) = false];

    optional uint64    term       = 3 [(gogoproto.nullable) = false];

}

message ConfState {

    // The voters in the incoming config. (If the configuration is not joint,

    // then the outgoing config is empty).

    repeated uint64 voters = 1;

    // The learners in the incoming config.

    repeated uint64 learners          = 2;

    // The voters in the outgoing config.

    repeated uint64 voters_outgoing   = 3;

    // The nodes that will become learners when the outgoing config is removed.

    // These nodes are necessarily currently in nodes_joint (or they would have

    // been added to the incoming config right away).

    repeated uint64 learners_next     = 4;

    // If set, the config is joint and Raft will automatically transition into

    // the final config (i.e. remove the outgoing config) when this is safe.

    optional bool   auto_leave        = 5 [(gogoproto.nullable) = false];

}

4、Snapshot 包括两个参数,一个是上面的SnapshotMetadata 存放了这次snapshot的配置信息,data是snap的数据

message Snapshot {

    optional bytes            data     = 1;

    optional SnapshotMetadata metadata = 2 [(gogoproto.nullable) = false];

}

5、MessageType,Raft集群中节点之间的通讯的各种消息类型,借用我们之前看的Raft文章中的图:

Hup表示Follower timers out,开始新的选举

Beat表示

Prop表示是外部客户端访问集群的请求消息

App/AppResp表示当选成为Leader后发给大家的消息和回复的消息

Vote/VoteResp表示投票和回应的消息

Snap是Leader向follower发送的快照

Heartbeat/HeartbeatResp是Leader发送给Follower的心跳信息和反馈


enum MessageType {
        MsgHup            MessageType = 0  //当Follower节点的选举计时器超时,会发送MsgHup消息
	MsgBeat           MessageType = 1    //Leader发送心跳,主要作用是探活,Follower接收到MsgBeat会重置选举计时器,防止Follower发起新一轮选举
	MsgProp           MessageType = 2   //客户端发往到集群的写请求是通过MsgProp消息表示的
	MsgApp            MessageType = 3  //当一个节点通过选举成为Leader时,会发送MsgApp消息
	MsgAppResp        MessageType = 4  //MsgApp的响应消息
	MsgVote           MessageType = 5      //当PreCandidate状态节点收到半数以上的投票之后,会发起新一轮的选举,即向集群中的其他节点发送MsgVote消息
	MsgVoteResp       MessageType = 6  //MsgVote选举消息响应的消息
	MsgSnap           MessageType = 7		//Leader向Follower发送快照信息
	MsgHeartbeat      MessageType = 8			//Leader发送的心跳消息
	MsgHeartbeatResp  MessageType = 9    //Follower处理心跳回复返回的消息类型
	MsgUnreachable    MessageType = 10  //Follower消息不可达
	MsgSnapStatus     MessageType = 11   //如果Leader发送MsgSnap消息时出现异常,则会调用Raft接口发送MsgUnreachable和MsgSnapStatus消息
	MsgCheckQuorum    MessageType = 12     //Leader检测是否保持半数以上的连接
	MsgTransferLeader MessageType = 13		//Leader节点转移时使用,本地消息
	MsgTimeoutNow     MessageType = 14    //Leader节点转移超时,会发该类型的消息,使Follower的选举计时器立即过期,并发起新一轮的选举
	MsgReadIndex      MessageType = 15   //客户端发往集群的只读消息使用MsgReadIndex消息(只读的两种模式:ReadOnlySafe和ReadOnlyLeaseBased)
	MsgReadIndexResp  MessageType = 16   //MsgReadIndex消息的响应消息
	MsgPreVote        MessageType = 17   //PreCandidate状态下的节点发送的消息
	MsgPreVoteResp    MessageType = 18  //预选节点收到的响应消息
}

6、Message涵盖了Raft集群中节点之间的通讯的各种消息所需的字段,Message结构如下

Type:当前传递的消息类型,它的取值有很多种,比如用来请求投票的MsgVote、用来处理网络分区的MsgPreVote2、用来发给leader节点,让它在日志中增加数据的MsgProp(ose)、用来复制日志的MsgApp(end)、用来安装snapshot的MsgSnap。不同类型的消息也会用到下面不同的字段。
To, From分别代表了这个消息的接受者和发送者。
Term:这个消息发出时整个集群所处的任期。
LogTerm:消息发出者所保存的日志中最后一条的任期号,一般MsgVote会用到这个字段。
Index:日志索引号。如果当前消息是MsgVote的话,代表这个candidate最后一条日志的索引号,它跟上面的LogTerm一起代表这个candidate所拥有的最新日志信息,这样别人就可以比较自己的日志是不是比candidata的日志要新,从而决定是否投票。
Entries:需要存储的日志。
Commit:已经提交的日志的索引值,用来向别人同步日志的提交信息。
Snapshot:一般跟MsgSnap合用,用来放置具体的Snapshot值。
Reject,RejectHint:代表对方节点拒绝了当前节点的请求(MsgVote/MsgApp/MsgSnap…)


message Message {
	optional MessageType type        = 1  [(gogoproto.nullable) = false];
	optional uint64      to          = 2  [(gogoproto.nullable) = false];
	optional uint64      from        = 3  [(gogoproto.nullable) = false];
	optional uint64      term        = 4  [(gogoproto.nullable) = false];
	optional uint64      logTerm     = 5  [(gogoproto.nullable) = false];
	optional uint64      index       = 6  [(gogoproto.nullable) = false];
	repeated Entry       entries     = 7  [(gogoproto.nullable) = false];
	optional uint64      commit      = 8  [(gogoproto.nullable) = false];
	optional Snapshot    snapshot    = 9  [(gogoproto.nullable) = false];
	optional bool        reject      = 10 [(gogoproto.nullable) = false];
	optional uint64      rejectHint  = 11 [(gogoproto.nullable) = false];
	optional bytes       context     = 12;
}



7、HardState硬状态,与软状态相反,需要写入持久化存储中,包括:节点当前Term、Vote、Commit

message HardState {

    optional uint64 term   = 1 [(gogoproto.nullable) = false];

    optional uint64 vote   = 2 [(gogoproto.nullable) = false];

    optional uint64 commit = 3 [(gogoproto.nullable) = false];

}

8、集群配置变化的类型和消息

enum ConfChangeType {

    ConfChangeAddNode        = 0;   //增加节点

    ConfChangeRemoveNode     = 1;  //移除节点

    ConfChangeUpdateNode     = 2;   //更新节点

    ConfChangeAddLearnerNode = 3;    //增加Learner节点

}

message ConfChange {   //集群配置变化的消息内容

    optional ConfChangeType  type    = 2 [(gogoproto.nullable) = false];   //变化的类型

    optional uint64          node_id = 3 [(gogoproto.nullable) = false, (gogoproto.customname) = "NodeID" ];   //节点的id

    optional bytes           context = 4;               

    // NB: this is used only by etcd to thread through a unique identifier.

    // Ideally it should really use the Context instead. No counterpart to

    // this field exists in ConfChangeV2.

    optional uint64          id      = 1 [(gogoproto.nullable) = false, (gogoproto.customname) = "ID" ];

}

 

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值