BusterZR 2019-06-29
TiDB 是由 PingCAP 开发的分布式关系型数据库,今天我们很高兴地推出 TiDB 2.1 正式版,提供更丰富的功能、更好的性能以及更高的可靠性。
今年 4 月份我们发布了 TiDB 2.0 版本,提升了稳定性、性能以及可运维性,这个版本在接下来的半年中得到了广泛的关注和使用。
迄今为止 TiDB 已经在 数百家用户 的生产环境中稳定运行,涉及互联网、游戏、金融、保险、制造业、银行、证券等多个行业,最大集群包含数百个节点及数百 TB 数据,业务场景包含纯 OLTP、纯 OLAP 以及混合负载。另外,既有使用 TiDB 当做关系数据库的场景,也有只用 TiKV 作为分布式 Key Value 存储的场景。
这几个月,在这些场景中,我们亲历了跨机房容灾需求、亲历了几十万级别的高吞吐业务、亲历了双十一的流量激增、亲历了高并发点查、高并发写入与上百行复杂 SQL 的混合负载、见到过多次的硬件/网络故障、见到过操作系统内核/编译器的 Bug。
简而言之,我们的世界充满了未知,而分布式关系型数据库这样一种应用广泛、功能丰富且非常关键的基础软件,最大的困难就是这些“未知”。在 2.1 版本中,我们引入了不少新的特性来抵御这些未知,适配各种复杂的场景,提升性能和稳定性,帮助我们的用户更好地支撑复杂的业务。
在 2.1 版本中,我们对 TiDB 的 Cost-based Optimizer 做了改进,希望这个优化器能够处理各种复杂的 Query,尽量少的需要人工介入去处理慢 SQL。例如对 Index Join 选择索引、外表的优化,对关联子查询的优化,显著地提升了复杂 SQL 的查询效率。
当然,除了自动的查询优化之外,2.1 也增加了更多的手动干预机制,比如对 Join 算子的 Hint、Update/Delete 语句的 Hint。用户可以在优化器没有指定合适的计划时,手动干预结果或者是用来确保查询计划稳定。
在 2.1 版本中,我们对部分物理算子的执行效率进行了优化,特别是对 Hash Aggregation 和 Projection 这两个算子进行了并行化改造,另外重构了聚合算子的运行框架,支持向量化计算。
得益于这些优化,在 TPC-H 这种 OLAP 的测试集上,2.1 比 2.0 版本有了显著的性能提升,让 2.1 版本更好的面对 HTAP 应用场景。
在 2.1 版本中,我们引入了 Raft PreVote、Raft Learner、Raft Region Merge 三个新特性:
这些新特性的引入,有助于提升存储集群尤其是大规模集群的稳定性和性能。
统计信息的及时性对查询计划的正确性非常重要。在 2.1 版本中,我们提供了基于 Query Feedback 的动态增量更新机制。
在制定查询计划时,会根据现有的统计信息估算出需要处理的数据量;在执行查询计划时,会统计出真实处理的数据量。TiDB 会根据这两个值之间的差距来更新统计信息,包括直方图和 CM-Sketch。在我们的测试中,对于一个完全没有统计信息的表,经过十轮左右的更新,可以达到统计信息基本稳定的状态。这对于维持正确的查询计划非常重要。
除了动态增量更新之外,我们对自动全量 Analyze 也提供了更多支持,可以通过 系统变量 指定做自动 Analyze 的时间段。
TiDB 所有的 DDL 操作都是 Online 进行,不过在 2.0 以及之前的版本中,所有的 DDL 操作都是串行执行,即使 DDL 所操作的表之间没有关联。比如在对 A 表 Add Index 时候,想创建一个 B 表,需要等待 Add Index 操作结束。这在一些场景下对用户使用造成了困扰。
在 2.1 版本中,我们对 DDL 流程进行拆分,将 Add Index 操作和其他的 DDL 操作的处理分开。由于在 TiDB 的 DDL 操作中,只有 Add Index 操作需要去回填数据,耗时较长,其他的 DDL 操作正常情况下都可以在秒级别完成,所以经过这个拆分,可以保证大多数 DDL 操作能够不需要等待,直接执行。
Explain 对于理解查询计划至关重要,2.1 之前的版本,TiDB 追随 MySQL 的 Explain 输出格式来展示查询计划。但是当 SQL 比较复杂时,MySQL 的格式并不利于展示算子之间的层级关系,不利于用户定位问题。
2.1 版本中,我们使用缩进来展示算子之间的层级关系,对每个算子的详细信息也做了优化,希望整个查询计划一目了然,帮助用户尽快定位问题。这篇文档 可以帮助用户了解 TiDB 的查询计划。
用户除了通过 Explain 语句查看查询计划之外,在 2.1 版本中还可以通过 Explain Analyze 语句查看语句的运行时信息,包括每个算子运行时的处理时间以及处理的数据量。这样可以通过实际的运行结果,拿到更加精确的信息。
热点是分布式系统最大的敌人之一,并且用户的业务场景复杂多变,让热点问题捉摸不定,也是最狡猾的敌人。2.1 版本中,我们一方面增强热点检测能力,尽可能详细地统计系统负载,更快的发现热点;另一方面优化热点调度策略,用尽可能小的代价,尽快地打散热点。同时我们也提供了手动分裂 Region 的接口,让用户在特殊场景下将单点瓶颈手动分裂开,再由 PD 进行负载均衡。
2.1 版本对 GC(垃圾回收) 模块进行优化。一方面减少对线上的写入的影响,另一方面加快了空间回收速度。在内部测试场景中,删除一个 1TB 的表,新的 GC 机制能够在 10 秒内回收 99% 左右的空间。
我们针对 OLTP 场景中,点查占多数的特点进行了针对性的优化。当通过 Unique Key 或者 Primary Key 进行数据访问时,在优化器和执行引擎中都做了改进,使得语句的执行效率更高,通过 2.1 和 2.0 版本的 Sysbench 对比 可以看到,点查性能提升 50%。
发布 2.0 的时候,我们同时发布了在 TPC-H Scale 50 的场景中 2.0 和 1.0 的对比结果。其中大多数 Query 都有数量级的提升,部分 Query 在 1.0 中跑不出结果,在 2.0 中可以顺利运行。不过对于 Query17 和 Query18,运行时间依然很长。
我们在相同的场景下,对 2.1 和 2.0 进行了 对比测试。从下图可以看到(纵坐标是 Query 的响应时间,越低越好),之前的两个慢 Query 的运行时间大幅缩短,其他的 Query 也有一定程度的提升。这些提升一方面得益于查询优化器以及执行引擎的改进,另一方面 得益于 TiKV 对连续数据扫描的性能优化。
为了让用户更方便的使用 TiDB,我们提供了三个工具:
上述三个工具可以将 TiDB 和周边的系统打通,既能将数据同步进 TiDB,又可以将数据同步出来。所以无论是迁移、回退还是做数据热备,都有完整的解决方案。
我们相信战胜“未知”最好的武器就是社区的力量,基础软件需要坚定地走开源路线。为了让社区更深入的了解 TiDB 的技术细节并且更好地参与到项目中来,我们今年已经完成超过 20 篇源码阅读文章,项目的设计文档(TiDB 和 TiKV)已经在 GitHub 上面公开出来,项目的开发过程也尽量通过 Github Issue/Project 向社区展示。一些 Feature 设计方案的讨论也会通过在线视频会议的方式方便社区参与进来,这里 可以看到会议安排。
从 TiDB 2.0 版发布到现在的半年多时间,TiDB 开源社区新增了 87 位 Contributor,其中 杜川 成为了 TiDB Committer,他已经贡献了 76 次 PR,还有一些活跃的 Contributor 有希望成为下一批 Committer。
在这里我们对社区贡献者表示由衷的感谢,希望更多志同道合的人能加入进来,也希望大家在 TiDB 这个开源社区能够有所收获!