一、数据存储的要求

1、数据库应该怎么存储数据

数据库最根本的功能就是把数据存下来,保存数据的方法有很多

(1)直接使用数组

最简单的就是在内存中直接构建一个数据结构(比如可以使用一个数组),保存用户

发来的数据。这个方案非常简单,性能也是非常好的。但是存在很大的缺点:数据完全在

内存中,一旦停机或者服务重启,数据就永远丢失

(2)数据丢失如何解决

为了解决数据丢失的问题,可以将数据存储在非易失性的介质中,比如硬盘这时我们

可以在磁盘上创建一个文件,收到一条数据就在文件中Append一行,这样持久化存储

数据

(3)磁盘出现故障如何解决

为了防止磁盘出现坏道,我们可以做RAID,单机冗余存储

(4)单机出现故障如何解决

但是如果机器挂了呢?我们还可以将存储改为网络存储,或者是通过硬件或者软件

进行存储复制,数据安全了

2、数据存储的其他需求

  • 跨数据中心的容灾

  • 写入速度如何提高

  • 数据保存下来后是否方便读取

  • 保存的数据如何修改,如何支持并发的修改

  • 原子性地修改多条记录

二、TiKV的设计思想

1、TiKV的数据存储模型

TiDB是Key-Value的模型,并且提供有序遍历的方法,TiKV的主要特点就是:

  • TiKV可以看做一个巨大的Map

  • 这个Map中的Key-Value是按照Key的二进制顺序有序排列的

我们可以找到某一个Key的位置,然后不断的调用Next方法以递增的顺序获取比这

个Key大的Key-Value。这里的存储模型和SQL中的Table无关,TiKV是一个巨大的分

布式Map

2、TiKV数据的持久化机制

TiKV没有选择直接向磁盘上写数据,而是将数据保存在RocksDB中,具体的数据落

地由RocksDB完成。RocksDB是一个非常优秀的开源的单机存储引擎,通过使用它TiKV

已经实现了高效可靠的本地存储

但是如何保证单机失效的情况下,数据不会丢失和出错,所以我们需要将数据复制

到多台机器上,这样一台机器挂了,在其他机器上还有副本,,所以还需要一个可靠,

高效且能处理副本失效的情况

3.TiKV的一致性设计思想-优化的Raft算法

Raft的主要就是一个一致性的协议,主要的功能是Leader选举、成员变更、日志复制

TiKV利用Raft来做数据复制,每条数据变更都会落地为一条Raft日志,通过Raft的日志复制

功能,将数据安全可靠地同步到Group的多数节点中

JDtF00.png

4、总结TiKV的设计思想

  • 单机的RocksDB,将数据快速地存储到磁盘上

  • 通过Raft协议,将数据复制到多台机器上,防止单机失效数据的写入是通过Raft这一层

的接口写入,而不是直接写入RocksDB通过Raft可以实现一个分布式的KV

三、Region

1、分布式存储的方案

对于一个KV系统,将数据分散在多台机器上一般有两种方案

  • 一种是按照Key做hash,根据hash值选择对应的存储节点

  • 分Range,某一段连续的Key都保存在一个存储节点上,TiKV将每一个Key-Value空间

分成很多段,每一段是一系列连续的Key,我们把每一段成为一个Region每一个Region

会有最大值,目前默认64Mb,每一个Region都可以用StartKey到EndKey这样一个左

开右闭的区间来描述

JDtajA.png

2、TiDB分布式存储方案

TiDB采取了第二种方案将数据划分成Region,水平扩展和复制都是以Region为单位的

(1)数据划分成Region存储

以Region为单位,将数据分散存储在集群的所有节点上,并且尽量保证每个节点上

的服务的Region的数量差不多

数据按照Key切分成很多的Region,每个Region的数据只会保存在一个节点上面,系

统会有一个组件来负责将Region 尽可能的散布在集群中的所有的节点,一方面实现了存储

容量的水平扩展,同时也实现了负载均衡(不会出现某个节点有很多数据但是其他节点机

会没有数据的情况)

同时系统中会有一个字组件记录Region在节点上面的分布情况,即通过Key可以查

到这个Key所处的Region,以及这个Region 目前实在哪个节点上

(2)以Region为单位做Raft的复制和成员的管理

每个Region的数据会保存多个副本,每个副本可称为Replica,Replica之间是通过

Raft来保持数据的一致性。一个Region的多个Replica会保存在不同的节点上,构成一

个Raft Group,其中一个Replica会作为这个Group的Leader,其他的Replica作为作为

Follower。所有的读和写都会通过Leader进行,再由Leader复制给Follower

JDUhkV.png

四、并发控制

TiDB 是基于MVCC的多版本控制机制来解决并发控制的问题的

两个Client同时去修改一个Key的Value,如果没有MVCC,就需要对数据上锁,在分

布式场景下,可能会导致死锁。TiKV的MVCC实现是通过在Key后面添加Version来实现的: JDNGbq.png

有了MVCC之后,TiKV的Key排列是这样的,对于同一个Key的多个版本,我们把

版本号较大的放在前面,版本号较小的放在后面,当用户通过一个Key+Version来获取

Value时,可以将Key和Version构造出MVCC的Key,也就是Key-Version,然后可以直接

Seek(Key-Version),定位到第一个大于等于这个Key-Version的位置即可