第一步、写请求 => Raft 日志
Raft 日志条目的数据结构信息:
type Entry struct {
Term uint64 `protobuf:”varint,2,opt,name=Term” json:”Term”`
Index uint64 `protobuf:”varint,3,opt,name=Index” json:”Index”`
Type EntryType `protobuf:”varint,1,opt,name=Type,enum=Raftpb.EntryType” json:”Type”`
Data []byte `protobuf:”bytes,4,opt,name=Data” json:”Data,omitempty”`
}
它由以下字段组成: 1)Term 是 Leader 任期号,随着 Leader 选举增加; 2)Index 是日志条目的索引,单调递增增加; 3)Type 是日志类型,比如是普通的命令日志(EntryNormal)还是集群配置变更日志(EntryConfChange); 3)Data 保存 put 提案内容;
第二步、Raft 日志 => WAL
它首先先将 Raft 日志条目内容(含任期号、索引、提案内容)序列化后保存到 WAL 记录的 Data 字段,然后计算 Data 的 CRC 值,设置 Type 为 Entry Type,以上信息就组成了一个完整的 WAL 记录。
最后,计算 WAL 记录的长度,顺序先写入 WAL 长度(Len Field),然后写入记录内容,调用 fsync 持久化到磁盘,完成将日志条目保存到持久化存储中。[……]