一、最初的三个基本信念
本次分享题目是《TiDB 的架构演进哲学》,既然讲哲学那肯定有故事和教训,否则哲学从哪儿来呢?但从另外的角度来说,一般大家来讲哲学就先得有信念。有一个内容特别扯的美剧叫做《美国众神》,里面核心的一条思路是“你相信什么你就是什么”。其实人类这么多年来,基本上也是朝这条线路在走的,人类对于未知的东西很难做一个很精确的推导,这时信念就变得非常重要了。
图 1 最初的基本信念
实际上,我们开始做 TiDB 这个产品的时候,第一个信念就是相信云是未来。当年 K8s 还没火,我们就坚定的拥抱了 K8s。第二是不依赖特定硬件、特定的云厂商,也就是说 TiDB 的设计方向是希望可以 Run 在所有环境上面,包括公有云私有云等等。第三是能支持多种硬件,大家都知道我们支持 X86、AMD64、ARM 等等,可能大家不清楚的是 MIPS,MIPS 典型代表是龙芯,除此之外,TiDB 未来还可以在 GPU 上跑(TiFlash 的后续工作会支持 GPU)。
二、早期用户故事
2.1 Make it work
有一句话大概是“眼睛里面写满了故事,脸上没有一点沧桑”,其实现实是残酷的,岁月一定会给你沧桑的。我们早期的时候,也有相对比较难的时候,这时候就有一些故事关于我们怎么去经历、怎么渡过的。
首先大家做产品之前肯定先做用户调研,这是通用的流程,我们当初也做过这个事,跟用户聊。我们通常会说:“我们要做一个分布式数据库,自动弹性伸缩,能解决分库分表的问题,你会用吗?”用户说“那肯定啊,现在的分库分表太痛苦了。”这是最初我们获取需求最普通的方式,也是我们最容易掉入陷阱的方式,就好像“我有一百万,你要不要?肯定要。”“我有一瓶水,喝了之后就健康无比,延年益寿你要不要?肯定要。”很容易就得到类似的结论。
所以这个一句话结论的代价是我们进行了长达两年的开发。在这两年的时间里,我们确定了很多的技术方向,比如最初 TiDB 就决定是分层的。很显然一个复杂的系统如果没有分层,基本上没有办法很好的控制规模和复杂度。TiDB 分两层,一层是 SQL 层,一层是 key-value 层,那么到底先从哪一个层开始写呢?其实从哪层开始都可以,但是总要有一个先后,如何选择?
这里就涉及到 TiDB 的第一条哲学。我们做一个产品的时候会不断面临选择,那每次选择的时候核心指导思想是什么?核心思想是能一直指导我们持续往前去迭代,所以我们第一条哲学就是:永远站在离用户更近的地方去考虑问题。
为什么我们会定义这样一条哲学?因为离用户越近越能更快的得到用户的反馈,更快的验证你的想法是不是可行的。显然 SQL 层离用户更近,所以我们选择从 SQL 层写起。其实一直到现在,绝大多数用户用 TiDB 的时候根本感受不到 KV 层的存在,用户写的都是 SQL,至于底层存储引擎换成了别的,或者底层的 RocksDB 做了很多优化和改进,这些变化对于用户关注的接口来说是不可见的。
选择从 SQL 层开始写之后,接下来面临的问题就是怎么做测试,怎么去更好的做验证,怎么让整个架构,先能够完整跑起来。
在软件开发领域有一条非常经典的哲学:「Make it work, make it right, make it fast」。我想大家每一个学软件开发的人,或者每一个学计算机的人可能都听过这样一句话。所以当时我们就做另外一个决定,先在已有的 KV 上面构建出一个原形,用最短的时间让整个系统能够先能 work。
我们在 2015 年的 9 月份开源了第一个版本,当时是没有存储层的,需要接在 HBase 上。当这个系统能跑起来之后,我们的第一想法是赶紧找到当初调研时说要用的那些用户,看看他们是什么想法,尽快的去验证我们的想法是不是可行的。因为很多人做产品思维属于自嗨型,“我做的东西最厉害,只要一推出去肯定一群人蜂拥而至。”抱有这种想法的人太多了,实际上,只有尽快去验证才是唯一的解决之道,避免产品走入误区。
图 2 与调研用户第二次对话
然而当我跟用户讲,你需要先装一个 Hadoop,可能还要装一组 Zookeeper,但用户说:“我只想要一个更强大的 MySQL,但是让我装这一堆东西,你是解决问题还是引入问题?”
这个问题有什么解决办法呢?一个办法是你去解决用户,可以通过销售或者通过某些关系跟用户聊,显然这是一个不靠谱的思路。作为一个产品型的公司,我们很快就否了这个想法。用户的本质要求是:你不要给我装一堆的东西,要真正解决我的问题。所以我们马上开始启动分布式 KV 的开发工作,彻底解决掉这个问题,满足用户的要求。
图 3 开发 TiKV 前的技术考量
开始开发 KV 层时候又会面临很多技术选择,我们有很多考量(如图 3)。
第一点,我们认为作为数据库最重要的是正确性。假设这个数据库要用在金融行业,用在银行、保险、证券,和其他一些非常关键的场合的时候,正确性就是无比重要的东西。没有人会用一个不正确的数据库。
第二点是实现简洁、易用。用户对于一个不简洁、不易用的东西是无法接受的,所以我们当时的一个想法是一定要做得比 HBase 更加易用,代码量也要比 HBase 小,所以时至今天 TiDB 代码量仍然是比 HBase 小得多,大约还不到 HBase 的十分之一。
第三点考虑是扩展性。 TiDB 不仅在整体上是分层的,在存储层 TiKV 内部也是分层的,所以有非常好的扩展性,也支持 Raw KV API、Transaction API,这个设计后来也收获了很多用户的支持,比如一点资讯的同学就是用的 Raw KV API。
第四点就是要求高性能低延迟。大家对于数据库的性能和延迟的追求是没有止境的,但是我们当时并没有把太多精力花在高性能低延迟上。刚才说到我们有一条哲学是「Make it work, make it right, make it fast」,大家可以看到这句话里面 「Fast」是放最后的,这一点也是 TiDB 和其他产品有非常大的差异的地方。作为一个技术人员,通常大家看一个产品好不好,就会想:“来,不服跑个分,产品架构、易用性、技术文档、Community 这些指标都不看,先跑个分让大家看看行不行”。这个思路真正往市场上去推时是不对的。很多事情的选择是一个综合的过程。你可以让你的汽车跑的巨快无比,上面东西全拆了就留一个发动机和四个轮子,那肯定也是跑得巨快&#x