文章目录
特点
- 开源分布式关系型数据库
- 支持在线事务处理,在线分析处理
- 适合高可用、强一致要求较高、数据规模较大等各种应用场景
五大核心特征
- 一键水平扩容或缩容
- 金融级高可用
- 实时HTAP
- 云原生的分布式数据库
- 兼容MySQL5.7协议和MySQL生态
四大核心应用场景
- 对数据一致性及高可靠、系统高可用、可扩展性、容灾要求较高的金融行业熟悉的场景
- 对存储容量、可扩展性、并发要求较高的海量数据及高并发的OLTP场景
- Real-time HTAP场景
- 数据汇聚、二次加工处理的场景
基本功能
数据类型
- 数值类型:BIT、BOOL/BOOLEAN、SMALLINT、MEDIUMINT、INT/INTEGER、BIGINT、FLOAT、DOUBLE、DECIMAL
- 日期和时间类型:DATE、TIME、DATETIME、TIMESTAMP、YEAR
- 字符串类型:CHAR、VARCAHR、TEXT、MEDIUMTEXT、LONGTEXT、BINARY、VARBINARY、BLOB、TINYBLOB、MODIUMBLOB、LONGBLOB、ENUM、SET
- JSON类型
运算符
- 算数运算符
- 位运算符
- 比较运算符
- 逻辑运算符
- 日期和时间运算符
- … …(与mysql基本一致)
架构
TiDB Server
- SQL层,对外暴露MySQL协议的连接endpoint,接受客户端的连接,执行SQL解析和优化,最终生成分布式执行计划。TiDB本身并不存储数据,只是解析SQL,将实际的数据读取请求转发给底层的存储节点TiKV(或者TiFlash).
PD Server
- 整个集群的元信息关系单元,负责存储每个TiKV节点实时的数据分布情况和集群的整体拓扑结构,提供TiDB Dashboard管控界面。并为分布式事务分配事务ID。PD不仅存储元信息,同时还会根据TiKV 节点实时上报的数据分布状态,下发数据调度命令给具体的TiKV节点,可以说是整个集群的“大脑”。此外,PD本身也是由至少3个节点构成,拥有高可用的能力。建议部署奇数个PD节点。
存储节点
- TiKV Server:负责存储数据,从外部看TiKV就是一个分布式的提供事务的Key-value存储引擎。存储数据的基本单位是Region,每个Region负责存储一个key Range(从StartKey到EndKey的左闭右开区间)的数据,每个TiKV节点会负责多个Region.
- TiFlash:TiFlash是一类特殊的存储节点,与TiKV不同的是,在TiFlash内部,数据是以列的形式进行存储,主要的功能是为分析型的场景加速。
存储
键值对
- key-value模型
- 这是一个巨大Map,存储的是key-value Paris键值对
- 这个Map中的key-value Paris按照key的二进制顺序有序来seek到某一个具体的key位置,然后通过不断调用Next方法以递增的顺序来获取比这个key大的key-value
- 本地存储RocksDB
- TiKV不是直接向磁盘写数据,而是把数据存储在RocksDB,具体的数据落地由RocksDB负责。RocksDB是一个由Facebook开源的非常优秀的单机kv存储引擎,可以满足Tikv对单机引擎的各种要求。
- Raft协议
- 保证单机失效情况下,数据不丢失,不出错
- Raft提供的重要功能:
- Leader(主副本)选举
- 成员变更(eg:添加副本、删除副本、转移Leader等)
- 日志复制
- TiKV利用Raft协议来做数据复制,每个数据变更都会落地为一条Raft日志,通过Raft的日志复制功能,将数据安全可靠的同步到复制组的每一个节点中。实际的写入中,根据Raft协议,只需要同步到多数节点,就可认为安全写入
- Region协议
- 一般对于一个kv系统,将数据分散在多台机器上,有两种比较典型的方案:
- Hash:按照Key做Hash,根据Hash值选择对应的存储节点。
- Range:按照Key分Range,某一段连续的Key都保存在一个存储节点上。
- TiKV 选择了第二种方式,将整个Key-Value空间分成很多段,每一段是一系列连续的Key,将每一段叫做一个Region
- 并且会尽量保持每个Region中保存的数据不超过一定的大小,目前在 TiKV 中默认是 96MB。
- 每一个Region都可以用[StartKey,EndKey)这样一个左闭右开区间来描述。
- 数据按照 Key 切分成很多 Region,每个Region的数据只会保存在一个节点上面(暂不考虑多副本)。同时为了保证上层客户端能够访问所需要的数据,系统中也会有一个组件(PD)记录Region在节点上面的分布情况,也就是通过任意一个 Key 就能查询到这个Key 在哪个 Region 中,以及这个Region目前在哪个节点上(即 Key 的位置路由信息)。
- TiKV 是以 Region为单位做数据的复制,也就是一个Region的数据会保存多个副本,TiKV将每一个副本叫做一个Replica。Replica之间是通过Raft来保持数据的一致,一个Region的多个Replica会保存在不同的节点上,构成一个Raft Group。其中一个Replica会作为这个Group的Leader,其他Replica作为Follower。默认情况下,所有的读和写都是通过Leader进行,读操作在Leader上即可完成,而写操作再由 Leader 复制给 Follower。
- 一般对于一个kv系统,将数据分散在多台机器上,有两种比较典型的方案:
- MVCC多本版并发控制
- TiKV 的 MVCC 实现是通过在Key后面添加版本号来实现
- Key1 -> Value
- Key1_Version3 -> Value
- 对于同一个Key的多个版本,版本号较大的会被放在前面,版本号小的会被放在后面,这样当用户通过一个 Key + Version来获取Value的时候,可以通过Key和Version构造出MVCC的Key,也就是Key_Version。然后可以直接通过RocksDB的SeekPrefix(Key_Version)API,定位到第一个大于等于这个 Key_Version 的位置。
- TiKV 的 MVCC 实现是通过在Key后面添加版本号来实现
- 分布式ACID事务
TiDB数据库的计算
表数据与key-value的映射关系
- TableID用来保证同一个表的数据放在一起,方便查找,整个集群唯一。
- RowID为每个表中每一行数据的行ID,表内唯一。如果某个表中有整数型的主键,TiDB会使用主键值作为这一行数据的行ID。
- 编码规则:
- Key: tablePrefix{TableID}_recordPrefixSep{RowID}
- Value: [col1, col2, col3, col4]
索引数据与key-value的映射关系
- TiDB支持主键和二级索引。
- 索引ID:indexID
元信息管理
- TiDB 中每个Database和Table都有元信息,也就是其定义以及各项属性。这些信息也需要持久化,TiDB将这些信息也存储在了 TiKV 中。
- 每个 Database/Table 都被分配了一个唯一的 ID,这个 ID 作为唯一标识,并且在编码为Key-Value时,这个ID都会编码到 Key 中,再加上m_前缀。这样可以构造出一个Key,Value 中存储的是序列化后的元信息。
- TiDB 还用一个专门的(Key,Value)键值对存储当前所有表结构信息的最新版本号。这个键值对是全局的,每次DDL操作的状态改变时其版本号都会加1。TiDB把这个键值对持久化存储在 PD Server中,其Key是“/tidb/ddl/global_schema_version” ,Value是类型为int64的版本号值有一个后台线程在不断地检查PDServer中存储的表结构信息的版本号是否发生变化,并且保证在一定时间内一定能够获取版本的变化。
sql层
- TiDB Server将SQL翻译成key-value操作,转发给共用的分布式key-value存储层TiKV,然后组装其返回结果。该层不存储数据,无状态,节点之间完全对等。
sql运算
分布式sql运算
- 计算应该尽量靠近存储节点,避免大量RPC调用
sql层架构
- 用户SQL
- Load Balancer
- TiDB Server(解析MySQL Protocol Packet)获取请求全部内容
- 对SQL进行语法解析,语义分析
- 指定和优化查询计划
- 执行查询计划并获取和处理数据
- 数据全部存储在TiKV集群中
- TiDB Server返回查询结果