有关日志的本质以及在分布式系统中的成都各类应用,早在工作室 2013 年,Kafka 之父 Jay Kreps 即在 - "The Log: What every software engineer should know about real-time data's unifying abstraction" 一文中有过非常专业的描述(这哥们的知识面实在是太广泛了!)。如果用一段话来概括日志对于分布式系统的意义,我认为应该是文章里的这段:
How is a append-only sequence of records in any way related to data systems? The answer is that logs have a specific purpose: they record what happened and when. For distributed data systems this is, in many ways, the very heart of the problem.
也就是说,一个只追加的日志系统记录了分布式系统中什么时间点发生了什么事情。这个在分布式系统中意味着什么?这意味着两件极其美妙的事情:1)你可以重现完整历史;2)你可以复制多份历史。以数据库系统为例,需要满足 ACID 性质,分别指 Atomicity(原子性),Consistency(一致性),Isolation(隔离性),Durability(持久性)。相较于整体打包实现这四个特性的一个超级存储体,一个只追加的日志系统能够提供其中的两大性质 - Atomicity(原子性)与 Durability(持久性),而数据库系统在此之上再做到数据一致性以及事务隔离性即可。
当然日志这个美妙的性质,人们很早就意识到了,日志(消息)队列产品也是层出不穷,如 Kafka,Pulsar,RabbitMQ,RocketMQ 等等。我们做分布式系统的同学多少都接触过计算-存储分离的概念,云原生数据库的先驱者 - AWS Aurora,创新性地在数据库领域采用了存储计算分离架构。如图 4 所示,再有日志的这一层抽象,即进一步把日志模块从存储中抽离出来,那么整个系统的架构就演进成了计算-日志-存储三级分离的架构。
书接上回,这里我们探讨一个问题:类似 Kafka/Pulsar 这样的消息队列能否作为数据库的日志存储组件?对于这个问题,我的回答是可以,也不可以。可以的原因是,实时分析数据库 Rockset,向量数据库 Milvus 应该都是直接依赖的开源消息队列 Kafka/Pulsar 做的日志存储,并且作者很是推崇“Replication as a Service” 这一趋势。想一想这个其实也比较合理,对于外部数据库创业公司而言,开源的 Kafka/Pulsar 提供了相当高的技术水准,能够满足我们对于日志存储绝大部分的想象,复用这样成熟的组件,可以让有限的人力聚焦在数据库创新业务本身的逻辑。
为什么说不可以呢?当然这个是对各云计算大厂而言的。原因有二:作为数据库产品依赖的核心组件,研发同学务必吃透它的每一行代码逻辑,才能满足开发运维需求,而开源的消息队列如 Kafka/Pulsar 等功能追求大而全,代码细节可理解性并不强,此乃原因一也;分布式存储场景下,日志模块需要适配并支持业务的定制需求,譬如说基于分区调度模型的存储产品 [4],分区的分裂合并是必须的业务需求,日志模块如何保障分区分裂合并前后的数据一致性?再譬如说数据库业务的跨域容灾,日志模块如何支持跨域部署,跨域同步复制?跨域就近访问?再譬如说要支持跨区域的强一致性读,日志模块该如何支持 ...... 这些数据库乃至分布式存储场景中的高阶需求并非开源日志队列组件如 Kafka/Pulsar 等后继发力的方向,所谓道不同不相为谋,此乃原因二也。
所以,假如(我是说假如)数据库产品,包括云存储产品需要一个公共的日志组件,它应该长什么样子呢?吾辈皆非 Jay Kreps 这等大牛,面对此问,竟一时语塞 ...... 所谓他山之石,可以攻玉,我们先看看业界同仁们的大作,尝试从中提炼一下公共的需求吧。