The relationship between RaftStore, Region, and Peer is as follows.

Peer encapsulates RawNode and PeerStorage (as with MemoryStorage in 2A, it is an implementation of raft.storage).

type peer struct {
    RaftGroup   *raft.RawNode
    peerStorage *PeerStorage
}
Copy the code

2B starts with raftstore.start (), which starts some Raftworkers and does two main things.

  1. Get and process Ready from Raft.
  2. Get and process Msg from raftCh.

Get and process Ready

Unlike MemoryStorage, which persists in memory, PeerStorage uses Badger for persistence.

type PeerStorage struct {
    Engines *engine_util.Engines
}
Copy the code

There are two badger instances in Engines, each storing some information. Different types of information are distinguished by special prefixes and suffixes.

  1. raftDB
    • raft log
      • key: region_id + log_idx
      • value: entry
    • raft state
      • key: region_id
      • value: RaftLocalState
  2. kvDB
    • data
    • apply state
      • key: region_id
      • value: RaftApplyState
    • region state
      • key: region_id
      • value: RegionLocalState

What we need to implement are two functions.

  1. PeerStorage.SaveReadyState(Ready) error
    • Use Append to save ready. Entries.
    • Update PeerStorage. RaftLocalState. HardState and save to raftDB.
  2. PeerStorage.Append([]pb.Entry, *engine_util.WriteBatch) error
    • Will save Entires to raftDB and delete now in Storage at the Append all the Entries after the last Entry, at the same time update PeerStorage. RaftLocalState and save to raftDB.
    • In addition, AS I mentioned in the article 2A, stabled is subject to change, so it is possible to have the previous Append Entry after the latest Append.

SaveReadyState

Append

Get and process the Msg

What we need to implement are two functions.

  1. peerMsgHandler.HandleRaftReady()
  2. peerMsgHandler.proposeRaftCommand()

PeerMsgHandler exposes two functions.

  1. HandleMsgs

    • HandleMsgs handles messages such as the MsgTypeTick driver Raft, which calls rawNode.tick (); For example, when MsgTypeRaftCmd appends a log to Raft, call proposeRaftCommand().
  2. HandleRaftReady

    • After HandleMsgs, the Raft state may change. HandleRaftReady detects this state and acts accordingly, and finally calls rawNode.advance ().

proposeRaftCommand

HandleRaftReady

conclusion

In fact, 2B should be put together with 2AC, which has a large correlation. There are many concepts about Storage, Peer, Node, Store and so on, and the nested level is also very deep. But in fact, raftworker.run () is a good starting point.

2B does not involve Snapshot, but the test program takes Snap from Response and Region from Snap, so you still need to consider CmdType_Snap in apply.