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.size
和max.queue.size
- 减少提交次数
增加offset.flush.timeout.ms
- 让 Connect 有时间处理累积的记录
减少offset.flush.interval.ms
- 应该减少累积的偏移量
不幸的是,有一个issue KAFKA-6551 潜伏在后台,仍然可以造成严重破坏。
【讨论】:
请注意,Debezium 的选项(max.batch.size
、max.queue.size
)必须作为连接器选项提供;将它们指定为 env 变量将不起作用(仅支持 Kafka (Connect) 定义的设置。
嗨,我正在阅读此处debezium.io/documentation/reference/assemblies/… 的文档,但我没有看到offset.flush.timeout.ms
或offset.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 连接器 - Kinesis - 服务未启动