随着企业采用云原生架构,对话自然会转向我们如何使数据库实现水平扩展。答案很可能是仔细研究 TiDB。
TiDB 是一款在 Apache 2.0 许可证下发布的开源 NewSQL 数据库。因为它使用 MySQL 协议,所以您现有的应用程序可以使用任何 MySQL 连接器连接到它,并且大多数 SQL 功能保持不变(joins, subqueries, transactions 等)。
然而,深入了解其内部,你会发现一些不同之处。如果您的架构基于带有只读副本的 MySQL,您会看到 TiDB 的工作方式略有不同。在这篇文章中,我将介绍我发现的 TiDB 和 MySQL 之间最重要的五个关键区别。
1. TiDB 原生分布式查询执行和存储
对于 MySQL,通常通过复制进行横向扩展。通常,您会有一个 MySQL 主服务器和多个从服务器,每个服务器都有数据的完整副本。使用应用程序逻辑或像 ProxySQL 这样的技术,查询被路由到适当的服务器(在安全的情况下,将查询从主服务器卸载到从服务器)。
横向扩展复制对于读密集型工作负载非常有效,因为查询执行可以在复制从服务器之间进行分配。但是,对于写密集型工作负载,它会成为瓶颈,因为每个副本都必须拥有数据的完整副本。另一种看待这个问题的方式是,MySQL 复制扩展了 SQL 处理,但它没有扩展存储。(顺便说一句,这对于传统复制以及较新的解决方案(如 Galera Cluster 和 Group Replication)都是如此。)
TiDB 的工作方式略有不同
-
查询执行由 TiDB 服务器层处理。通过添加新的 TiDB 服务器可以扩展 SQL 处理,这使用 Kubernetes ReplicaSets 非常容易实现。这是因为 TiDB 服务器是 无状态的;其 TiKV 存储层负责所有数据持久性。
-
表的数据会自动分片成小块并分布在 TiKV 服务器之间。每个数据区域(TiKV 中分片的名称)的三个副本都保存在 TiKV 集群中,但没有 TiKV 服务器需要数据的完整副本。用 MySQL 术语来说:每个 TiKV 服务器既是主服务器又是从服务器,因为对于某些数据区域,它将包含主副本,而对于其他数据区域,它将是辅助副本。
-
TiDB 支持跨数据区域的查询,或者用 MySQL 术语来说,跨分片查询。有关不同区域位置的元数据由 Placement Driver 维护,Placement Driver 是任何 TiDB 集群的管理服务器组件。所有操作都完全符合 ACID,并且跨两个区域修改数据的操作使用 两阶段提交。
对于学习 TiDB 的 MySQL 用户来说,一个更简单的解释是 TiDB 服务器就像一个智能代理,将 SQL 转换为批量键值请求并发送到 TiKV。TiKV 服务器使用基于范围的分区存储您的表。这些范围会自动平衡,以使每个分区保持在 96MB(默认,但可配置),并且每个范围可以存储在不同的 TiKV 服务器上。Placement Driver 服务器跟踪哪些范围位于何处,并在范围变得太大或太热时自动重新平衡范围。
这种设计具有横向扩展复制的几个优点
-
它可以独立扩展 SQL 处理层和数据存储层。对于许多工作负载,您会先遇到一个瓶颈,然后再遇到另一个。
-
它可以通过添加节点(对于 SQL 和数据存储)进行增量扩展。
-
它更好地利用了硬件。要将 MySQL 横向扩展到一个主服务器和四个副本,您将拥有五个数据副本。TiDB 将仅使用三个副本,并通过 Placement Driver 自动重新平衡热点。
2. TiDB 的存储引擎是 RocksDB
自 2010 年以来,MySQL 的默认存储引擎一直是 InnoDB。在内部,InnoDB 使用 B+树 数据结构,这与传统商业数据库使用的类似。
相比之下,TiDB 使用 RocksDB 作为 TiKV 的存储引擎。RocksDB 对于大型数据集具有优势,因为它可以更有效地压缩数据,并且当索引无法再容纳在内存中时,插入性能不会下降。
请注意,MySQL 和 TiDB 都支持允许提供新存储引擎的 API。例如,Percona Server 和 MariaDB 都支持 RocksDB 作为一种选择。
3. TiDB 在 Prometheus/Grafana 中收集指标
跟踪关键指标是维护数据库健康的重要组成部分。MySQL 将这些快速变化的指标集中在 Performance Schema 中。Performance Schema 是一组内存表,可以通过常规 SQL 查询进行查询。
对于 TiDB,没有选择将指标保留在服务器内部,而是战略性地选择将信息发送到一流的服务。Prometheus+Grafana 是当今运维团队中常见的技术堆栈,包含的图表使您可以轻松创建自己的图表或配置警报阈值。

4. TiDB 处理 DDL 明显更好
如果我们暂时忽略并非 MySQL 中的所有数据定义语言 (DDL) 更改都是在线的这一事实,那么在运行分布式 MySQL 系统时,更大的挑战是在所有节点上同时外部化模式更改。想象一下,如果您有 10 个分片并添加一列,但每个分片完成修改所需的时间不同。即使没有分片,这种挑战仍然存在,因为副本将在主服务器之后处理 DDL。
TiDB 使用 Google F1 论文介绍的协议实现了在线 DDL。简而言之,DDL 更改被分解为更小的转换阶段,以便它们可以防止数据损坏情况,并且系统容忍单个节点一次最多落后一个 DDL 版本。
5. TiDB 专为 HTAP 工作负载设计
MySQL 团队传统上一直专注于优化在线事务处理 (OLTP) 查询的性能。也就是说,MySQL 团队花费更多时间使更简单的查询执行得更好,而不是使所有或复杂的查询执行得更好。这种方法没有错,因为许多应用程序只使用简单的查询。
TiDB 旨在在混合事务/分析处理 (HTAP) 查询中表现良好。对于那些希望对其数据进行实时分析的人来说,这是一个主要的卖点,因为它消除了在 MySQL 数据库和分析数据库之间进行批量加载的需要。
结论
这些是我基于在 MySQL 领域 15 年以及接触 TiDB 的经验得出的五个主要观察结果。虽然其中许多都指的是内部差异,但我建议查看有关 MySQL 兼容性的 TiDB 文档。它描述了可能影响您的应用程序的任何差异的一些细微之处。
1 条评论