[学习笔记] TiDB学习笔记(二)

2021-12-30 18:40:02 浏览数 (1)

本文是《极客时间》-《TiDb极简入门》的学习笔记。传送门:https://time.geekbang.org/opencourse/videointro/100089601

这部分讲解了Tidb的整体概述。


一 我们需要一个什么样的数据库?

数据库设计要考虑什么

1.扩展性 scale-out

颗粒度越小越好,常见的颗粒度:集群/db/表/分表/分区表

写入能力的线性扩展

2.强一致,高可用

强一致: CAP里的一致性(副本一致性)

由于副本节点数和网络延迟成正比,节点数量越多,网络延迟越大。 普遍采用多数派强一致,常见的3副本强制写2节点

数据容灾:RPO(数据恢复点目标)所能容忍的数据容量量

rto(恢复时间目标)所能容忍业务停止服务的最长时间

强一致,高可用目标是实现RPO=0,RTO足够小(目前普遍是若干秒级)

3.实现标准SQL与事务的支持

因为SQL是高度易用性,已经是数据交互类语言的实施标准,所以兼容sql非常重要

同时在很多场景下,尤其是oltp,完整事务是必选项

4.云原生

5混合数据服务HTAP

在海量数据下OLTP OLAP的数据服务融合

行列混合

更彻底的资源隔离

6.兼容主流生态协议

数据技术栈领域里常见的基础因素

1. 数据模型: 关系模型/ 文档模型/KV模型

2. 数据存储与检索结构:B-Tree/LSM-Tree/分形树

3. 数据格式:结构化数据/非结构化数据/半结构化数据

4. 存储引擎:负责数据的存储和持久化:Inno DB Rocks DB

5. 复制协议:保证数据的可用性,Raft/Paxos

6. 分布式事务模型:事务处理时的并发处理方法,以保证事务的可串行化 XA/Percolato

7. 数据架构:多个计算引擎共享同一份数据/多份数据,常见的有 Share-Disk/Share-Nothing/Share-Everything等

8. 优化器算法:根据数据分布/统计信息生成成本最低的执行计划

9. 执行引擎:火山引擎/向量化/大规模并行计算等

10.计算引擎:是否是一个标准SQL的引擎

计算与存储分离的必然性

1. 计算与存储绑定,意味着总有一个资源是浪费的

2. 服务器选型困难

3. 在云计算场景下,弹性的颗粒度是机器,不能做到真正资源的弹性

TiDB高度分层架构

弹性是整个架构设计的核心考量点,计算与存储分离

从逻辑上TiDb主要分为3层

1.TiDB-Server: 支持标准SQL的计算引擎(以Mysql5.7为主,在逐步兼容Mysql8.0), 本身并不存储数据,只进行计算

2.TiKv: 分布式存储引擎

3.Placement Driver(PD): 负责元信息与调度引擎,整个集群的大脑,为了保证高可用性,至少有3个节点,通过raft复制。

PD有以下几个功能:

集群的元信息管理:分片的分布,拓扑结构

分布式事务ID的分配

调度中心

二 如何构建一个分布式存储系统

我们需要一个什么样的存储引擎

1.更细粒度的弹性扩缩容

2.高并发读写

3.数据不丢不错

4.多副本保障一致性及高可用性

5.支持完整的分布式事务

TiDb 的选择

数据结构

选择了KV的数据索引, 简单随处可见,而且是其他更复杂索引基础构建的模块

存储引擎

选择了基于LSM-Tree的RocksDB引擎

支持批量写入

无锁快照读

为什么不用B-Tree:

在传统的OLTP系统中,写入是最昂贵的成本

B-Tree至少要写两次,一次预写(WAL),一次写入树本身,

B-Tree是严格平衡的数据结构,他的设计是对读友好,数据写入触发的B-Tree分裂与平衡成本是非常高的,因此B-Tree相对于写入并不友好

在传统的主从架构里,不管加多少个节点,集群的写入容量完全由主哭的机器配置决定,扩容只能通过分库(集群拆分)来进行

因此选择了LSM-Tree,本质是用空间置换写入延迟,用顺序写入替代随机写入到数据结构

采用顺序写,写到了一定阈值以后,持久化成一个静态文件,随着静态文件越来越大,会被推到下一层进行合并

数据副本

数据冗余决定了系统可用性

强一致数据算法:raft

对比Paxos, Raft的目标是提供更清晰的逻辑分工,使得算法本身能被更好地理解,同时他的安全性更高,能提供一些额外的特性。(from wiki)

如何实现扩展

做分片,预先分片还是自动分片?

传统的分库分表属于预先分片,只解决了表容量问题,没有解决弹性问题

分片算法:哈希,范围,列举

Tikv采取了范围,原因

1. 在“where 字段> value”的场景下,在这个场景下,range分片可以更高效的扫描数据

2. 可以简单实现自动完成分裂和合并

3. 弹性有限,分片需要可以自由调度,range对于自由调度更友好

range分片的问题

1.需要考虑热点问题?

region概念

把Tikv看成是一个巨大的有序的kv map,通过范围的方式,将整个kv空间分成若干段,每一段也是一些列连续的kv,把每一段成为region, 并且尽量保证每个region中保存的数据不超过一定的大小

如何进行分离与扩展

当region超过一定大小,会自动分成两个region, 当由于大量删除请求导致region变小,会自动和相邻的region合并

灵活调度机制

PD来负责将region尽可能的,均匀的,离散的,分布在集群的所有节点上。

1.实现了存储容量的水平扩展,通过增加新的节点会自动将其他节点上的region分片调度过来

2.实现了负载均衡

TiKv整体架构

参考率goole spanner设计的multi raft-group副本机制

多版本控制MVCC

通过在key后面增加版本号实现

分布式事务模型

参考了google的percolator事务模型

去中心化两阶段提交

每个节点单独分配区域存放锁信息(Tikv的锁是基于列簇,CF lock)

通过PD全局授时(TSO)

TIDB默认隔离级别是SI(快照隔离),也支持RC(read commit)

默认乐观锁,在3.0以后也支持悲观锁,可以自由选择,在5.0以后,实现了两阶段异步提交

协作处理器Coprocessor

tikv中读取数据的计算模块

在数据层尽快的进行计算和预处理,例如在本地节点尽快完成filter,group by等

三 如何构建一个分布式sql引擎

如何在kv上实现逻辑表

每个表有一个tableid, 每个索引indexid, 每行有rowid

简单来看,key = rowid indexid

value=所有列按等位偏移的方式进行connect进行连接

在数据查询的时候,我们通过等位偏移对value进行反解析,然后对应schema的元信息进行列信息映射

二级索引:也是一个全局有序的kvmap

简单来说:key= 索引列信息

value= primary-key

然后通过pk在原表查数据,类似于b-tree的回表

sql引擎过程

SQL: sql语法解析/语义解析

抽象语法树:从文本解析成结构化数据

逻辑优化:将各种sql等价改写以及优化

物理优化:基于统计信息与成本进行生产执行计划(重要)

执行引擎:根据优化器定下的执行路径进行数据寻址,数据计算

基于成本优化器

cost model里需要进行合理的匹配计算

分布式sql引擎主要优化策略

最大程度让数据在分布式存储层尽快的完成过滤以及预计算(最大下推策略 push down)

关键算子分布式化

如何构建一个Online DDL

1.tidb没有分表概念,所以整个ddl完成过程是很快的,秒回

2.ddl过程分成public/delete-only/write-only等几个状态,每个状态在多节点之间同步和一致,完成最终的ddl(根据goggle的f1论文)

如何连接到tidb-server

可以使用mysql客户端或者sdk直接连接

从进程的角度看tidb-server

就是一个后台进程,不断监听port,和client通信,按照mysql协议解析收到的网络请求,获取时间戳,通过分片的路由信息找到对应的存储节点去查询数据

从内部角度看tidb-server

mysql协议层

sql核心层:sql的parse分析,逻辑优化,物理优化,统计信息收集,执行层等

其他功能

前台功能

1.管理连接和账号权限管理

2.mysql协议编码解码

3.独立sql执行

4.库表元信息,系统变量管理

后台功能

1.GCC

2.执行DDL

3.统计信息收集

4.sql优化器与执行器

0 人点赞