# Raft 日志复制

__*Raft 日志复制*__
__*raft log*__
__*raft 日志*__
__*entry*__

![left](./student-guide/diagram/RaftLogReplication01_aa_001_20220511.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。