TiKV 的 Service 层的代码位于 src/server
文件夹下,提供 RPC 服务、将 store id 解析成地址、TiKV 之间的相互通信等。 Service 层封装了 TiKV 在网络上提供服务和 Raft Group 成员之间相互通信的逻辑。
TiKV 包含多个 GRPC Service。
KVService
定义了 TiKV 的 kv_get
,kv_scan
,kv_prewrite
,kv_commit
等事务操作的 API,用于执行 TiDB 下推下来的复杂查询和计算的 coprocessor
API,以及 raw_get
,raw_put
等 Raw KV API。batch_commands
接口则是用于将上述的接口 batch 起来,以优化高吞吐量的场景。
每个 TiKV 实例都由一个唯一的 store id 进行标识。Resolver 的功能是将 store id 解析成 TiKV 的地址和端口,用于建立网络通信。
TiKV 是一个 Multi Raft 的结构,Region 副本之间需要相互通信,RaftClient
的作用便是管理 TiKV 之间的连接,并用于向其它 TiKV 节点发送 Raft 消息。RaftClient
可以和另一个节点建立多个连接,并把不同 Region 的请求均摊到这些连接上。
RaftStoreRouter
负责将收到的 Raft 消息转发给 raftstore 中对应的 Region,而 Transport
负责将 Raft 消息发送到指定的 store。
TiKV 会将数据存储到 RocksDB,RocksDB 是一个 key-value 存储系统,所以对于 TiKV 来说,任何的数据都最终会转换成一个或者多个 key-value 存放到 RocksDB 里面。
每个 TiKV 包含两个 RocksDB 实例,一个用于存储 Raft Log,称为 Raft RocksDB,而另一个则是存放用户实际的数据,称为 KV RocksDB。
一个 TiKV 会有多个 Regions,我们在 Raft RocksDB 里面会使用 Region 的 ID 作为 key 的前缀,然后再带上 Raft Log ID 来唯一标识一条 Raft Log。
TiKV 会将自己所有的 Region 信息汇报给 PD,这样 PD 就有了整个集群的 Region 信息,就有了一张 Region 的路由表.
当 Client 需要操作某一个 key 的数据的时候,它首先会向 PD 问一下这个 key 属于哪一个 Region,Client 会将相关的 Region 信息缓存到本地,加速后续的操作,但有可能 Region 的 Raft Leader 变更,或者 Region 出现了分裂,合并,Client 会知道缓存失效,然后重新去 PD 获取最新的信息。