昨天发了一篇关于AlloyDB的文章,有朋友给我留言,也有朋友通过微信做了一些交流,实际上AlloyDB到底能不能成功,能获得多大的成功还是个未知数。并且因为AlloyDB旨在GCP上提供,不提供云下版本,因此我也没办法真实的去体验AlloyDB,仅仅从发布会上及会后一些体验者的实验报告中获得一些特性方面的信息。只不过我觉得AlloyDB为云原生数据库提供了一个十分好的样板,在很多设计上都具有划时代意义的创新。如谷歌官方所说,AlloyDB关注的是未来及当下数据库用户的最大的关注点:高可扩展性、高性能、高可用性、易于管理、实时运维可观测性、AL/ML能力。
如上图所示,通过Intelligent Database Storage Engine,AlloyDB消除了数据库BLOCK的回写,只剩下WAL WRITE。计算引擎只需要把WAL写入低延时日志存储层,那么事务提交就完成了。数据文件的落盘是异步的,通过LPS服务使用WAL来完成。这种设计参考了分布式消息中间件等的设计思路,以往采用此类实现的都是一些简单的系统,而谷歌把这种设计用到了十分复杂的数据库上。
消除块写,是充分利用现代硬件和云平台的高可扩展性和性能特点的一种设计。通过并行的LPS可以并发处理大量的WAL写入和BLOCK落盘,通过低延时的LOG STORE,可以快速的完成WAL落盘,避免引起数据库事务提交的性能问题。这也是AlloyDB不支持跨数据中心的主要原因(跨数据中心需要通过复制)。昨天和朋友的交流中,也表示了对LOG STORE与计算节点分离后的性能问题的担忧,不过想想Oracle的Exadata,计算节点与存储节点之间也存在复杂的IO路径,只要能够优化好,实际上也是问题不大的。我们的传统数据库架构,从服务器到存储系统,也有很长的IO路径。
昨天大家比较关心的另外一个问题,如果计算引擎不写BLOCK了,那么是不是要等LPS完成日志数据重演,数据才能读取呢?实际上这个担心是不必要的,谷歌也意识到了AlloyDB的读取路径有点长,因此为了降低OLTP的延时,设计了一种多层缓冲机制的读取架构。如果LPS还没有完成某个BLOCK的持久化写入,那么这个BLOCK相关的数据是在LPS BUFFER CACHE里缓存的,可以直接从LPS BUFFER CACHE里命中该数据(哪怕写入完成,如果该BLOCK还没有老化,那么在BUFFER CACHE中也可能命中),如果在此层命中,则访问效率会更高,因为LPS所在的设备的IO性能更好。
我觉得还是用昨天那张写入流程的图可以更为准确的描述写入操作。在WAL落盘的同时,WAL STREAM会被同步到只读节点,用于更新只读节点的BUFFER CACHE(与主节点的BUFFER CACHE同步)。为什么要这么做呢?对于基于“日志就是数据库”理念设计的读写分离共享存储数据库系统,只读节点与主节点之间并不是完全实时的,因为只有当BLOCK被写入后,从节点才能获取到最新的版本。在主节点缓冲区中暂时没有落盘的数据有可能没有提交就已经落盘,也有可能落盘后还没有提交。因此对从节点的一致性读造成了影响。去年的一篇分析PolarDB的架构的文章中,我也提出了这个问题,当时我也提出了可以采用缓冲区融合或者更为简化的方案来替代目前PolarDB仅仅依靠日志重演来实现主从同步的方案。
在那篇文章里,我也分析了PolarDB日志重演算法可能引发的一些读节点因为重演延时而导致的读最新数据的阻塞问题。
在那篇文章中,我也谈到了目前PolarDB采用的日志重演的方式存在的缺陷以及通过WAL STREAMS直接同步BUFFER CACHE的设想。在这里我就不多说了,大家有兴趣可以区翻阅一下。PolarDB设计了多种结构来避免重演存在的问题,设计也十分精巧,只不过还是没有脱离BLOCK持久化的惯性,因此每个从节点都需要独立的重演日志。AlloyDB在这方面的解决方案更加漂亮,AlloyDB的从节点不需要重演日志,因为日志重演变成了一个公共服务,不论主节点还是从节点,一个集群里只需要一次统一的持久化为目的的重演。
利用WAL STREAMS同步了BUFFER CACHE后,主从节点之间就没有任何数据延迟了。国内现在有些数据库厂商也都在搞类似Aurora的分布式数据库产品,AlloyDB是一个很好的学习榜样。我不太赞成数据库厂商去通过类似Oracle Cache fusion的方式来实现类似RAC的功能,因为这个太复杂了,DLM/GES/GCS等服务想要做好并不容易。而类似AlloyDB这种实现是很容易的,也能够满足绝大多数用户的需求。特别是云原生数据库,这种架构比CACHE FUSION为核心的RAC有更好的横向扩展能力。
昨天很多朋友对AlloyDB如何实现HTAP,实现分析类SQL 100倍的性能提升。也有一些朋友对100倍的性能提升提出了疑问,认为很难实现。AlloyDB的HTAP是通过实例内的列引擎实现的。行数据在内存中生成了列缓冲副本,这个实现方式十分类似于Oracle的in-memory db。
AlloyDB通过AI/ML引擎自动推荐列缓冲建议,用户可以使用自动或者手动方式来建立列缓冲。实际上,HTAP中的AP不仅仅是列缓冲就能解决的,列缓冲只能解决一部分问题,OLAP数据库产品有着更为复杂的索引与执行器优化机制。昨天一个朋友也质疑AlloyDB在AP上100倍的性能提升问题。我也仔细阅读了谷歌官网的文档,也认真看了一些体验者的实验。
谷歌的官方说明是具体提升的倍数是和应用场景相关的,他们目前也在通过进一步的优化,从而让各种场景都能有更大的性能提升。这说明100倍不是覆盖所有的场景。我看了一些案例,大多数是逻辑比较简单的超大表的查询或者全表扫描,分组统计,并没有特别复杂的多表关联。对于AlloyDB的理解我也还比较肤浅,只不过在多年的数据库应用经验中,我看到了一种全新的云原生数据库设计方案,我觉得我们的数据库架构师能够认真研究一下,应该是能从中学到不少好东西的。