TIDB的优势:分布式,高度兼容MySQL,高可用,支持ACID事务(事务模型:Percolator),丰富的工具链生态
一、TiDB
SQL层,解析SQL,将数据读取请求发给TiKV/TiFlash
功能:
TiDB缓存组成:SQL结果,线程缓存,元数据,统计信息
缓存管理:tidb_mem_quota_query,oom-action
二、PD
集群的大脑。元信息管理模块,负责存储每个 TiKV 节点实时的数据分布情况和集群的整体拓扑结构,分配分布式事务ID,根据 TiKV 节点实时上报的数据分布状态,下发数据调度命令给具体的 TiKV 节点
功能:
TSO
int(64) TSO=physical time + logical time
获取流程:TSO请求者 -> PD Client ->PD leader ->PD Client -> TSO请求者
PD -> PD Client -> TSO请求者
PD每次分配给TiDB3秒内的TSO。如果中途PD leader宕机,则TSO将继续增加,可能出现TSO的不连续现象,但并不影响高可用。
调度:信息收集->生成调度->执行调度
生成调度:Balance (leader,region,hot region)
集群拓扑
缩容
故障恢复
Region merge
label:为每个TiKV实例做的标签,标识其所在位置 zone rack host
三、TiKV
存储数据,分布式提供事务的KV存储引擎
存储数据的基本单位是Region,每个TiKV会负责多个Region,默认SI(Snapshot Isolation)隔离级别
TiKV通过协处理器Corprocessor可以为 TiDB 分担一部分计算:TiDB 会将可以由存储层分担的计算下推
以 Region 为单位,将数据分散在集群中所有的节点上,并且尽量保证每个节点上服务的 Region 数量差不多。
以 Region 为单位做 Raft 的复制和成员管理。
功能:
四、TiFlash
功能:
五、RocksDB LSM-Tree架构引擎,单机持久化KV存储引擎,针对Flash存储进行优化,延迟极小。
每个TiKV中有两个RocksDB,一个raftdb存储Raft日志,一个kvdb存储数据和MVCC信息
写操作过程:写请求->磁盘记录日志(WAL,防止数据丢失)->内存MemTable->immutable MemTable ->刷到磁盘(磁盘中会对Level进行合并,随机写变为顺序写)
写操作为一次磁盘IO,一次内存IO。写操作访问内存MemTable即可(简单理解为写入的操作一直在追加),读操作要访问内存...->磁盘level...
Column Families 列簇,每个CF中可以有一类或多类键值对,数据分片功能, 各自使用各自部分的内存磁盘,共用WAL日志文件。每个RocksDB可以有多个CF,每个TiKV中有4个Column Family,每个CF中的最多有5个MemTable存在,MemTable的大小限制是128MB。
六、Raft协议
重要功能:Leader(主副本)选举,成员变更,日志复制
日志复制:propose 写入数据时发指令给leader后,写入raft log
append leader将日志进行持久化写入到RocksDB
replicate follower收到指令后后写入写入到RocksDB
append
committed 多数节点(超过一半以上)持久化完成后发送指令给leader,只是raft log的持久化
apply 真正的提交,rocksdb raft -> rocksdb kv ,写入的数据可在RocksDB中查询到
至此,一个写入的操作才算commit
Leader选举: follower等待leader election timeout,这个时间后没有响应,此follower将发起选举,term升级,作为candidate,发起投票后成为leader(超过一半的投票)
leader宕机后,follower等待heartbeat time interval ,没有响应后,此follower将发起选举,term升级,作为candidate,发起投票后成为leader(超过一半的投票)
多节点等待leader超时后,同时发起选举,生成随机等待的响应时间,可快速选举出leader
raft-election-timeout-ticks >= raft-heartbeat-ticks
七、Region
将KV的空间分成若干段,Region为其中一段,是一个左闭右开的区间,存储数据的大小不超过96MB
当Region的大小超过144MB(默认)时,将分裂。
八、调度
TiKV->Region->Replica
每个Region有多个副本,这些副本分布在不同的TiKV节点上。Leader负责读写,Follower负责同步Leader同步过来的Raft log
分布式高可用存储系统需满足:
良好的分布式系统需满足:
调度操作:增加、删除副本,将 Leader 角色在一个 Raft Group 的不同副本之间 transfer
信息收集:
调度策略:
九、分布式事务
提交分两阶段:1.prewrite:修改数据和锁信息 2.commit 时间戳从PD获取
悲观锁。只为事务中修改的第一行加锁
TiKV节点中有三个列簇:Default,Lock,Write
write列存储数据长度小于255字节
default列存储数据长度大于255字节
一个事务中修改的如果数据在不同的TiKV节点上,事务中修改的第一行加主锁,后面的行表明主锁所在的TiKV节点。事务执行中途宕机后进行恢复,后面的修改数据的操作查询主锁的状况。
十、数据的写入
TiDB->raftstore pool ->rocksdb raft
->apply pool ->rocksdb kv
十一、数据的读取 ReadIndex
Lease Read 接收到读请求后,leader会给follower发心跳确认自己是否是leader,在election timeout时间限制内都不会发生重新选举
ReadIndex:读取的点在想读的数据之后,这样保证一定可以读到想读的数据(此处暂不提MVCC机制)
Follower Read:等待follower上的提交点提交后,和ReadIndex读取方式类似。从follower读取可能更快,这取决于apply的速度。
十二、SQL语句执行流程
DML:读请求->Protocol Layer ->PD(TSO)->Parse->Compile->Execute->TiKV返回结果
写请求->Protocol Layer ->PD(TSO)->Parse->Compile->Execute->TiKV->memBuffer->Transaction(1.两阶段提交 2.从PD获得TSO)->TiKV
编译部分:对于点查可直接找出数据后修改。非点查会进行一系列解析优化
DDL:online DDL,TiKV存在三种队列 job queue,add index queue ,history queue
每个TiDB节点都可以接收DDL请求,接收后将其存放在job queue中,然后由具有owner角色的worker进行执行(owner会定期进行选举),执行后放入到history queue。