MySQL 的 Debezium 刷新超时和 OutOfMemoryError 错误

Posted

技术标签:

【中文标题】MySQL 的 Debezium 刷新超时和 OutOfMemoryError 错误【英文标题】:Debezium flush timeout and OutOfMemoryError errors with MySQL 【发布时间】:2018-09-26 20:50:48 【问题描述】:

使用 Debezium 0.7 从 mysql 读取,但在初始快照阶段出现刷新超时和 OutOfMemoryError 错误。查看下面的日志,似乎连接器试图一次写入太多消息:

WorkerSourceTaskid=accounts-connector-0 flushing 143706 outstanding messages for offset commit   [org.apache.kafka.connect.runtime.WorkerSourceTask]
WorkerSourceTaskid=accounts-connector-0 Committing offsets   [org.apache.kafka.connect.runtime.WorkerSourceTask]
Exception in thread "RMI TCP Connection(idle)" java.lang.OutOfMemoryError: Java heap space
WorkerSourceTaskid=accounts-connector-0 Failed to flush, timed out while waiting for producer to flush outstanding 143706 messages   [org.apache.kafka.connect.runtime.WorkerSourceTask]

想知道对于大型数据库 (>50GB) 的正确设置是什么 http://debezium.io/docs/connectors/mysql/#connector-properties。对于较小的数据库,我没有这个问题。简单地增加超时似乎不是一个好策略。我目前使用的是默认连接器设置。

更新

按照以下建议更改了设置并解决了问题:

OFFSET_FLUSH_TIMEOUT_MS: 60000  # default 5000
OFFSET_FLUSH_INTERVAL_MS: 15000  # default 60000
MAX_BATCH_SIZE: 32768  # default 2048
MAX_QUEUE_SIZE: 131072  # default 8192
HEAP_OPTS: '-Xms2g -Xmx2g'  # default '-Xms1g -Xmx1g'

【问题讨论】:

【参考方案1】:

这是一个非常复杂的问题 - 首先,Debezium Docker 映像的默认内存设置非常低,因此如果您正在使用它们,可能需要增加它们。

接下来,有多种因素在起作用。我建议执行以下步骤。

    增加max.batch.sizemax.queue.size - 减少提交次数 增加offset.flush.timeout.ms - 让 Connect 有时间处理累积的记录 减少offset.flush.interval.ms - 应该减少累积的偏移量

不幸的是,有一个issue KAFKA-6551 潜伏在后台,仍然可以造成严重破坏。

【讨论】:

请注意,Debezium 的选项(max.batch.sizemax.queue.size)必须作为连接器选项提供;将它们指定为 env 变量将不起作用(仅支持 Kafka (Connect) 定义的设置。 嗨,我正在阅读此处debezium.io/documentation/reference/assemblies/… 的文档,但我没有看到offset.flush.timeout.msoffset.flush.interval.ms 配置选项。你从哪里弄来的? @lollerskates 它是一个连接工作者配置。看看这个:docs.confluent.io/current/connect/references/allconfigs.html【参考方案2】:

补充Jiri所说的:

Debezium bugtracker 中现在有一个未解决的问题,如果您有任何有关根本原因、日志或复制的更多信息,请随时在此处提供。

对我来说,更改 Jiri 在评论中提到的价值观并不能解决问题。唯一可行的解​​决方法是在同一个工作人员上创建多个连接器,每个连接器负责所有表的一个子集。为此,您需要启动连接器 1,等待快照完成,然后启动连接器 2,依此类推。在某些情况下,当较晚的连接器开始快照时,较早的连接器将无法刷新。在这些情况下,您可以在所有快照完成后重新启动工作程序,并且连接器将再次从 binlog 中获取(确保您的快照模式为“when_needed”!)。

【讨论】:

【参考方案3】:

我可以确认 Jiri Pechanec 上面发布的答案解决了我的问题。这是我正在使用的配置:

在 worker.properties 配置文件中设置的 kafka 连接工作者配置:

offset.flush.timeout.ms=60000
offset.flush.interval.ms=10000
max.request.size=10485760

Debezium 配置通过 curl 请求进行初始化:

max.queue.size = 81290
max.batch.size = 20480

我们的 staging MySQL db (~8GB) 没有遇到这个问题,因为数据集要小得多。对于生产数据集(~80GB),我们必须调整这些配置。

希望这会有所帮助。

【讨论】:

以上是关于MySQL 的 Debezium 刷新超时和 OutOfMemoryError 错误的主要内容,如果未能解决你的问题,请参考以下文章

Debezium MySQL 参数 table.exclude.list 不起作用

MySQL使用Debezium更改为Kafka-仅捕获DDL stmts

Debezium的基本使用(以MySQL为例)

Debezium - MySQL 连接器 - Kinesis - 服务未启动

在 Debezium 中无法根据 MySQL 的表创建某些主题

Debezium - 自定义负载 - MySQL 连接器