1. 概述
Databus是一个低延迟、可靠的、支持事务的、保持一致性的数据变更抓取系统。由LinkedIn于2013年开源。Databus通过挖掘数据库日志的方式,将数据库变更实时、可靠的从数据库拉取出来,业务可以通过定制化client实时获取变更并进行其他业务逻辑。
Databus有以下特点:
- 数据源和消费者之间的隔离。
- 数据传输能保证顺序性和至少一次交付的高可用性。
- 从变化流的任意时间点进行消费,包括通过bootstrap获取所有数据。
- 分区消费
- 源一致性保存,消费不成功会一直消费直到消费成功
2. 功能&特性
- 来源独立:Databus支持多种数据来源的变更抓取,包括Oracle和MySQL。
- 可扩展、高度可用:Databus能扩展到支持数千消费者和事务数据来源,同时保持高度可用性。
- 事务按序提交:Databus能保持来源数据库中的事务完整性,并按照事务分组和来源的提交顺寻交付变更事件。
- 低延迟、支持多种订阅机制:数据源变更完成后,Databus能在毫秒级内将事务提交给消费者。同时,消费者使用Databus中的服务器端过滤功能,可以只获取自己需要的特定数据。
- 无限回溯:对消费者支持无限回溯能力,例如当消费者需要产生数据的完整拷贝时,它不会对数据库产生任何额外负担。当消费者的数据大大落后于来源数据库时,也可以使用该功能。
3. 使用场景举例
BUSSINESS1 和 BUSSINESS2 是两个不同的业务逻辑,它们的变更需要同时写入到 DB 和 CACHE ,那么当他们同时修改同一个数据的时候是否能保证数据的一致性呢?可以发现如果按照下图标明的顺序进行操作并不能保证数据的一致性!
还有一个问题是变更完DB之后,更新CACHE失败怎么办?如果忽略的话,会造成后续读取到CACHE中旧的数据,如果重试的话,业务代码会写得更加复杂。针对这些场景,如果没有一个强一致协议是很难解决掉的。如果要业务逻辑去实现这些晦涩的一致性协议,却又是不现实的。
解决方案如下图所示:
3.1 常见概念
1. SCN(System Change Number):也就是通常所说的系统改变号,是数据库中非常重要的一个数据结构。SCN用以标识数据库在某个确切时刻提交的版本。在事务提交时,它被赋予一个唯一的标识事务的SCN。SCN同时被作为Oracle数据库的内部时钟机制,可被看做逻辑时钟,每个数据库都有一个全局的SCN生成器。
2. binlog:MySQL的二进制日志可以说是MySQL最重要的日志了,它记录了所有的DDL和DML(除了数据查询语句)语句,以事件形式记录,还包含语句所执行的消耗的时间,MySQL的二进制日志是事务安全型的。
DDL****和DML:DDL(Data Definition Language 数据定义语言)用于操作对象和对象的属性,这种对象包括数据库本身,以及数据库对象,像:表、视图等等,DDL对这些对象和属性的管理和定义具体表现在Create、Drop和Alter上。DML(Data Manipulation Language 数据操控语言)用于操作数据库对象中包含的数据,也就是说操作的单位是记录。包括Insert、Delete和Update语句
分片:将数据库的变更,按照某个字段的不同维度(如哈希取模),交给不同线程处理,在保证同一条数据顺序执行的前提下,提高变更消费的速度,主要解决顺序执行和并发之间的矛盾。详见:Dbus如何保证顺序性&一致性
5. source:databus关注哪个数据库哪些表的变更。
4. 系统整体架构
上图中介绍了Databus系统的构成,包括Relays、Bootstrap Service和Client lib等。Bootstrap Service中包括Bootstrap Producer和Bootstrap Server。快速变化的Consumer直接从Relay中取事件。如果一个Consumer的数据更新大幅落后,它要的数据就不在Relay的日志中,而是需要请求Bootstrap Service,返回的将会是自Consumer上次处理变更之后的所有数据变更Snapshot。
- Source Databases:MySQL以及Oracle数据源
- Relays:负责抓取和存储数据库变更,全内存存储,也可配置使用mmap内存映射文件方式
- Schema Registry:数据库数据类型到Databus数据类型的一个转换表
- Bootstrap Service:一个特殊的客户端,功能和Relays类似,负责存储数据库变更,主要是磁盘存储
- Application:数据库变更消费逻辑,从Relay中拉取变更,并消费变更
- Client Lib:提供挑选关注变更的API给消费逻辑
- Consumer Code:变更消费逻辑,可以是自身消费或者再将变更发送至下游服务
4.1 主要组件及功能
DataBus的主要由以下四个组件构成:
- Databus Relay:
- 从Source DataBus中的Databus源中读取变化的行并序列化为Databus变化事件保存到内存缓冲区中。
- 监听Databus客户端的请求(包括引导程序的请求)并传输Databus数据变化事件。
- Databus Client:
- 在Relay上检查新的数据变化事件和处理特定的业务逻辑的回调。
- 如果它们在relay后面落下太远,到Bootstrap Service运行一个追溯查询。
- 单独的客户端可以处理全部的Databus流,它们也可以作为集群的一部分而每个客户端处理一部分流。
- Databus Bootstrap Producer:
- 只是一个特殊的客户端。
- 检查Relay上的新的数据变化事件。
- 保存数据变化事件到Mysql数据库,Mysql数据库用于引导程序和为了客户端追溯数据。
- Databus Bootstrap Server:
- 监听来自Databus客户端的请求并为了引导和追溯返回一个超长的回溯的数据变化事件。
5. Databus Relay和Databus Client详细分析
5.1 Databus Relay
5.1.1 架构与组件功能
**Databus Event Producer(DBEP)**:定期从数据库中查询变更,如果检测到变更,它将读取数据库中的所有已更改的行,并将其转换为Avro记录。因为数据库数据类型和Databus数据类型不一致,因此需要 Schema Registry 做转换。
SCN(System Change Number):系统改变号,是数据库中非常重要的一个数据结构。SCN用以标识数据库在某个确切时刻提交的版本。在事务提交时,它被赋予一个唯一的标识事务的SCN。
Event Buffers:按照SCN的顺序存储databus事件,buffer可以是纯内存的,也可以是mmap到文件系统的。每个buffer在内存中还有一个对应的SCN Index和一个MaxSCN reader/writer,SCN Index可以加快查询指定事件的速度。
Request Processor:通过监听Netty的channel,实现收发client的请求。
MaxSCN Reader/Writer:用于跟踪DBEP的处理进度;Reader在Databus启动的时候会读取存储的文件上一次DBEP处理的位置,当Databus从DBEP中读取变更存储到Event Buffers时,Writer就会最后一个SCN写入到文件中存储,这样就能保证下次启动可以从正确的位置读取数据库变更。
JMX(Java Management Extensions):支持标准的Jetty容器,databus提供了多个Mbean来监控relay
- ContainerStatsMBean
- DbusEventsTotalStatsMBean
- DbusEventsStatisticsCollectorMBean
RESTFul Interface:Realy提供了相关http接口供外部调用,Client与Relay建立http长连接,并从Relay拉取Event。
5.2 Databus Client
5.2.1 架构与组件功能
Relay Puller:负责从relay拉取数据,具体工作有挑选relay,请求source,请求Register,校验schema,设置dispatcher等。
Dispatcher:从event buffers中读取事件,调用消费逻辑的回调,主要职责有:
- 判断回调是否正确,回调失败后会进行重试,重试次数超限后抛出异常
- 监控错误和超时
- 持久化checkpoint
Checkpoint persistence Provider:checkpoint是消费者消费变更记录点的位置,负责将checkpoint持久化到本地,保证下次启动后可以从正常的位置pull event。
Event Callback:调用消费者自定义业务逻辑代码。
Bootstrap Puller:负责从Bootstrap servers拉取数据,功能类似Relay Puller。