共计 6820 个字符,预计需要花费 18 分钟才能阅读完成。
本文作者为 PingCAP 联结创始人兼 CTO 黄东旭,将分享分布式数据库的发展趋势以及云原生数据库设计的新思路。
在讲新的思路之前,先为过来没有关注过数据库技术的敌人们做一个简略的历史回顾,接下来会谈谈将来的数据库畛域,在云原生数据库设计方面的新趋势和前沿思考。首先来看看一些支流数据库的设计模式。
常见的分布式数据库流派
分布式数据库的倒退历程,我依照年代进行了分类,到目前为止分成了四代。第一代是基于简略的分库分表或者中间件来做 Data Sharding 和 程度扩大。第二代零碎是以 Cassandra、HBase 或者 MongoDB 为代表的 NoSQL 数据库,个别多为互联网公司在应用,领有很好的程度扩大能力。
第三代零碎我集体认为是以 Google Spanner 和 AWS Aurora 为代表的新一代云数据库,他们的特点是交融了 SQL 和 NoSQL 的扩大能力,对业务层裸露了 SQL 的接口,在应用上能够做到程度的扩大。
第四代零碎是以当初 TiDB 的设计为例,开始进入到混合业务负载的时代,一套零碎领有既能做交易也能解决高并发事务的个性,同时又能联合一些数据仓库或者剖析型数据库的能力,所以叫 HTAP,就是交融型的数据库产品。
将来是什么样子,前面的分享我会介绍对于将来的一些瞻望。从整个工夫线看,从 1970 年代倒退到当初,database 也算是个古老的行业了,具体每个阶段的倒退状况,我就不过多开展。
数据库中间件
对于数据库中间件来说,第一代零碎是中间件的零碎,基本上整个支流模式有两种,一种是在业务层做手动的分库分表,比方数据库的使用者在业务层里通知你;北京的数据放在一个数据库里,而上海的数据放在另一个数据库或者写到不同的表上,这种就是业务层手动的最简略的分库分表,置信大家操作过数据库的敌人都很相熟。
第二种通过一个数据库中间件指定 Sharding 的规定。比方像用户的城市、用户的 ID、工夫来做为分片的规定,通过中间件来主动的调配,就不必业务层去做。
这种形式的长处就是简略。如果业务在特地简略的状况下,比如说写入或者读取根本能进化成在一个分片上实现,在应用层做充沛适配当前,提早还是比拟低的,而整体上,如果 workload 是随机的,业务的 TPS 也能做到线性扩大。
然而毛病也比拟显著。对于一些比较复杂的业务,特地是一些跨分片的操作,比如说查问或者写入要放弃跨分片之间的数据强一致性的时候就比拟麻烦。另外一个比拟显著的毛病是它对于大型集群的运维是比拟艰难的,特地是去做一些相似的表构造变更之类的操作。设想一下如果有一百个分片,要去加一列或者删一列,相当于要在一百台机器上都执行操作,其实很麻烦。
NoSQL – Not Only SQL
在 2010 年前后,好多互联网公司都发现了这个大的痛点,认真思考了业务后,他们发现业务很简略,也不须要 SQL 特地简单的性能,于是就倒退出了一个流派就是 NoSQL 数据库。NoSQL 的特点就是放弃到了高级的 SQL 能力,然而有得必有失,或者说放弃掉了货色总能换来一些货色,NoSQL 换来的是一个对业务通明的、强的程度扩大能力,但反过来就意味着你的业务原来是基于 SQL 去写的话,可能会带来比拟大的革新老本,代表的零碎有方才我说到的 MongoDB、Cassandra、HBase 等。
最有名的零碎就是 MongoDB,MongoDB 尽管也是分布式,但依然还是像分库分表的计划一样,要抉择分片的 key,他的长处大家都比拟相熟,就是没有表构造信息,想写什么就写什么,对于文档型的数据比拟敌对,但毛病也比拟显著,既然抉择了 Sharding Key,可能是依照一个固定的规定在做分片,所以当有一些跨分片的聚合需要的时候会比拟麻烦,第二是在跨分片的 ACID 事务上没有很好的反对。
HBase 是 Hadoop 生态下的比拟有名的分布式 NoSQL 数据库,它是构建在 HDFS 之上的一个 NoSQL 数据库。Cassandra 是一个分布式的 KV 数据库,其特点是在 KV 操作上提供多种一致性模型,毛病与很多 NoSQL 的问题一样,包含运维的复杂性,KV 的接口对于原有业务革新的要求等。
第三代分布式数据库 NewSQL
方才说过 Sharding 或者分库分表,NoSQL 也好,都面临着一个业务的侵入性问题,如果你的业务是重度依赖 SQL,那么用这两种计划都是很不舒服的。于是一些技术比拟前沿的公司就在思考,能不能联合传统数据库的长处,比方 SQL 表达力,事务一致性等个性,然而又跟 NoSQL 时代好的个性,比方扩展性可能相结合倒退出一种新的、可扩大的,然而用起来又像单机数据库一样不便的零碎。在这个思路下就诞生出了两个流派,一个是 Spanner,一个是 Aurora,两个都是顶级的互联网公司在面临到这种问题时做出的一个抉择。
Shared Nothing 流派
Shared Nothing 这个流派是以 Google Spanner 为代表,益处是在于能够做到简直有限的程度扩大,整个零碎没有端点,不论是 1 个 T、10 个 T 或者 100 个 T,业务层基本上不必放心扩大能力。第二个益处是他的设计指标是提供强 SQL 的反对,不须要指定分片规定、分片策略,零碎会主动的帮你做扩大。第三是反对像单机数据库一样的强统一的事务,能够用来反对金融级别的业务。
代表产品就是 Spanner 与 TiDB,这类零碎也有一些毛病,从实质上来说一个纯分布式数据库,很多行为没有方法跟单机行为截然不同。举个例子,比如说提早,单机数据库在做交易事务的时候,可能在单机上就实现了,然而在分布式数据库上,如果要去实现同样的一个语义,这个事务须要操作的行可能散布在不同的机器上,须要波及到屡次网络的通信和交互,响应速度和性能必定不如在单机上一次操作实现,所以在一些兼容性和行为上与单机数据库还是有一些区别的。即便是这样,对于很多业务来说,与分库分表相比,分布式数据库还是具备很多劣势,比方在易用性方面还是比分库分表的侵入性小很多。
Shared Everything 流派
第二种流派就是 Shared Everything 流派,代表有 AWS Aurora、阿里云的 PolarDB,很多数据库都定义本人是 Cloud-Native Database,但我感觉这里的 Cloud-Native 更多是在于通常这些计划都是由私有云服务商来提供的,至于自身的技术是不是云原生,并没有一个对立的规范。从纯技术的角度来去说一个外围的要点,这类零碎的计算与存储是彻底拆散的,计算节点与存储节点跑在不同机器上,存储相当于把一个 MySQL 跑在云盘上的感觉,我集体认为相似 Aurora 或者 PolarDB 的这种架构并不是一个纯正的分布式架构。
原来 MySQL 的主从复制都走 Binlog,Aurora 作为一种在云上 Share Everything Database 的代表,Aurora 的设计思路是把整个 IO 的 flow 只通过 redo log 的模式来做复制,而不是通过整个 IO 链路打到最初 Binlog,再发到另外一台机器上,而后再 apply 这个 Binlog,所以 Aurora 的 IO 链路缩小很多,这是一个很大的翻新。
日志复制的单位变小,意味着我发过来的只有 Physical log,不是 Binlog,也不是间接发语句过来,间接发物理的日志能代表着更小的 IO 的门路以及更小的网络包,所以整个数据库系统的吞吐效率会比传统的 MySQL 的部署计划好很多。
Aurora 的劣势是 100% 兼容 MySQL,业务兼容性好,业务基本上不必改就能够用,而且对于一些互联网的场景,对一致性要求不高的话,数据库的读也能够做到程度扩大,不论是 Aurora 也好,PolarDB 也好,读性能是有下限的。
Aurora 的短板大家也能看得出来,实质上这还是一个单机数据库,因为所有数据量都是存储在一起的,Aurora 的计算层其实就是一个 MySQL 实例,不关怀底下这些数据的散布,如果有大的写入量或者有大的跨分片查问的需要,如果要反对大数据量,还是须要分库分表,所以 Aurora 是一款更好的云上单机数据库。
第四代零碎:分布式 HTAP 数据库
第四代零碎就是新形态的 HTAP 数据库,英文名称是 Hybrid Transactional and Analytical Processing,通过名字也很好了解,既能够做事务,又能够在同一套零碎外面做实时剖析。HTAP 数据库的劣势是能够像 NoSQL 一样具备有限程度扩大能力,像 NewSQL 一样可能去做 SQL 的查问与事务的反对,更重要的是在混合业务等简单的场景下,OLAP 不会影响到 OLTP 业务,同时省去了在同一个零碎外面把数据搬来搬去的懊恼。目前,我看到在工业界根本只有 TiDB 4.0 加上 TiFlash 这个架构可能合乎上述要求。
分布式 HTAP 数据库:TiDB (with TiFlash)
为什么 TiDB 可能实现 OLAP 和 OLTP 的彻底隔离,互不影响?因为 TiDB 是计算和存储拆散的架构,底层的存储是多正本机制,能够把其中一些正本转换成列式存储的正本。OLAP 的申请能够间接打到列式的正本上,也就是 TiFlash 的副原本提供高性能列式的剖析服务,做到了同一份数据既能够做实时的交易又做实时的剖析,这是 TiDB 在架构层面的微小翻新和冲破。
下图是 TiDB 的测试后果,与 MemSQL 进行了比照,依据用户场景结构了一种 workload,横轴是并发数,纵轴是 OLTP 的性能,蓝色、黄色、绿色这些是 OLAP 的并发数。这个试验的目标就是在一套零碎上既跑 OLTP 又跑 OLAP,同时一直晋升 OLTP 和 OLAP 的并发压力,从而查看这两种 workload 是否会相互影响。能够看到在 TiDB 这边,同时加大 OLTP 和 OLAP 的并发压力,这两种 workload 的性能体现没有什么显著变动,简直是差不多的。然而,同样的试验产生在 MemSQL 上,大家能够看到 MemSQL 的性能大幅衰减,随着 OLAP 的并发数变大,OLTP 的性能降落比拟显著。
接下来是 TiDB 在一个用户理论业务场景的例子,在进行 OLAP 业务的查问的时候,OLTP 业务依然能够实现平滑的写入操作,提早始终维持在较低的程度。
将来在哪里
Snowflake
Snowflake 是一个 100% 构建在云上的数据仓库零碎,底层的存储依赖 S3,基本上每个私有云都会提供相似 S3 这样的对象存储服务,Snowflake 也是一个纯正的计算与存储拆散的架构,在零碎外面定义的计算节点叫 Virtual Warehouse,能够认为就是一个个 EC2 单元,本地的缓存有日志盘,Snowflake 的次要数据存在 S3 上,本地的计算节点是在私有云的虚机上。
这是 Snowflake 在 S3 外面存储的数据格式的特点,每一个 S3 的对象是 10 兆一个文件,只追加,每一个文件外面蕴含源信息,通过列式的存储落到磁盘上。
Snowflake 这个零碎最重要的一个闪光点就是对于同一份数据能够调配不同的计算资源进行计算,比方某个 query 可能只须要两台机器,另外一个 query 须要更多的计算资源,然而没关系,实际上这些数据都在 S3 下面,简略来说两台机器能够挂载同一块磁盘别离去解决不同的工作负载,这就是一个计算与存储解耦的重要例子。
Google BigQuery
第二个零碎是 BigQuery,BigQuery 是 Google Cloud 上提供的大数据分析服务,架构设计上跟 Snowflake 有点相似。BigQuery 的数据存储在谷歌外部的分布式文件系统 Colossus 下面,Jupiter 是外部的一个高性能网络,下面这个是谷歌的计算节点。
BigQuery 的解决性能比拟杰出,每秒在数据中心内的一个双向的带宽能够达到 1 PB,如果应用 2000 个专属的计算节点单元,大略一个月的费用是四万美金。BigQuery 是一个按需付费的模式,一个 query 可能就用两个 slot,就收取这两个 slot 的费用,BigQuery 的存储老本绝对较低,1 TB 的存储大略 20 美金一个月。
RockSet
第三个零碎是 RockSet,大家晓得 RocksDB 是一个比拟有名的单机 KV 数据库,其存储引擎的数据结构叫 LSM-Tree,LSM-Tree 的核心思想进行分层设计,更冷的数据会在越上层。RockSet 把前面的层放在了 S3 的存储下面,下面的层其实是用 local disk 或者本地的内存来做引擎,人造是一个分层的构造,你的利用感知不到上面是一个云盘还是本地磁盘,通过很好的本地缓存让你感知不到上面云存储的存在。
所以方才看了这三个零碎,我感觉有几个特点,一个是首先都是人造分布式的,第二个是构建在云的规范服务下面的,尤其是 S3 和 EBS,第三是 pay as you go,在架构外面充分利用了云的弹性能力。我感觉这三点最重要的一点是存储,存储系统决定了云上数据库的设计方向。
为什么 S3 是要害?
在存储里边我感觉更要害的可能是 S3。EBS 其实咱们也有钻研过,TiDB 第一阶段其实曾经正在跟 EBS 块存储做交融,但从更久远的角度来看,我感觉更有意思的方向是在 S3 这边。
首先第一点 S3 十分划算,价格远低于 EBS,第二 S3 提供了 9 个 9 很高的可靠性,第三是具备线性扩大的吞吐能力,第四是人造跨云,每一个云上都有 S3 API 的对象存储服务。然而 S3 的问题就是随机写入的提早十分高,然而吞吐性能不错,所以咱们要去利用这个吞吐性能不错的这个特点,躲避提早高的危险。这是 S3 benchmark 的一个测试,能够看到随着机型的晋升,吞吐能力也是继续的晋升。
如何解决 Latency 的问题?
如果要解决 S3 的 Latency 问题,这里提供一些思路,比方像 RockSet 那样用 SSD 或者本地磁盘来做 cache,或者通过 kinesis 写入日志,来升高整个写入的提早。还有数据的复制或者你要去做一些并发解决等,其实能够去做 Zero-copy data cloning,也是升高提早的一些形式。
上述例子有一些共同点都是数据仓库,不晓得大家有没有发现,为什么都是数据仓库?数据仓库对于吞吐的要求其实是更高的,对于提早并不是那么在意,一个 query 可能跑五秒出后果就行了,不必要求五毫秒之内给出后果,特地是对于一些 Point Lookup 这种场景来说,Shared Nothing 的 database 可能只须要从客户端的一次 rpc,然而对于计算与存储拆散的架构,两头无论如何要走两次网络,这是一个外围的问题。
你可能会说没有关系,反正计算和存储曾经拆散了,鼎力出奇观,能够加计算节点。然而我感觉新思路没必要这么极其,Aurora 是一个计算存储拆散架构,但它是一个单机数据库,Spanner 是一个纯分布式的数据库,纯 Shared Nothing 的架构并没有利用到云基础设施提供的一些劣势。
比如说将来咱们的数据库能够做这样的设计,在计算层其实带着一点点状态,因为每台 EC2 都会带一个本地磁盘,当初支流的 EC2 都是 SSD,比拟热的数据能够在这一层做 Shared Nothing,在这一层去做高可用,在这一层去做随机的读取与写入。热数据一旦 cache miss,才会落到 S3 下面,能够在 S3 只做前面几层的数据存储,这种做法可能会带来问题,一旦穿透了本地 cache,Latency 会有一些抖动。
这种架构设计的益处:首先,领有对实时业务的数据计算亲和力,在 local disk 上会有很多数据,在这点上很多传统数据库的一些性能优化技巧能够用起来;第二,数据迁徙其实会变得很简略,实际上底下的存储是共享的,都在 S3 下面,比如说 A 机器到 B 机器的数据迁徙其实不必真的做迁徙,只有在 B 机器上读取数据就行了。
这个架构的毛病是:第一,缓存穿透了当前,Latency 会变高;第二,计算节点当初有了状态,如果计算节点挂掉了当前,Failover 要去解决日志回放的问题,这可能会减少一点实现的复杂度。
还有很多值得钻研的课题
下面的架构只是一个构想,TiDB 其实还不是这样的架构,但将来可能会在这方向去做一些尝试或者钻研,在这个畛域外面其实还有很多 open question 咱们还没有答案,包含云厂商、包含咱们,包含学术界都没有答案。
当初有一些钻研的课题,第一,如果咱们要利用本地磁盘,应该缓存多少数据,LRU 的策略是什么样子,跟 performance 到底有什么关系,跟 workload 有什么关系。第二,对于网络,方才咱们看到 S3 的网络吞吐做的很好,什么样的性能要配上什么样的吞吐,要配多少个计算节点,特地是对于一些比较复杂查问的 Reshuffle;第三,计算复杂度和计算节点、机型的关系是什么?这些问题其实都是比较复杂的问题,特地是怎么用数学来表白,因为须要自动化地去做这些事件。
即便这些问题都解决了,我感觉也只是云上数据库时代的一个开始。将来在 Serverless,包含 AI-Driven 几大方向上,怎么设计出更好的 database,这是咱们致力的方向。最初援用屈原的一句话,就是路漫漫其修远兮,咱们还有很多事件须要去做,谢谢大家。