世界级的开源项目:TiDB 如何从新定义下一代关系型数据库

著名的开源分布式缓存服务 Codis 的做者,PingCAP 联合创始人& CTO ,资深 infrastructure 工程师的黄东旭,擅长分布式存储系统的设计与实现,开源狂热分子的技术大神级别人物。即便在互联网如此繁荣的今天,在数据库这片边界模糊且不肯定地带,他还在努力寻找肯定性的实践方向。git

在数据库的平行世界里,黄东旭以不一样的方式在追随着本身的心里。他认为,一般传统的关系型数据库没法知足海量数据处理和分析时,新一轮的窗口期也随之需求开启,可是各种劣势架构、内存架构、 NoSQL 等方案都不能知足本身理想的解决方案,这些都不够美,不多可以把分布式事务与弹性扩展作到完美。github

绝对的理性与感性,在黄东旭的身上看似矛盾,直到 2012 年末,他看到 Google 发布的两篇论文,如同棱镜般,折射出他本身心里微烁的光彩。这两篇论文描述了 Google 内部使用的一个海量关系型数据库 F1/Spanner ,解决了关系型数据库、弹性扩展以及全球分布的问题,并在生产中大规模使用。“若是这个能实现,对数据存储领域来讲将是颠覆性的”,黄东旭为完美方案的出现而兴奋, PingCAP 的 TiDB 在此基础上诞生了。算法

固然,每向前进一步,都须要付出巨大的努力。在启动 TiDB 项目以前,黄东旭先完成了一个开源分布式的 Redis 集群方案 Codis ,这个项目完成之后让他们以为虽然缓存的水平扩展问题有了解决方案,可是底层的关系型数据库(主要是 MySQL 为主)并无一个优雅的扩展方案。业界除了在业务层分库分表,或者使用中间件等折衷方案外,并无其余太多的办法,有些业务可能能迁移到 NoSQL 之上,例如 HBase 、 C* 等,跟不少的业务无法平滑迁移,几乎须要重写所有逻辑。若是采用分库分表和中间件的方案,扩展以及高可用的方案会带来大量额外的运维成本,好比没法使用跨 shard 的 join、子查询、跨行事务等。数据库

可是做为一个基础软件工程师的黄东旭他们不但愿将这些复杂度转嫁给业务层,因此就开始从新审视整个数据库,但愿从根本上解决 MySQL 的扩展问题,而不是再造一个中间件。编程

“若是创造一个全新的东西,使它有一天可以成为生产力,那种感受真好!”缓存

在 2012 、 2013 年期间,黄东旭他们就开始研究了Google 发表的一系列关于新一代分布式数据库 Spanner 和 F1 的论文以及相关的学术界的进展,直到 2015 年,他们以为基本全部的技术问题和架构都已经思考得差很少了,因而决定出来全职去从新开始完整的实现一个新的数据库,也就是今天的主角——下一代开源 NewSQL 数据库 TiDB 。安全

固然了,创造并不意味着开始,它须要面临的是无限的投入和无限的博弈来适应互联网的竞争和审视,真正作到让开发者和企业受益,才是真正的开始。性能优化

TiDB在总体架构基本是参考 Google Spanner 和 F1 的设计,上分两层为 TiDB 和 TiKV 。 TiDB 对应的是 Google F1, 是一层无状态的 SQL Layer ,兼容绝大多数 MySQL 语法,对外暴露 MySQL 网络协议,负责解析用户的 SQL 语句,生成分布式的 Query Plan,翻译成底层 Key Value 操做发送给 TiKV , TiKV 是真正的存储数据的地方,对应的是 Google Spanner ,是一个分布式 Key Value 数据库,支持弹性水平扩展,自动的灾难恢复和故障转移(高可用),以及 ACID 跨行事务。值得一提的是 TiKV 并不像 HBase 或者 BigTable 那样依赖底层的分布式文件系统,在性能和灵活性上能更好,这个对于在线业务来讲是很是重要。网络

▲ TiDB 总体架构架构

这群理想很丰沛,这不被骨感现实所惑的人。在 TiDB 研发语言的选择过程当中,放弃了 Java 而采用 Go 。

TiDB整个项目分为两层,TiDB 做为 SQL 层,采用 Go 语言开发, TiKV 做为下边的分布式存储引擎,采用 Rust 语言开发。在架构上确实相似 FoundationDB,也是基于两层的结构。 FoundationDB 的 SQL Layer 采用 Java ,底层是 C++ ,不过在去年,被 Apple 收购了。

在选择编程语言并无融入太多的我的喜爱偏向, SQL 层选择 Go 相对 Java 来讲:

第一是 他们团队的背景使用 Go 的开发效率更高,并且性能尚可,尤为对于高并发程序而言,可使用 goroutine / channel 等工具用更少的代码写出正确的程序;

第二是 在标准库中不少包对网络程序开发很是友好,这个对于一个分布式系统来讲很是重要;

第三是 在存储引擎底层对于性能要求很高,Go 毕竟是一个带有 GC 和 Runtime 的语言,在 TiKV 层能够选择的方案并很少,过去基本只有 C 或 C++,不过近两年随着 Rust 语言的成熟,又在通过长时间的思考和大量实验,最终他们团队选择了 Rust。

Rust 这门静态语言的定位是取代 C++,最大的特色是经过不少语法的限制来避免开发者写出内存泄露和 data race 的程序,将不少问题解决在编译期,使得运行时不须要花费额外的代价进行 GC 之类的事情,保证高性能。因此,写出安全的程序,这正是 C++ 程序的很大的一个痛点。

虽然在 C++ 11 中有了不少的改进,可是因为历史包袱过重或者第三方包库开发者的水平良莠不齐。可是重要的缘由不由于别的,正是他们的背后并非一个 C++ 背景很深的团队,因此最后放弃了 C++ 11 而选择了 Rust 。

Rust 不只有安全和高性能的特色,同时语法更加现代,开发效率更高,另外拥有很是完善的包管理机制(Cargo),使得在能写出很是高性能且安全的程序同时,开发效率比起 Go并无降低太多,对于目前来讲是一个很是正确的选择。做为 Rust 社区内全球最大的开源项目之一,也获得了 Rust 语言官方团队的很大支持,黄东旭表示,包括一些他们须要的第三方库,Rust team 都会放在很高优先级上去开发或者在社区里推动。另外 Rust 早已发布 1.0,语法也早已稳定,是一个很是有前途的系统编程语言。

轮番在Google中刷出了存在感后,还一直在没有尽头的草原上奔跑,黄东旭认为只有聚焦,专一,才能摆脱掉使人迷惑的干扰。在不断的探索后,终于寻找到了实现事务模型的方式。

TiDB 的事务模型经过参考了 Google 的 Percolator。该论文发表于 2010 年,是描述 Google 在 BigTable 上的构建 ACID 跨行事务框架用于保证索引更新的一致性。算法的核心思想是两阶段提交,可是传统的分布式两阶段提交的问题是单点的事务管理器无法扩展,会成为整个系统的瓶颈,Percolator 使用了一个两级锁的机制实现了去中心化的事务管理器,使得整个系统的可扩展性大大提高。

▲ Goolge Percolator内部实现

TiDB 将这个模型应用在底层的存储引擎中,并作了不少工程上的优化,黄东旭举例说,经过 batch 和 pipeline 等手段大大提高了授时服务的吞吐,使用 Raft + RockDB 来替代原文的 BigTable 性能更好,另外采用乐观事务机制追求更高的吞吐,不过是从算法层面,是 Percolator 实现。

TiDB 对比 NOSQL

TiDB 对于这些 NoSQL 来讲,最大的特色是编程接口是 SQL,SQL对于开发者而言是更加灵活的操做数据库的方式,且对 MySQL 有着极高的兼容性—原业务的 MySQL切换到 TiDB 几乎一行代码都不用修改就能够完成。TiDB 在支持 SQL 的同时有没有丧失 HBase 这样的系统的弹性扩展能力,业务层不须要再去关心数据库的容量,不用去考虑分库分表,也不用像过去那样投入很大的运维力量,扩容只需简单加机器就好,存储节点故障对业务透明,并且数据库自己具备自我修复的能力,保证数据不会丢失。

对于 MongoDB 也是同样,更重要的是不须要改变用户已有的习惯和程序,并且为了定义将来的云上的数据库形态,TiDB 设计的目标是单集群须要能够 Scale 到 1000 以上物理节点的规模,支持 P 级别容量,万亿以上的行的结构化数据存储,在这个前提约束下的设计和技术选型和 MongoDB 很不同,在大数据量的状况下 TiDB 的表现更稳定,扩展更加平滑。

TiDB 的 SQL 优化器是黄东旭他们从头开始实现的一个面向分布式存储设计的查询优化器,使用了不少学术界很新的查询优化技术和分布式计算框架的思想,保证 MySQL 兼容性的前提下比 MySQL 在复杂查询下表现要好得多。

传统数据库的痛点解决

任何企业,若是使用传统的单机关系型数据库,在数据量持续增加下,或者对业务的可用性有严格要求的状况下,可能都会面临单点故障和单点容量限制的问题,这个问题最近几年在互联网行业尤为突出,目前来讲除了上面提到的分库分表和中间件也并无其余的方案解决,几乎苦不堪言。

TiDB 基于更先进的 Raft 算法来实现了存储层的水平扩展基础上加上了分布式事务,构建了完整的 SQL 查询层,在保证不丧失 ACID 事务的前提下,支持 JOIN ,子查询等复杂查询,另外对外暴露 MySQL 接口,让用户几乎在无侵入性的前提下,解决大量结构化数据的存储问题。考虑到传统行业和互联网行业的代差大概在 3 年左右,另外这个时间在不断的缩短,最近随着 TiDB 趋于稳定,愈来愈多的互联网在使用 TiDB ,相信将来会成为扩展数据库的一个新的主流选择。

TiDB 的应用场景

应用场景是典型的 OLTP 场景,范围很大,覆盖到任何企业。在关系型数据库上遇到扩展性问题、同时须要强一致事务、须要实现多数据中心强一致和高可用,都是 TiDB 的典型用户。TiDB 对 MySQL 的支持很完善,基于目前使用着 MySQL 的用户或企业,但愿寻求更优雅的水平扩展方案,都是很是不错的选择。

其实目前在统计大多数线上生产环境中使用的用户基本都是互联网场景,从 MySQL 过来。TiDB 目前暂时不支持存储过程和视图,因此前提条件是已有业务中没有这类操做。

在项目开始第一天就肯定了 TiDB 最大兼容 MySQL ,黄东旭坦言, MySQL 是一个单机的数据库,并且查询优化器是针对单机场景设计,基于这架构上去作一个分布式数据库的难度很大。

而此时,他们决定选择一条更完全的道路,就是重写整个 SQL Parser 和查询优化引擎。虽然看上去几乎是不可能完成的事情,可是实际作下来他们以为在一个更良好设计和复杂度控制下,反而是一条更轻松的路。而选择彻底的 MySQL 兼容这个事情带来的好处不只限于对用户的友好度,更重要的是能从 MySQL 社区吸收大量的测试。这对于一个数据库产品来讲,作出来并不难,如何证实你是对的,这才是更重要的!黄东旭他们不断的从 MySQL 社区收集了千万级的测试用例来保证每一个模块的正确性,和对 MySQL 行为的一致性。

TiDB 项目开源的程度

TiDB 项目是100% 开源,致力于作一个具备国际水准的顶级开源项目,从 Github repo 自己其实很难看出来这是一个背后是国人主导的开源项目,全部的提交记录,全部的协做,Roadmap ,Issue tracking ,中英文文档,以及代码审核都是开源的。

而项目已经迭代到 Beta 4 版本,从线上用户的反馈,主要的功能已经基本完善稳定。黄东旭表示,接下来重要的工做会是持续的性能优化和继续提高稳定性,还有在更大容量,更恶劣严苛的集群环境下持续测试。固然周边工具,部署教程,更多的设计文档也是在持续的丰富中。

TiDB 的将来

从更长远的角度,一切东西都会运行在云端,数据库也不例外。在海量数据,大规模集群的前提下,关系型数据库的设计和理论还有不少东西须要探索,这种集群规模之下,一切依赖人工的运维都将会失效,由于人是无法 scale ,数据库须要具备自我修复和自我扩展的能力,也只有这样,才能更好的利用集群的计算资源,这也为何 TiDB 团队对本身的定位是要作 Cloud-Native 的数据库,他们在为将来作不少基础性的研究和准备,包含对 Kubernetes 和分布式数据库的结合上也作了不少探索性的工做。

黄东旭但愿 TiDB 定义下一代关系型数据库,将来开发者可以真正专一本身的业务,不用在关心数据库有多大,并发可能会有多高,何时须要扩容一下,选哪一个 sharding key 好等这些问题都应该被隐藏在一个很简单的 SQL interface 之下。

TiDB 有了很是不错的开头,他们作到了,在下一代关系型数据库里面,每一个人都能感觉到这种技术所带来生产力的美好!

开源项目地址:https://github.com/pingcap/tidb

PS:黄东旭将在11月26号出席WOT2016大数据技术峰会,届时在NoSQL实践技术专场分享《NewSQL in action: Patterns and Tools》内容,敬请关注。

WOT2016大数据技术峰会官网:http://wot.51cto.com/

相关文章
相关标签/搜索