TiDB存储学习

TiDB的诞生主要是为了解决数据的问题,数据的问题一般分存储、计算、调度几大块,接下来围绕这几方面来做下笔记。 我们会想,数据存储一般都有哪些问题呢,这就要围绕分布式数据一致性、灾备、数据读写效率这几个点来了 1. 能否支持跨数据中心的容灾 2. 写入速度是否够快 3. 数据保存下来后,是否方便读取 4. 保存后的数据如何修改 5. 并发修改如何支持 6. 如何原子的修改多条数据记录 为了解决存储问题,衍生TiKV。TiKV如其名,整个数据的存储模型就是一个大的Map,其中 Key 和 Value 都是原始的 Byte 数组,在这个 Map 中,Key 按照 Byte 数组总的原始二进制比特位比较顺序排列。

1 如何存储?

任何持久话的存储引擎,数据终归要保存在磁盘上,TiKV是否也直接向磁盘写数据呢?答案是否定的,TiKV的数据是保存在RocksDB中的,具体的磁盘落地也是由RocksDB来完成,RocksDB是一个由facebook维护的非常优秀的单机存储引擎,为什么选择RocksDB而不是直接搞落磁盘这套呢?原因也不言而喻,开发一套完善的单机存储引擎是一项不小的工作,能有RocksDB这样优秀的服务为何不用。

2 如何保证数据不丢失

保证数据不丢失,首先需要把数据复制到多台机器上,那么问题来了,如何保证多台机器数据一致,涉及到一致性算法Raft。 Raft是一个一致性协议,提供几个重要功能: 1. Leader选举 2. 成员变更 3. 日志复制 TiKV 利用 Raft 来做数据复制,每个数据变更都会落地为一条 Raft 日志,通过 Raft 的日志复制功能,将数据安全可靠地同步到 Group 的多数节点中。

3 存储水平扩展

Region是实现存储水平扩展的重要概念,对于一个 KV 系统,将数据分散在多台机器上有两种比较典型的方案,一种是按照key做hash分布存储,另一种分range,一段连续的 Key 都保存在一个存储节点上。目前TiKV采取的是第二种。 将数据划分成 Region 后,将会做两件重要的事情: 1. 以 Region 为单位将数据分散在集群中所有的节点上,并且尽量保证每个节点上服务的 Region 数量差不多 2. 以 Region 为单位做 Raft 的复制和成员管理 以 Region 为单位做数据的分散和复制,就有了一个分布式的具备一定容灾能力的Key-Value系统,不用担心数据存不下,也不用担心数据都是或者不一致问题。

4 MVCC

MVCC(Multi-Version Concurrency Control)多版本并发控制。

5 事务

TiKV 的事务采用乐观锁,事务的执行过程中,不会检测写冲突,只有在提交过程中,才会做冲突检测,冲突的双方中比较早完成提交的会写入成功,另一方会尝试重新执行整个事务。 当业务的写入冲突不严重的情况下,这种模型性能会很好,比如随机更新表中某一行的数据,并且表很大。 如果业务的写入冲突严重,性能就会很差,举一个极端的例子,就是计数器,多个客户端同时修改少量行,导致冲突严重的,造成大量的无效重试。