Debezium 是一个用于变更数据捕获的开源分布式平台。能够保证应用程序就可以开始响应其他应用程序提交到您数据库的所有插入、更新和删除操作。Debezium 持久、快速,因此即使出现问题,您的应用程序也能快速响应,绝不会错过任何事件。Debezium 默认使用Kafka来投递数据,在事务日志中记录提交到每个数据库表的所有行级变更。每个应用程序只需读取其感兴趣的事务日志,即可按事件发生的相同顺序查看所有事件。
Debezium 简介
Debezium是一个开源项目,为捕获数据更改(change data capture,CDC)提供了一个低延迟的流式处理平台。你可以安装并且配置Debezium去监控你的数据库,然后你的应用就可以消费对数据库的每一个行级别(row-level)的更改。只有已提交的更改才是可见的,所以你的应用不用担心事务(transaction)或者更改被回滚(roll back)。Debezium为所有的数据库更改事件提供了一个统一的模型,所以你的应用不用担心每一种数据库管理系统的错综复杂性。另外,由于Debezium用持久化的、有副本备份的日志来记录数据库数据变化的历史,因此,你的应用可以随时停止再重启,而不会错过它停止运行时发生的事件,保证了所有的事件都能被正确地、完全地处理掉。
监控数据库,并且在数据变动的时候获得通知一直是很复杂的事情。关系型数据库的触发器可以做到,但是只对特定的数据库有效,而且通常只能更新数据库内的状态(无法和外部的进程通信)。一些数据库提供了监控数据变动的API或者框架,但是没有一个标准,每种数据库的实现方式都是不同的,并且需要大量特定的知识和理解特定的代码才能运用。确保以相同的顺序查看和处理所有更改,同时最小化影响数据库仍然非常具有挑战性。
Debezium提供了模块为你做这些复杂的工作。一些模块是通用的,并且能够适用多种数据库管理系统,但在功能和性能方面仍有一些限制。另一些模块是为特定的数据库管理系统定制的,所以他们通常可以更多地利用数据库系统本身的特性来提供更多功能。
Debezium基础架构
Debezium是一个捕获数据更改(CDC)平台,并且利用Kafka和Kafka Connect实现了自己的持久性、可靠性和容错性。每一个部署在Kafka Connect分布式的、可扩展的、容错性的服务中的connector监控一个上游数据库服务器,捕获所有的数据库更改,然后记录到一个或者多个Kafka topic(通常一个数据库表对应一个kafka topic)。Kafka确保所有这些数据更改事件都能够多副本并且总体上有序(Kafka只能保证一个topic的单个分区内有序),这样,更多的客户端可以独立消费同样的数据更改事件而对上游数据库系统造成的影响降到很小(如果N个应用都直接去监控数据库更改,对数据库的压力为N,而用debezium汇报数据库更改事件到kafka,所有的应用都去消费kafka中的消息,可以把对数据库的压力降到1)。另外,客户端可以随时停止消费,然后重启,从上次停止消费的地方接着消费。每个客户端可以自行决定他们是否需要exactly-once或者at-least-once消息交付语义保证,并且所有的数据库或者表的更改事件是按照上游数据库发生的顺序被交付的。
对于不需要或者不想要这种容错级别、性能、可扩展性、可靠性的应用,他们可以使用内嵌的Debezium connector引擎来直接在应用内部运行connector。这种应用仍需要消费数据库更改事件,但更希望connector直接传递给它,而不是持久化到Kafka里。
常见使用场景
Debezium有很多非常有价值的使用场景,我们在这儿仅仅列出几个更常见的使用场景。
缓存失效(Cache invalidation)
在缓存中缓存的条目(entry)在源头被更改或者被删除的时候立即让缓存中的条目失效。如果缓存在一个独立的进程中运行(例如Redis,Memcache,Infinispan或者其他的),那么简单的缓存失效逻辑可以放在独立的进程或服务中,从而简化主应用的逻辑。在一些场景中,缓存失效逻辑可以更复杂一点,让它利用更改事件中的更新数据去更新缓存中受影响的条目。
简化单体应用(Simplifying monolithic applications)
许多应用更新数据库,然后在数据库中的更改被提交后,做一些额外的工作:更新搜索索引,更新缓存,发送通知,运行业务逻辑,等等。这种情况通常称为双写(dual-writes),因为应用没有在一个事务内写多个系统。这样不仅应用逻辑复杂难以维护,而且双写容易丢失数据或者在一些系统更新成功而另一些系统没有更新成功的时候造成不同系统之间的状态不一致。使用捕获更改数据技术(change data capture,CDC),在源数据库的数据更改提交后,这些额外的工作可以被放在独立的线程或者进程(服务)中完成。这种实现方式的容错性更好,不会丢失事件,容易扩展,并且更容易支持升级。
共享数据库(Sharing databases)
当多个应用共用同一个数据库的时候,一个应用提交的更改通常要被另一个应用感知到。一种实现方式是使用消息总线,尽管非事务性(non-transactional)的消息总线总会受上面提到的双写(dual-writes)影响。但是,另一种实现方式,即Debezium,变得很直接:每个应用可以直接监控数据库的更改,并且响应更改。
数据集成(Data integration)
数据通常被存储在多个地方,尤其是当数据被用于不同的目的的时候,会有不同的形式。保持多系统的同步是很有挑战性的,但是可以通过使用Debezium加上简单的事件处理逻辑来实现简单的ETL类型的解决方案。
命令查询职责分离(CQRS)
在命令查询职责分离 [Command Query Responsibility Separation (CQRS)](http://martinfowler.com/bliki/CQRS.html) 架构模式中,更新数据使用了一种数据模型,读数据使用了一种或者多种数据模型。由于数据更改被记录在更新侧(update-side),这些更改将被处理以更新各种读展示。所以CQRS应用通常更复杂,尤其是他们需要保证可靠性和全序(totally-ordered)处理。Debezium和CDC可以使这种方式更可行:写操作被正常记录,但是Debezium捕获数据更改,并且持久化到全序流里,然后供那些需要异步更新只读视图的服务消费。写侧(write-side)表可以表示面向领域的实体(domain-oriented entities),或者当CQRS和 [Event Sourcing](http://martinfowler.com/eaaDev/EventSourcing.html) 结合的时候,写侧表仅仅用做追加操作命令事件的日志。
一)安装部署
debezium需要安装kafka环境
从网站 https://debezium.io 下载最新debezium连接器包debezium-connector-mysql,解压后放到kafka的plugins插件文件夹里,如图
二)配置
1.mysql打开binlog
2.mysql中新增用户,给对应的权限
3.修改kafka里config配置connect-debezium-mysql.properties
#实例名称,保持默认
name=debezium-mysql-snweb-connector
#入口类名,请勿修改
connector.class=io.debezium.connector.mysql.MySqlConnector
#目标数据库地址
database.hostname=
#目标数据库端口
database.port=3306
#数据库用户
#注意此用户必须至少具有SELECT, RELOAD, SHOW DATABASES, REPLICATION SLAVE, REPLICATION CLIENT 权限
database.user=cdc
#数据库密码
database.password=
#数据库实例编号,保持默认
database.server.id=1
#数据库时区 https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
database.connectionTimeZone=Asia/Shanghai
#数据变更所属主题前缀,建议名称为 数据库名_cdc
topic.prefix=
#要监听数据变更的数据库
database.include.list=
#不监听的数据库表,多个表之间使用英文逗号隔开
#table.exclude.list=snweb-jl.auditlog,snweb-jl.log,snweb-jl.handsetmessage,snweb-jl.terminalmessage,snweb-jl.handsetlog
#数据变更消息投递目标kafka服务器
schema.history.internal.kafka.bootstrap.servers=localhost:9092
#数据库结构变更消息所属主题,建议名称为 数据库名称_dbhistory
schema.history.internal.kafka.topic=
#是否监听数据库结构变更,保持默认
include.schema.changes=true
#是否包含原始查询语句,保持默认
include.query=true
#注意如果要接收1MB以上的数据,需要设置该值
producer.max.request.size = 67108864
在kafka根目录启动命令:bin/connect-standalone.sh config/connect-standalone.properties config/connect-debezium-mysql.properties
三)订阅数据查看
使用offset,原kafka tools连接kafka查看数据
四)程序订阅数据
编写C#或者Java等程序读取kafka里的数据,代码自行编写或者搜索,就不列举了。
主要注意消息体里,before是修改前数据,after是修改之后数据,包括数据结构也在消息体里,可以根据业务自行操作
注意如果要接收1MB以上的数据,需要设置该值producer.max.request.size值,