好久没写东西,分享一下最近思考的比较多的东西,就当是工作记录了。
从一个很重要的问题出发:如果在今天,我们从新设计一个 Database,架构会是什么样子?
在进入到具体的技术设计之前,我先分享一下我理解的当今(以及未来)的开发者对于数据库的期待:
针对上面这些趋势和痛点,映射到技术上:
带着这些假设,过去这一年,大概做的工作总结一句话就是把: TiDB 大卸八块,然后利用云的基础设施,将它从新拼装起来变成一个数据库服务。最近低调的发布了 TiDB Serverless Tier 就是这个新引擎的第一次亮相。下面聊聊一些技术和工程上的思考。
今天做数据库,如果你不提供云服务,出门都不太好意思和人打招呼(很快就会是 Serverless)。有很多人(尤其是数据库内核开发者)会低估做一个云服务的复杂性,经典的论调:‘不就是在云上的自动化部署吗?’ 或者 ‘支持一下 Kubernetes Operator?’…其实并不是,甚至目标都应该反过来:**我们要做的并不是一个数据库软件,而是一个数据库服务,当我们用更长的眼光去看的时候就会发现,后者是包含前者的。**这个认知的转变是做好数据库云服务第一步,也是最重要的一步。
我们过去开发程序,不同的模块看到的环境是同构且确定的,例如:开发一个单机上运行的软件,不同的模块虽然可以有逻辑上的边界,但是链接到一起之后,运行起来看到的还是这台计算机的一亩三分地,Everything is a trade-off。即使近几年的分布式系统的兴起,但对于经典的分布式软件来说,大致还是单机软件设计思路的延伸,只是通过 RPC 将多台计算机连接在一起,但是仍然环境是相对确定的,尽管很多软件对于底层的环境变化做了一些适配:例如分布式数据库的动态扩容,数据重均衡 Re-balance 等,但是本质并未变化,只是能够操控和调度的资源变多了。但是在云上,这些假设都发生了变化:
假设的变化带来的技术上的变化:云上的数据库,首先应该是多个自治的微服务组成的网络。这里的微服务并非一定是在不同的机器上,在物理上可能在一台机器上,但是需要能在远程访问,另外这些服务应该是无状态的(无副作用),方便快速的弹性扩展,这个带来对于开发者的转变就是:放弃对于同步语义的坚持,这个世界是异步化且不可靠的。我很高兴我的偶像 Amazon 的 CTO Werner Vogels 在今年 ReInvent Keynote 上也强调了这一点。放弃掉对于同步和单机的幻想,得到了什么?我们看一些例子:
第一,最近几年被聊烂的存算分离🙂。在云上,计算的单位价格比存储要高得多,如果计算和存储绑定,那么就没有办法利用存储的价格优势,另外对于一些特定的请求,对于计算的需求很可能与存储节点的物理资源是完全不对等的(想象一下重型的 OLAP 请求的 Resuffle 和分布式聚合)。另外,对于分布式数据库来说,扩容速度是一个重要的用户体验指标,当存算分离后,原则上扩容速度是能做到极快的,因为扩容变成了:1. 启动新的计算节点 2. 缓存预热;反之亦然。
第二,对于数据库来说,一些内部组件的微服务化,例如:DDL-as-a-Service。传统数据库的 DDL 对于在线业务是有影响的(即使用了 Online DDL),例如添加索引时候,不可避免的需要进行数据回填,这对于正在服务 OLTP 负载存储节点来说会引起抖动。如果我们仔细思考一下 DDL 就会发现它是一个:全局的,偶发的,重计算,可离线进行,可重入的模块,如果有一个共享的存储层(例如 S3),这类模块非常适合剥离出来变成一个 Serverless 的服务,通过 S3 与 OLTP 的存储引擎共享数据。带来的好处毋庸置疑:
类似的例子还有很多:日志(CPU 使用少,但是对于存储要求高),LSM-Tree 存储引擎的 Compaction,数据压缩,元信息服务,连接池,CDC 等等,都是可以且很适合被剥离的对象。在新的 Cloud-native 版本的 TiDB 中,我们使用了 Spot Instances 进行存储引擎的 Remote Compaction,带来的成本下降是惊人的。
在设计云数据库的时候,另一个重要的要思考的问题是:QoS(Quality of service),具体到细节大概是:
挑战还有很多,我就不一一列举了。很多经验在 AWS 今年那篇 DynamoDB 的新论文中介绍得很详细,大概参考那篇论文即可。
另一个很重要话题是:云上哪些服务可以依赖?这是因为对于一个第三方厂商来说,跨云(甚至是跨云下,类似混合云)的产品体验是你天然的优势,如果对于特定的云服务依赖得太深太紧,将会让你丧失这份灵活性。所以选择依赖的时候需要非常小心,下面是一些原则:
下面举几个例子说明一下,对于 Cloud-Native TiDB 来说,在选择依赖的时候做出如下选择:
在云上,还有一个很大的设计问题:文件系统是一个好抽象吗?这个问题来自于在哪层抽象之下屏蔽云的基础设施。在 S3 普及之前,各个大型的分布式系统存储系统,尤其是 Google 的:BigTable,Spanner 等都选择了一个分布式文件系统作为底座(我认为这里面有很深的 Plan9 的痕迹,毕竟 Google 内部这些 Infra 大神很多都是从贝尔实验室来的😄)。那么问题来了,如果有了 S3,我们还需不需要一层文件系统的抽象?我目前还没有想清楚,我倾向于有,理由仍然是存储的缓存,如果有一层文件系统,在文件系统层能够根据文件的访问热度做进行一层缓存,提升扩容时候的预热速度;另一个好处是基于文件系统,生态工具兼容性会更好,很多 UNIX 的工具能直接复用,运维复杂度降低。
我在今年的 DevCon 的 Keynote 中提到了一点:云上的数据库如何与现代的开发者体验融合?这个是一个很有意思的话题,因为数据库那么多年了,几乎还是这个样子,SQL is still the king。但是另一方面现在开发者开发的应用以及使用的工具已经和几十年前大不一样了,作为一个从 UNIX 时代过来的老程序员,看到现在年轻一代的开发者使用的眼花缭乱的先进开发工具和理念,只能感叹一代比一代强,虽然操作数据 SQL 仍然是标准,但是数据库软件能否做更多,去融入这些现代的应用开发体验中?
我的答案是:还是能做一些微小的贡献的。例如:
Serverless ,很多人认为的 Serverless 是一个技术名词,我认为不是,Serverless 更重要的是从用户体验角度定义了什么是更好的云上软件的产品形态。或者这是本来就应该是理所应当的:为什么我作为用户需要关心你有几个节点?为什么我需要关心你内部的参数和配置?为什么我点了启动,你要让我再等半小时?…等等这些在我们这个行业里面过去看起来似乎理所应当的事情,其实仔细想想都觉得挺可笑的,举个例子:假设你去买个车,卖车的先送给你一本发动机维修指南,告诉你读完才能上路,车跑得不快,然后告诉你某个发动机参数需要你调一下,每次启动汽车都要等半小时…是不是很奇怪?对于 Serverless 的产品来说,从用户体验来说,最大的意义在于三件事情:
有了这三点,才能很好的将数据库嵌入到其他的应用开发框架中,这是构建更大的生态的基础。
除了 Serverless 之外,现代的开发者体验(DX)中还包含很多其他的关键要素,例如:
我上面提到的很多技术内容,基本上都是无人区,很难提前预见到所有的挑战,这也是没办法的事情。这一段作为结尾,列一部分有意思的挑战,虽然肯定不完备,希望能对你有所启发:
问题和挑战嘛,永远都是有的,把这个系统做出来的过程,也是我们理解这个系统的过程,最后送上我很喜欢的一句话,来自著名的物理学家理查德费曼:
What I cannot create, I do not understand。
领取专属 10元无门槛券
私享最新 技术干货