TiDB学习(一)

TiDB是一个分布式数据库,由TiDB Server、PD Server和TiKV Server组成,支持水平扩展和高可用性。TiDB的核心特性包括水平扩展、故障自恢复和兼容MySQL语法。TiKV作为存储层,采用Key-Value模型,基于RocksDB和Raft协议实现数据复制和故障恢复。TiDB的SQL层与存储层分离,支持分布式事务,提供SQL解析、优化和执行。通过PD进行集群管理和数据调度,保证数据分布和副本均匀。监控方面,TiDB提供了全面的监控指标以确保系统稳定运行。
摘要由CSDN通过智能技术生成

TiDB基本介绍

组件

TiDB 集群有三大组件构成:TiDB Server、PD Server、TiKV Server(图 1)。

 

其中各个组件的功能如下:

  • TiDB Server,可以理解为 SQL Layer,负责接收 SQL 请求,处理 SQL 解析、SQL 优化等相关逻辑,并通过 PD 与底层 TiKV 交互来获取或变更数据;

  • PD Server,可以视作集群的大脑,负责集群各类元信息的存储以及 TiKV 节点间的数据调度和负载均衡,另外还负责集群全局事务 ID 的分配;

  • TiKV Server,集群的存储层,数据最终以 Key-Value 的形式存储于其中,并通过 PD 在各个 KV 节点调度,以保证各节点负载均衡。TiKV Cluster 本身也可作为分布式的 Key-Value 存储独立使用。

TiDB 核心特性

水平扩展计算与存储

TiDB Server 负责处理 SQL 请求,随着业务的增长,可以简单的添加 TiDB Server 节点,提高整体的计算处理能力。TiKV 负责存储数据,随着数据量的增长,

可以部署更多的 TiKV Server 节点,提高集群整体的存储能力。PD 会在 TiKV 节点之间做调度,将部分数据迁移到新加的节点上,这个过程不需要人为的干预。

 故障自恢复的高可用

TiDB / TiKV / PD 三个组件都能容忍部分实例失效,不影响整个集群的可用性。

  • TiDB Server 节点失效,只会影响该节点上的 session,应用连接失败重试后可通过前端负载均衡中间件将请求发送到其他正常的 TiDB Server 节点。
  • PD 节点失效,若非 Raft leader 节点(PD Cluster 通过 Raft 协议保证自身数据一致性)则无影响,否则会重新选取 leader,期间该无法对外提供服务(约 3 秒钟)。
  • TiKV 节点失效,会影响该节点上的所有 region,若 region 非 Raft leader(TiKV Cluster 也通过 Raft 协议保证节点间的数据一致性),则服务不受影响,否则服务会中断,待重新选举 leader 后恢复。如果 PD 确认了失效的 TiKV 节点已经不能恢复,则会自动将该节点的数据调度至其他正常的 TiKV 节点。

TiDB 其他特性及原理

  • 高度兼容 MySQL 语法和协议;

  • 分布式事务;

  • 跨数据中心数据强一致性保证;

  • 海量数据高并发实时写入与实时查询。 

TiDB演化背景

背景

在大约两年前,我有一次做MySQL分库分表和中间件的经历,那时在中间件里做 sharding,把 16 个节点的 MySQL 扩到 32 节点,差不多要提前一个月做演练,再用一个礼拜来上线。我就在想,能不能有一个数据库可以让我们不再想分库分表这些东西?当时我们也刚刚做完 Codis,觉得分布式是个比较合适的解决方案。另外我一直在关注学术圈关于分布式数据库的最新进展,有看到谷歌在 2013 年发的 Spanner 和 F1 的论文,所以决定干脆就重新开始写一个数据库,从根本上解决 MySQL 扩展性的问题。

 

初始版本

  • 0.2:TiDB 只有一个 SQL 解析器,没有存储引擎
  • 0.5:SQL 层跟存储层基本上做了完全分离,HBASE作为分布式存储引擎
  • 1.0版本:存储引擎改为基于RocksDB的存储

 

TiKV

Key-Value

作为保存数据的系统,首先要决定的是数据的存储模型,也就是数据以什么样的形式保存下来。TiKV 的选择是 Key-Value 模型,并且提供有序遍历方法。简单来讲,可以将 TiKV 看做一个巨大的 Map,其中 Key 和 Value 都是原始的 Byte 数组,在这个 Map 中,Key 按照 Byte 数组总的原始二进制比特位比较顺序排列。

大家这里需要对 TiKV 记住两点:

1. 这是一个巨大的 Map,也就是存储的是 Key-Value pair;

2. 这个 Map 中的 Key-Value pair 按照 Key 的二进制顺序有序,也就是我们可以 Seek 到某一个 Key 的位置,然后不断的调用 Next 方法以递增的顺序获取比这个 Key 大的 Key-Value。

讲了这么多,有人可能会问了,这里讲的存储模型和 SQL 中表是什么关系?在这里有一件重要的事情要说四遍:

这里的存储模型和 SQL 中的 Table 无关!

这里的存储模型和 SQL 中的 Table 无关!

这里的存储模型和 SQL 中的 Table 无关!

这里的存储模型和 SQL 中的 Table 无关!

现在让我们忘记 SQL 中的任何概念,专注于讨论如何实现 TiKV 这样一个高性能高可靠性的巨大的(分布式的) Map。

RocksDB

任何持久化的存储引擎,数据终归要保存在磁盘上,TiKV 也不例外。但是 TiKV 没有选择直接向磁盘上写数据,而是把数据保存在 RocksDB 中,具体的数据落地由 RocksDB 负责。这个选择的原因是开发一个单机存储引擎工作量很大,特别是要做一个高性能的单机引擎,需要做各种细致的优化,而 RocksDB 是一个非常优秀的开源的单机存储引擎,可以满足我们对单机引擎的各种要求,而且还有 Facebook 的团队在做持续的优化,这样我们只投入很少的精力,就能享受到一个十分强大且在不断进步的单机引擎。这里可以简单的认为 RocksDB 是一个单机的 Key-Value Map。

Raft

接下来我们面临一件更难的事情:如何保证单机失效的情况下,数据不丢失,不出错?

简单来说,我们需要想办法把数据复制到多台机器上,这样一台机器挂了,我们还有其他的机器上的副本;

这里采用 Raft 协议。Raft 是一个一致性算法,它和 Paxos 等价,但是更加易于理解。感兴趣的可以参考:[https://raft.github.io/raft.pdf]

Raft 是一个一致性协议,提供几个重要的功能:

1. Leader 选举

2. 成员变更

3. 日志复制

TiKV 利用 Raft 来做数据复制,每个数据变更都会落地为一条 Raft 日志,通过 Raft 的日志复制功能,将数据安全可靠地同步到 Group 的多数节点中。

 

到这里我们总结一下,通过单机的 RocksDB,我们可以将数据快速地存储在磁盘上;通过 Raft,我们可以将数据复制到多台机器上,以防单机失效。数据的写入是通过 Raft 这一层的接口写入,而不是直接写 RocksDB。通过实现 Raft,我们拥有了一个分布式的 KV,现在再也不用担心某台机器挂掉了。

Region

讲到这里,我们可以提到一个非常重要的概念:Region。这个概念是理解后续一系列机制的基础。

前面提到,我们将 TiKV 看做一个巨大的有序的 KV Map,那么为了实现存储的水平扩展,我们需要将数据分散在多台机器上。这里提到的数据分散在多台机器上和 Raft 的数据复制不是一个概念,在这一节我们先忘记 Raft,假设所有的数据都只有一个副本,这样更容易理解。

对于一个 KV 系统,将数据分散在多台机器上有两种比较典型的方案:

  • 一种是按照 Key 做 Hash,根据 Hash 值选择对应的存储节点;
  • 另一种是分 Range,某一段连续的 Key 都保存在一个存储节点上。
    TiKV 选择了第二种方式,将整个 Key-Value 空间分成很多段,每一段是一系列连续的 Key,我们将每一段叫做一个 Region,并且会尽量保持每个 Region 中保存的数据不超过一定的大小(这个大小可以配置,目前默认是 64MB)。每一个 Region 都可以用 StartKey 到 EndKey 这样一个左闭右开区间来描述。

注意,这里的 Region 还是和 SQL 中的表没什么关系! 请各位继续忘记 SQL,只谈 KV。

将数据划分成 Region 后,将会做两件重要的事情:

  • 以 Region 为单位,将数据分散在集群中所有的节点上,并且尽量保证每个节点上服务的 Region 数量差不多

  • 以 Region 为单位做 Raft 的复制和成员管理

这两点非常重要,我们一点一点来说。

先看第一点,数据按照 Key 切分成很多 Region,每个 Region 的数据只会保存在一个节点上面。我们的系统会有一个组件来负责将 Region 尽可能均匀的散布在集群中所有的节点上,这样一方面实现了存储容量的水平扩展(增加新的节点后,会自动将其他节点上的 Region 调度过来),另一方面也实现了负载均衡(不会出现某个节点有很多数据,其他节点上没什么数据的情况)。同时为了保证上层客户端能够访问所需要的数据,我们的系统中也会有一个组件记录 Region 在节点上面的分布情况,也就是通过任意一个 Key 就能查询到这个 Key 在哪个 Region 中,以及这个 Region 目前在哪个节点上。

对于第二点,TiKV 是以 Region 为单位做数据的复制,也就是一个 Region 的数据会保存多个副本,我们将每一个副本叫做一个 Replica。Repica 之间是通过 Raft 来保持数据的一致,一个 Region 的多个 Replica 会保存在不同的节点上,构成一个 Raft Group。其中一个 Replica 会作为这个 Group 的 Leader,其他的 Replica 作为 Follower。所有的读和写都是通过 Leader 进行,再由 Leader 复制给 Follower。

大家理解了 Region 之后,应该可以理解下面这张图:

我们以 Regio

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值