一、和MySql相比,具有OLAP能力。省去了不少数据仓库搭建成本和学习成本。这在业务层是很是受欢迎的。能够在其余分库分表业务中,经过 syncer 同步,进行合并,而后进行统计分析
二、数据量增加极快的OLTP场景,这些数据库的数据在一年内轻松达到数百亿量级。TiDB 的全部特性都很是契合这种海量高并发的 OLTP 场景。git
三、弥补单机容量上限,支持水平扩展,无限扩容存储github
四、传统 Sharding 方案查询维度单一,TIDB支持多维度查询算法
五、支持在线 DDL 这个特性特别适合这些业务,有须要业务更改不会阻塞业务,业务快速迭代比较须要sql
六、在MySQL上要分库分表,可是又须要分布式事务的业务。支持分布式事务数据库
七、支持读写QPS须要弹性扩容、缩容的业务安全
SQL层和调度层为Go,KV层Rust,引擎C++服务器
兼容80% MySQL协议网络
全局单点授时服务架构
不管是一个地方的几个节点,仍是跨多个数据中心的多个节点,TiDB 均支持 ACID 分布式事务。并发
TiDB 事务模型灵感源自 Google Percolator 模型,主体是一个两阶段提交协议,并进行了一些实用的优化。该模型依赖于一个时间戳分配器,为每一个事务分配单调递增的时间戳,这样就检测到事务冲突。在 TiDB 集群中,PD 承担时间戳分配器的角色。
TiKV 的事务采用乐观锁,事务的执行过程当中,不会检测写写冲突,只有在提交过程当中,才会作冲突检测,冲突的双方中比较早完成提交的会写入成功,另外一方会尝试从新执行整个事务。当业务的写入冲突不严重的状况下,这种模型性能会很好,好比随机更新表中某一行的数据,而且表很大。可是若是业务的写入冲突严重,性能就会不好,举一个极端的例子,就是计数器,多个客户端同时修改少许行,致使冲突严重的,形成大量的无效重试
乐观锁
强一致的raft
7.一、TiKV 没有选择直接向磁盘上写数据,而是把数据保存在 RocksDB 中,具体的数据落地由 RocksDB 负责。这个选择的缘由是开发一个单机存储引擎工做量很大,特别是要作一个高性能的单机引擎,须要作各类细致的优化,而 RocksDB 是一个很是优秀的开源的单机存储引擎,能够知足咱们对单机引擎的各类要求,并且还有 Facebook 的团队在作持续的优化
7.二、Raft协议保证存储的高可用
Raft 是一个一致性协议,提供几个重要的功能:
TiKV 利用 Raft 来作数据复制,每一个数据变动都会落地为一条 Raft 日志,经过 Raft 的日志复制功能,将数据安全可靠地同步到 Group 的多数节点中。
经过单机的 RocksDB,咱们能够将数据快速地存储在磁盘上;经过 Raft,咱们能够将数据复制到多台机器上,以防单机失效。数据的写入是经过 Raft 这一层的接口写入,而不是直接写 RocksDB。经过实现 Raft,咱们拥有了一个分布式的 KV,如今不再用担忧某台机器挂掉了
7.三、存储数据的基本单位:Region
7.四、多版本控制(MVCC)
设想这样的场景,两个 Client 同时去修改一个 Key 的 Value,若是没有 MVCC,就须要对数据上锁,在分布式场景下,可能会带来性能以及死锁问题。 TiKV 的 MVCC 实现是经过在 Key 后面添加 Version 来实现
7.五、行存仍是列存?
TiDB 面向的首要目标是 OLTP 业务,这类业务须要支持快速地读取、保存、修改、删除一行数据,因此采用行存是比较合适的
8.一、一个 Table 内部全部的 Row 都有相同的前缀,一个 Index 的数据也都有相同的前缀。这样具体相同的前缀的数据,在 TiKV 的 Key 空间内,是排列在一块儿。同时只要咱们当心地设计后缀部分的编码方案,保证编码前和编码后的比较关系不变,那么就能够将 Row 或者 Index 数据有序地保存在 TiKV 中
8.二、数据元数据处理(表结构)
通常数据库在进行 DDL 操做时都会锁表,致使线上对此表的 DML 操做所有进入等待状态(有些数据支持读操做,可是也以消耗大量内存为代价),即不少涉及此表的业务都处于阻塞状态,表越大,影响时间越久
TiDB 使用 Google F1 的 Online Schema 变动算法,有一个后台线程在不断的检查 TiKV 上面存储的 Schema 版本是否发生变化,而且保证在必定时间内必定可以获取版本的变化(若是确实发生了变化)。这部分的具体实现参见 TiDB 的异步 schema 变动实现一文。
8.三、分布式sql计算
咱们将 Filter 也下推到存储节点进行计算,这样只须要返回有效的行,避免无心义的网络传输。最后,咱们能够将聚合函数、GroupBy 也下推到存储节点,进行预聚合,每一个节点只须要返回一个 Count 值便可,再由 tidb-server 将 Count 值 Sum 起来
提升计算速度的优化:
整个系统也是在动态变化,Region 分裂、节点加入、节点失效、访问热点变化等状况会不断发生,整个调度系统也须要在动态中不断向最优状态前进,若是没有一个掌握全局信息,能够对全局进行调度,而且能够配置的组件,就很难知足这些需求。所以咱们须要一个中心节点,来对系统的总体情况进行把控和调整,因此有了 PD 这个模块
一、信息收集
TiKV 节点(Store)与 PD 之间存在心跳包,一方面 PD 经过心跳包检测每一个 Store 是否存活,以及是否有新加入的 Store;还包括如下信息:
每一个 Raft Group 的 Leader 和 PD 之间存在心跳包,用于汇报这个 Region 的状态,主要包括下面几点信息:
PD 还能够经过管理接口接受额外的信息,用来作更准确的决策。
二、调度策略
一个 Raft Group 中的多个 Replica 不在同一个位置
副本在 Store 之间的分布均匀分配。每一个副本中存储的数据容量上限是固定的,因此咱们维持每一个节点上面,副本数量的均衡,会使得整体的负载更均衡。
Leader 数量在 Store 之间均匀分配
访问热点数量在 Store 之间均匀分配
各个 Store 的存储空间占用大体相等
控制调度速度,避免影响在线服务
参考资料:
TIDB对Raft 的优化 https://zhuanlan.zhihu.com/p/25735592