# `Raft`日志复制

![`smart`](RaftLogReplication01_aa_001_20220511.png)

----------------------------------------------------------------------------
以下，我们描述日志复制：

当客户端（例如TiDB服务器）需要写入一些数据时，它会将操作发送到Leader角色的Region，在TiKV中我们称之为`Propose`。

领导将操作编码成一个条目，并将其写入自己的Raft日志，我们称之为`Append`。

我们可以简单地理解Raft Log的格式：TiKV会有多个Region，我们会用Region的ID作为key的前缀，然后再加上Raft Log ID来唯一标识一个Raft Log。
- 假设有两个区域，分别具有ID 4 和 5，那么Raft Log的格式如下：

```
4_1, log { PUT key = 1, name = tom }
4_2, log { PUT key = 2, name = andy }
4_3, log { PUT key = 1, name = jack }
...
4_N, log { DEL key = 3 }
5_1, log { PUT key = 100, name = tim }
5_2, log { PUT key = 100, name = jim }
5_3, log { PUT key = 200, name = tony }
...
5_N, log { PUT key = 100, name = mark }
```

领导也将通过Raft算法将条目复制给其他追随者，我们称之为`Replicate`。

收到条目后，跟随者也会执行一次 `Append` 操作，并将成功的结果通知领导者（`Append` 指的是将条目写入自己的 Raft 日志，而不是应用条目）。

当领导者发现这个条目已经被大多数节点`Append`ed时，它认为这个条目已经被提交，然后它可以解码条目中的操作，执行并将它们应用到数据持久性存储引擎，我们称之为Apply。