Thoughts behind TiDB - Part I

“让我们看看未来的数据库到底应该是什么样子吧。”

其实想写这个蛮久了,趁着整个 TiDB 项目即将 release beta 的时机,作为 NewSQL 领域走在全球前沿的开源项目,我试着整理一下关于 TiDB 背后的一些理念和关键设计背后的想法,对于一起现在或者未来一起工作的 PingCAP 的小伙伴,也可以了解到目前为止这个项目是一步步走过来的,算是留个记录。另外对于分布式系统和数据库感兴趣的朋友如果能从我的文章中得到一点启发,也算是没白写。还有我们也在招聘,我的邮箱是 huang at pingcap.com

TiDB 和 TiKV 项目均在 Github 上开源,欢迎 Star & Fork :)

https://github.com/pingcap/tidb
https://github.com/pingcap/tikv

缘起

在 2015 年初,我和 goroutine 做完 Codis 后,陷入了一个比较迷茫的状态,我们开始了一个新的项目,希望能在缓存之下解决关系型数据库的水平扩展问题,也就是的 mp 这个项目,那时在豌豆荚内部,使用的是基于阿里开源的 cobar 的 MySQL sharding 方案,不管是从水平扩展能力和易用性来说,都是达到了一些瓶颈,希望寻求更好的方案,当时希望参考 vitess,但在不损失 MySQL 兼容的基础之上,加入一些特性进来,总之就是一个不那么重的 vitess,但是本质上仍然是一个 MySQL 中间件。当时做的特沮丧,业务层仍然没有透明的事务支持,仍然没有办法做很优雅的扩容,MySQL 的同步机制仍然原始,我们还没法动,总而言之,后来我们的判断是:中间件的方案实在是太丑了。在一个几乎所有东西都有水平扩展方案的今天,我们发现关系型数据库上,仍然没有任何比较优雅的方案,唯一能找到的我们认可方案是 Google 的 Spanner,正好 goroutine 之前一直在 follow 着 CockroachDB 这个项目,但是对于 Cockroach 的一些理念有着自己不同的看法,于是我们就萌生了自己去做更加 "正统" 的 Spanner 和 F1 开源实现的想法,出于一些机缘巧合,拿到了一笔相当不错的天使投资(嗯,我们的早期天使很有眼光 :D,不过因为这是技术 blog,就不提融资和创业的事情了),拉上了 cuiqiu,三个码农从豌豆荚出来自己开搞。

初探

我们最早还是很天真的,觉得既然要兼容 MySQL,那最简单的方法就是给 MySQL 写个存储引擎呗,这还不简单,然后我们花了几天时间,写了一个 MySQL 的存储引擎接入 CockroachDB,当然结果可想而知,效果并不理想,原因是多方面的,主要的原因还是 MySQL 这样的单机数据库的 SQL 优化器其实并不是为底层是分布式存储设计的,其实后来看看,SQL 优化器这边需要很多存储引擎的很多信息,比如数据的分布,表的大小等等,而且对于分布式数据库来说,尽可能的将计算推到存储节点带来的性能提升会更大,也就是 MPP,复用 MySQL 几乎完全没可能。

接下来,大概 2015 年的 5 月下旬,我们开始了 TiDB 项目,目标就是先完成 Google F1 的实现,也就是分布式 SQL 引擎这一层。

不同于 CockroachDB,我们先做的是 SQL Layer,其实背后的理由也很简单:SQL 是我们希望用户最终的用户接口,用户并不需要关心底层的存储实现,只需要无心智负担的当 MySQL 使用就好,这层是最接近用户的一层。从某方面来讲,用户的使用方式决定了你下层的存储引擎的实现,如果你早期并没有对用户的使用模型进行限制和设定,直接从底层开始写,很容易导致缺乏方向感,很可能做很多无用功,如果有对 Cockroach 熟悉的同学可能还记得,在去年年中时,Cockroach 抛弃掉了 Structure API,后来也抛弃了他们从 vitess 中提取出来的 SQL Parser,就是典型的例子。

同时早期 SQL Layer 的目标非常明确,就是 MySQL 的语法及协议级别的兼容,但是麻雀虽小五脏俱全,需要有一个可用而且可控的 Parser 和 SQL 优化器,看上去很难,但是这个工作其实相对于去 hack MySQL 是简单很多的。而且我们选择了 Go 语言来开发,开发效率会比 C/C++ 高很多。

早期我们坚决选择 MySQL 兼容带来的另一个好处就是测试可以做得比较充分,MySQL 社区积累了那么多年的集成用例,ORM 框架的测试,各种语言客户端的测试,SQL logic tests 数不胜数。做数据库最困难并不在于写出来,而是在于去证明它是正确的,如果你凭空发明一套协议和语法,光是写测试用例对于初创团队就是不可能的事情。到现在,我们每次提交,我们的 CI 会跑六百万以上个测试用例,当然这比起 Oracle 的级别还有很长的距离,但是我们已经在路上。另外独立的 SQL Layer 暗示着我们并不需要一个真正的分布式存储就可以开始进行测试,同时很多工作可以并行起来,事实上我们甚至在去年 11 月时尝试接入了 HBase 作为第一个分布式的底层存储,这个事情后续再说。选择从 SQL 入手从现在看来,这是一个非常正确的决定。

未完待续,明天再写。

你可能感兴趣的:(Thoughts behind TiDB - Part I)