# Raft 日志复制

![center](./student-guide/diagram/03-Raft–Log-replication-01-01.png)
-------------------------------------------------------------
下面，我们描述日志复制：

当客户端（例如 TiDB Server ）需要写入某个数据的时候，会将操作发送给 Leader 角色的 Region，这个在 TiKV 里面我们叫做 propose，Leader 会将操作编码成一个 entry，写入到自己的 Raft Log 里面，这个过程我们叫做 Append。

对于 raft log，我们可以这样简单理解它的格式，一个 TiKV 会有多个 Regions，我们在 raft log 中会使用 Region 的 ID 作为 key 的前缀，然后再带上 Raft Log ID 来唯一标识一条 Raft Log。譬如，假设现在有两个 Region，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 }
```

Leader 也会通过 Raft 算法将 entry 复制到其他的 Follower 上面，这个我们叫做 Replicate。Follower 收到这个 entry 之后也会同样进行 Append 操作，并且会告知 Leader Append 成功（注意：Append 指的是将 entry 写入自己的 Raft Log 存储中，并不是应用这个 entry）。

当 Leader 发现这个 entry 已经被大多数节点 Append，就认为这个 entry 已经是 Committed 的了，然后就可以将 entry 里面的操作解码出来，执行并且应用到数据持久化存储引擎（ State Machine ）中，这个我们叫做 Apply。