Debezium系列之:Debezium Server

一、认识Debezium Server

Debezium 提供了一个即用型应用程序,可将更改事件从源数据库流式传输到 Amazon Kinesis、Google Cloud Pub/Sub、Apache Pulsar、Redis (Stream) 或 NATS JetStream 等消息传递基础设施。要将更改事件流式传输到 Apache Kafka,建议通过 Kafka Connect 部署 Debezium 连接器。

Debezium Server实现详细步骤可以参考博主以下几篇技术博客:

更多内容请阅读博主Debezium专栏,博主会持续更新Debezium专栏:

二、部署

安装包下载链接:

将创建一个名为 debezium-server 的目录,其中包含以下内容:

debezium-server/
|-- CHANGELOG.md
|-- conf
|-- CONTRIBUTE.md
|-- COPYRIGHT.txt
|-- debezium-server-2.3.0.Final-runner.jar
|-- lib
|-- LICENSE-3rd-PARTIES.txt
|-- LICENSE.txt
|-- README.md
`-- run.sh

服务器使用run.sh脚本启动,依赖项存储在lib目录中,conf目录包含配置文件。

如果使用 Oracle 连接器,您必须将 ORACLE JDBC 驱动程序添加到 lib 目录(如果使用 XStream,还需要添加 XStream API 文件)。

获取 Oracle JDBC 驱动程序和 XStream API 文件,可以参考下面这篇技术博客:

三、配置

Debezium Server 使用 MicroProfile Configuration 进行配置。这意味着可以从不同的源(如配置文件、环境变量、系统属性等)配置应用程序。

主要配置文件是conf/application.properties。配置了多个部分:

  • debezium.source 用于源连接器配置; Debezium Server 的每个实例都运行一个连接器
  • debezium.sink用于水槽系统配置
  • debezium.format 用于输出序列化格式配置
  • debezium.transforms 用于消息转换的配置
  • debezium.predicates 用于配置消息转换谓词

示例配置文件如下所示:

debezium.sink.type=kinesis
debezium.sink.kinesis.region=eu-central-1
debezium.source.connector.class=io.debezium.connector.postgresql.PostgresConnector
debezium.source.offset.storage.file.filename=data/offsets.dat
debezium.source.offset.flush.interval.ms=0
debezium.source.database.hostname=localhost
debezium.source.database.port=5432
debezium.source.database.user=postgres
debezium.source.database.password=postgres
debezium.source.database.dbname=postgres
debezium.source.topic.prefix=tutorial
debezium.source.schema.include.list=inventory

在此配置文件示例中:

  • 接收器已在区域 eu-central-1 中为 AWS Kinesis 设置
  • 使用默认的 Debezium detectorbufs 插件为 PostgreSQL 设置源连接器。如果使用 PostgreSQL 的内置 pgoutput 插件,请设置 debezium.source.plugin.name=pgoutput
  • 源连接器设置为从名为 inventory 的架构捕获事件。如果要捕获数据库中的所有更改,请删除此行。否则,请更新此行以对应于您首选的架构或表。
  • 源偏移量将存储在数据目录中名为 offsets.dat 的文件中。请注意,您可能需要创建此目录以防止启动时出错。

当服务器启动时,它会生成一系列日志消息,如下所示:

__  ____  __  _____   ___  __ ____  ______
 --/ __ \/ / / / _ | / _ \/ //_/ / / / __/
 -/ /_/ / /_/ / __ |/ , _/ ,< / /_/ /\ \
--\___\_\____/_/ |_/_/|_/_/|_|\____/___/
2020-05-15 11:33:12,189 INFO  [io.deb.ser.kin.KinesisChangeConsumer] (main) Using 'io.debezium.server.kinesis.KinesisChangeConsumer$$Lambda$119/0x0000000840130c40@f58853c' stream name mapper
2020-05-15 11:33:12,628 INFO  [io.deb.ser.kin.KinesisChangeConsumer] (main) Using default KinesisClient 'software.amazon.awssdk.services.kinesis.DefaultKinesisClient@d1f74b8'
2020-05-15 11:33:12,628 INFO  [io.deb.ser.DebeziumServer] (main) Consumer 'io.debezium.server.kinesis.KinesisChangeConsumer' instantiated
2020-05-15 11:33:12,754 INFO  [org.apa.kaf.con.jso.JsonConverterConfig] (main) JsonConverterConfig values:
	converter.type = key
	decimal.format = BASE64
	schemas.cache.size = 1000
	schemas.enable = true

2020-05-15 11:33:12,757 INFO  [org.apa.kaf.con.jso.JsonConverterConfig] (main) JsonConverterConfig values:
	converter.type = value
	decimal.format = BASE64
	schemas.cache.size = 1000
	schemas.enable = false

2020-05-15 11:33:12,763 INFO  [io.deb.emb.EmbeddedEngine$EmbeddedConfig] (main) EmbeddedConfig values:
	access.control.allow.methods =
	access.control.allow.origin =
	admin.listeners = null
	bootstrap.servers = [localhost:9092]
	client.dns.lookup = default
	config.providers = []
	connector.client.config.override.policy = None
	header.converter = class org.apache.kafka.connect.storage.SimpleHeaderConverter
	internal.key.converter = class org.apache.kafka.connect.json.JsonConverter
	internal.value.converter = class org.apache.kafka.connect.json.JsonConverter
	key.converter = class org.apache.kafka.connect.json.JsonConverter
	listeners = null
	metric.reporters = []
	metrics.num.samples = 2
	metrics.recording.level = INFO
	metrics.sample.window.ms = 30000
	offset.flush.interval.ms = 0
	offset.flush.timeout.ms = 5000
	offset.storage.file.filename = data/offsets.dat
	offset.storage.partitions = null
	offset.storage.replication.factor = null
	offset.storage.topic =
	plugin.path = null
	rest.advertised.host.name = null
	rest.advertised.listener = null
	rest.advertised.port = null
	rest.extension.classes = []
	rest.host.name = null
	rest.port = 8083
	ssl.client.auth = none
	task.shutdown.graceful.timeout.ms = 5000
	topic.tracking.allow.reset = true
	topic.tracking.enable = true
	value.converter = class org.apache.kafka.connect.json.JsonConverter

2020-05-15 11:33:12,763 INFO  [org.apa.kaf.con.run.WorkerConfig] (main) Worker configuration property 'internal.key.converter' is deprecated and may be removed in an upcoming release. The specified value 'org.apache.kafka.connect.json.JsonConverter' matches the default, so this property can be safely removed from the worker configuration.
2020-05-15 11:33:12,763 INFO  [org.apa.kaf.con.run.WorkerConfig] (main) Worker configuration property 'internal.value.converter' is deprecated and may be removed in an upcoming release. The specified value 'org.apache.kafka.connect.json.JsonConverter' matches the default, so this property can be safely removed from the worker configuration.
2020-05-15 11:33:12,765 INFO  [org.apa.kaf.con.jso.JsonConverterConfig] (main) JsonConverterConfig values:
	converter.type = key
	decimal.format = BASE64
	schemas.cache.size = 1000
	schemas.enable = true

2020-05-15 11:33:12,765 INFO  [org.apa.kaf.con.jso.JsonConverterConfig] (main) JsonConverterConfig values:
	converter.type = value
	decimal.format = BASE64
	schemas.cache.size = 1000
	schemas.enable = true

2020-05-15 11:33:12,767 INFO  [io.deb.ser.DebeziumServer] (main) Engine executor started
2020-05-15 11:33:12,773 INFO  [org.apa.kaf.con.sto.FileOffsetBackingStore] (pool-3-thread-1) Starting FileOffsetBackingStore with file data/offsets.dat
2020-05-15 11:33:12,835 INFO  [io.deb.con.com.BaseSourceTask] (pool-3-thread-1) Starting PostgresConnectorTask with configuration:
2020-05-15 11:33:12,837 INFO  [io.deb.con.com.BaseSourceTask] (pool-3-thread-1)    connector.class = io.debezium.connector.postgresql.PostgresConnector
2020-05-15 11:33:12,837 INFO  [io.deb.con.com.BaseSourceTask] (pool-3-thread-1)    offset.flush.interval.ms = 0
2020-05-15 11:33:12,838 INFO  [io.deb.con.com.BaseSourceTask] (pool-3-thread-1)    database.user = postgres
2020-05-15 11:33:12,838 INFO  [io.deb.con.com.BaseSourceTask] (pool-3-thread-1)    database.dbname = postgres
2020-05-15 11:33:12,838 INFO  [io.deb.con.com.BaseSourceTask] (pool-3-thread-1)    offset.storage.file.filename = data/offsets.dat
2020-05-15 11:33:12,838 INFO  [io.deb.con.com.BaseSourceTask] (pool-3-thread-1)    database.hostname = localhost
2020-05-15 11:33:12,838 INFO  [io.deb.con.com.BaseSourceTask] (pool-3-thread-1)    database.password = ********
2020-05-15 11:33:12,839 INFO  [io.deb.con.com.BaseSourceTask] (pool-3-thread-1)    name = kinesis
2020-05-15 11:33:12,839 INFO  [io.deb.con.com.BaseSourceTask] (pool-3-thread-1)    topic.prefix = tutorial
2020-05-15 11:33:12,839 INFO  [io.deb.con.com.BaseSourceTask] (pool-3-thread-1)    database.port = 5432
2020-05-15 11:33:12,839 INFO  [io.deb.con.com.BaseSourceTask] (pool-3-thread-1)    schema.include.list = inventory
2020-05-15 11:33:12,908 INFO  [io.quarkus] (main) debezium-server 1.2.0-SNAPSHOT (powered by Quarkus 1.4.1.Final) started in 1.198s. Listening on: http://0.0.0.0:8080
2020-05-15 11:33:12,911 INFO  [io.quarkus] (main) Profile prod activated.
2020-05-15 11:33:12,911 INFO  [io.quarkus] (main) Installed features: [cdi, smallrye-health]

四、源配置

源配置使用特定连接器文档页面上描述的相同配置属性(仅带有 debezium.source 前缀),以及在 Kafka Connect 外部运行所需的一些更具体的配置属性:

属性默认值描述
debezium.source.connector.class实现源连接器的 Java 类的名称。
debezium.source.offset.storageorg.apache.kafka.connect.storage.FileOffsetBackingStore用于存储和检索非 Kafka 部署的偏移量的类。要使用 Redis 存储偏移量,请使用 io.debezium.storage.redis.offset.RedisOffsetBackingStore
debezium.source.offset.storage.file.filename如果使用文件偏移存储(默认),则为非 Kafka 部署存储连接器偏移的文件。
debezium.source.offset.flush.interval.ms定义将偏移量刷新到文件中的频率。
debezium.source.offset.storage.redis.address(可选)如果使用 Redis 存储偏移量,则为一个地址,格式为主机:端口,在该地址提供 Redis 目标流。如果未提供,将尝试读取 debezium.sink.redis.address
debezium.source.offset.storage.redis.user(可选)如果使用 Redis 存储偏移量,则用于与 Redis 通信的用户名。如果未提供 redis.address 配置,并且 redis.address 是从 Redis 接收器获取的,将尝试从 debezium.sink.redis.user 加载该值
debezium.source.offset.storage.redis.password(可选)如果使用 Redis 存储偏移量,则用于与 Redis 通信的密码(各个用户的)。如果设置了用户,则必须设置密码。如果未提供 redis.address 配置,并且 redis.address 是从 Redis 接收器获取的,则将尝试从 debezium.sink.redis.password 加载该值
debezium.source.offset.storage.redis.ssl.enabled(可选)如果使用Redis存储偏移量,是否使用SSL与Redis通信。如果未提供 redis.address 配置,并且 redis.address 是从 Redis 接收器获取的,则将尝试从 debezium.sink.redis.ssl.enabled 加载该值。默认为“假”
debezium.source.offset.storage.redis.key(可选)如果使用Redis存储偏移量,请在redis中定义哈希键。如果未提供 redis.key 配置,则默认值为metadata:debezium:offsets
debezium.source.offset.storage.redis.wait.enabledfalse如果使用 Redis 存储偏移量,则启用等待副本。如果 Redis 配置了副本分片,则可以验证数据是否已写入副本。有关详细信息,请参阅 Redis WAIT 命令。
debezium.source.offset.storage.redis.wait.timeout.ms1000如果使用 Redis 存储偏移量,则定义等待副本时的超时(以毫秒为单位)。必须具有正值。
debezium.source.offset.storage.redis.wait.retry.enabledfalse如果使用 Redis 存储偏移量,则启用等待副本失败时重试。
debezium.source.offset.storage.redis.wait.retry.delay.ms1000如果使用 Redis 存储偏移量,则定义等待副本失败时重试的延迟。
debezium.source.schema.history.internalio.debezium.storage.kafka.history.KafkaSchemaHistory一些连接器(例如 MySQL、SQL Server、Db2、Oracle)会跟踪数据库模式随时间的演变,并将这些数据存储在数据库模式历史记录中。默认情况下,这是基于 Kafka 的。还有其他可用选项:用于非 Kafka 部署的 io.debezium.storage.file.history.FileSchemaHistory用于测试环境的 io.debezium.relational.history.MemorySchemaHistory 易失性存储Redis 部署的 io.debezium.storage.redis.history.RedisSchemaHistoryRocketMQ 部署的 io.debezium.storage.redis.history.RocketMqSchemaHistory
debezium.source.schema.history.internal.file.filenameFileSchemaHistory 保存其数据的文件的名称和位置。
debezium.source.schema.history.internal.redis.address如果使用 RedisSchemaHistory,则要连接到的 Redis 主机:端口。
debezium.source.schema.history.internal.redis.password使用 RedisSchemaHistory 时要使用的 Redis 密码。
debezium.source.schema.history.internal.redis.ssl.enabled如果使用 RedisSchemaHistory,请使用 SSL 连接。
debezium.source.schema.history.internal.redis.key如果使用 RedisSchemaHistory,则用于存储的 Redis 键。默认值:元数据:debezium:schema_history
debezium.source.schema.history.internal.redis.retry.initial.delay.ms如果使用 RedisSchemaHistory,重试连接到 Redis 时的初始延迟。默认值:300(毫秒)
debezium.source.schema.history.internal.redis.retry.max.delay.ms如果使用 RedisSchemaHistory,重试连接到 Redis 时的最大延迟。默认值:10000(毫秒)
debezium.source.schema.history.internal.redis.connection.timeout.ms如果使用 RedisSchemaHistory,Redis 客户端的连接超时。默认值:2000(毫秒)
debezium.source.schema.history.internal.redis.socket.timeout.ms如果使用 RedisSchemaHistory,Redis 客户端的套接字超时。默认值:2000(毫秒)
debezium.source.schema.history.internal.redis.wait.enabledfalse如果使用 Redis 存储架构历史记录,则启用等待副本。如果 Redis 配置了副本分片,则可以验证数据是否已写入副本。有关详细信息,请参阅 Redis WAIT 命令。
debezium.source.schema.history.internal.redis.wait.timeout.ms1000如果使用 Redis 存储架构历史记录,则定义等待副本时的超时(以毫秒为单位)。必须具有正值。
debezium.source.schema.history.internal.redis.wait.retry.enabledfalse如果使用 Redis 存储架构历史记录,则启用等待副本失败时重试。
debezium.source.schema.history.internal.redis.wait.retry.delay.ms1000如果使用 Redis 存储架构历史记录,则定义等待副本失败时重试的延迟。

五、格式配置

可以为键和值分别配置消息输出格式。默认情况下,输出为 JSON 格式,但可以使用 Kafka Connect 转换器的任意实现。

属性默认值描述
debezium.format.keyjsonkey 的输出格式名称,json/jsonbytearray/avro/protobuf 之一。
debezium.format.key.*传递给密钥转换器的配置属性。
debezium.format.valuejson值的输出格式的名称,json/jsonbytearray/avro/protobuf/cloudevents 之一。
debezium.format.value.*传递给值转换器的配置属性。
debezium.format.headerjsonvalue 的输出格式名称,json/jsonbytearray 之一
debezium.format.header.*传递给标头转换器的配置属性。

六、Transformation配置

在消息被传递到接收器之前,它们可以运行一系列转换。服务器支持 Kafka Connect 定义的单个消息转换。配置需要包含转换列表、每个转换的实现类以及每个转换的配置选项。

属性默认值描述 [id=“debezium-transforms”]
debezium.transforms逗号分隔的转换符号名称列表。
debezium.transforms.<name>.type实现名称为 <name> 的转换的 Java 类的名称。
debezium.transforms.<name>.*传递给名为 <name> 的转换的配置属性。
debezium.transforms.<name>.predicate要应用于名为 <name> 的转换的谓词的名称。
debezium.transforms.<name>.negatefalse确定名称为 <name> 的转换谓词的结果是否会被否定。

七、Predicates配置

Predicates可以与转换相关联,以使转换成为可选的。服务器支持 Kafka Connect 定义的过滤器和条件 SMT。配置需要包含Predicates列表、每个Predicates的实现类以及每个Predicates的配置选项。

属性默认值描述[id=“debezium-predicates”]
debezium.predicates逗号分隔的predicates符号名称列表。
debezium.predicates.<name>.type实现名为 <name> 的predicates的 Java 类的名称。
debezium.predicates.<name>.*传递给名为 <name> 的predicates的配置属性。

八、附加配置

Debezium Server 运行在 Quarkus 框架之上。 Quarkus 公开的所有配置选项也可在 Debezium Server 中使用。最常用的是:

属性默认值描述[id=“debezium-quarkus-http-port”]
quarkus.http.port8080Debezium 公开 Microprofile Health 端点和其他公开状态信息的端口。
quarkus.log.levelINFO每个日志类别的默认日志级别。
quarkus.log.console.jsontrue确定是否启用 JSON 控制台格式化扩展,这将禁用“正常”控制台格式化。

可以通过在conf/application.properties 文件中设置quarkus.log.console.json=false 来禁用JSON 日志记录,如conf/application.properties.example 文件中所示。

九、启用消息过滤

  • Debezium Server 提供过滤 STM 功能。然而,出于安全原因,默认情况下它并未启用,并且必须在 Debezium Server 启动时显式启用。
  • 要启用它,请将环境变量 ENABLE_DEBEZIUM_SCRIPTING 设置为 true。
  • 这会将 debezium-scripting jar 文件和 JSR 223 实现(当前为 Groovy 和 graalvm.js)jar 文件添加到服务器类路径中。这些 jar 文件包含在 Debezium Server 发行版的 opt_lib 目录中。

十、接收器配置

接收器配置特定于每种接收器类型。

接收器通过配置属性 debezium.sink.type 选择。

Apache Kafka
Apache Kafka 是一个流行的分布式事件流开源平台。 Debezium Server 支持将捕获的更改事件发布到已配置的 Kafka 消息代理。

属性默认值描述
debezium.sink.type必须设置为kafka。
debezium.sink.kafka.producer.*Kafka接收器适配器支持直通配置。这意味着所有 Kafka 生产者配置属性都会传递给生产者,并删除前缀。至少必须提供 bootstrap.servers、key.serializer 和 value.serializer 属性。该主题由 Debezium 设置。

十一、扩展

Debezium Server 使用 Quarkus 框架并依赖依赖注入来使开发人员能够扩展其行为。请注意,仅支持 Quarkus 的 JVM 模式,但不支持通过 GraalVM 进行本机执行。通过提供自定义逻辑,可以通过两种方式扩展服务器:

  • 实施新sink
  • 现有sink的定制 - 即非标准配置

实施新sink
新接收器可以实现为实现接口 DebeziumEngine.ChangeConsumer 的 CDI bean,并使用注释 @Named 和唯一名称和范围 @Dependent。 bean 的名称用作 debezium.sink.type 选项。

接收器需要使用 Microprofile Config API 读取配置。执行路径必须将消息传递到目标系统并定期提交传递/处理的消息。

现有sink的定制
一些接收器公开了依赖注入点,使用户能够提供自己的 bean 来修改接收器的行为。典型的例子是目标客户端设置、目标命名等的微调。

十二、使用 Cassandra 连接器运行 Debezium Server

使用 java 11+ 运行需要在启动时通过 JDK_JAVA_OPTIONS 环境变量或等效变量设置以下 java 选项:

JDK_JAVA_OPTIONS="--add-exports java.base/jdk.internal.misc=ALL-UNNAMED --add-exports java.base/jdk.internal.ref=ALL-UNNAMED --add-exports java.base/sun.nio.ch=ALL-UNNAMED --add-exports java.management.rmi/com.sun.jmx.remote.internal.rmi=ALL-UNNAMED --add-exports java.rmi/sun.rmi.registry=ALL-UNNAMED --add-exports java.rmi/sun.rmi.server=ALL-UNNAMED --add-exports java.sql/java.sql=ALL-UNNAMED  --add-opens java.base/java.lang.module=ALL-UNNAMED --add-opens java.base/jdk.internal.loader=ALL-UNNAMED --add-opens java.base/jdk.internal.ref=ALL-UNNAMED --add-opens java.base/jdk.internal.reflect=ALL-UNNAMED --add-opens java.base/jdk.internal.math=ALL-UNNAMED --add-opens java.base/jdk.internal.module=ALL-UNNAMED --add-opens java.base/jdk.internal.util.jar=ALL-UNNAMED --add-opens jdk.management/com.sun.management.internal=ALL-UNNAMED --add-opens=java.base/java.io=ALL-UNNAMED --add-opens java.base/sun.nio.ch=ALL-UNNAMED"

用于使用 Redis 接收器运行 Cassandra 连接器的基本 application.properties 示例

# Sink
debezium.sink.type=redis
debezium.sink.redis.address=localhost:6379

# Connector
debezium.source.connector.class=io.debezium.connector.cassandra.Cassandra4Connector
## node.id must be unique per each connector running on each Cassandra node
debezium.source.cassandra.node.id=sample_node_01
debezium.source.cassandra.hosts=127.0.0.1
debezium.source.cassandra.port=9042
debezium.source.cassandra.config=/opt/cassandra/conf/cassandra.yaml
debezium.source.commit.log.relocation.dir=cassandra/relocdir
debezium.source.offset.storage=io.debezium.server.redis.RedisOffsetBackingStore
debezium.source.topic.prefix=sample_prefix
## internal Cassandra http port
debezium.source.http.port=8040

操作码转换
默认情况下,Cassandra 连接器有自己的操作代码,与 Debezium 操作代码并不完全兼容。如果需要,可以在 Debezium Server 的 application.properties 中定义特定的转换来启用转换:

debezium.transforms=EnvelopeTransformation
debezium.transforms.EnvelopeTransformation.type=io.debezium.connector.cassandra.transforms.EnvelopeTransformation

这将转换操作代码如下:

INSERT "i"          -> CREATE "c"
UPDATE "u"          -> UPDATE "u"
DELETE "d"          -> DELETE "d"
RANGE_TOMBSTONE "r" -> TRUNCATE "t"
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

最笨的羊羊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值