我目前正在与Kafka Connect S3 Sink Connector 3.3.1一起将Kafka消息复制到S3,处理后期数据时出现OutOfMemory错误。
我知道这似乎是一个很长的问题,但是我尽力使它变得清晰和易于理解。 非常感谢您的帮助。
CustomByteArrayFormat
类的角色(请参见下面的配置)Record
时间戳对数据进行分区和存储
CustomTimeBasedPartitioner
扩展了io.confluent.connect.storage.partitioner.TimeBasedPartitioner
,其唯一目的是覆盖generatePartitionedPath
方法以将主题放在路径的末尾。timestamp.extractor
配置设置为Record
Wallclock
(即Kafka Connect进程的时间)请勿抛出OOM错误,并且可以处理所有最新数据,但不再正确存储最新数据
YYYY/MM/dd/HH/mm/topic-name
时间段内存储。Record
时间戳正确存储数据时,它执行的并行读取过多,导致OOM错误
"partition.duration.ms": "600000"
参数使连接器存储桶数据以每小时6个10分钟的路径进行传输(2018/06/20/12/[00|10|20|30|40|50]
适用于2018年6月20日中午12点)24h * 6 = 144
个不同的S3路径中输出数据。"flush.size": "100000"
表示,如果有100,000条以上的消息被读取,则应将它们提交到文件中(从而释放内存)。
"flush.size"
是要每个分区读取的记录数吗?还是每个连接器的任务?"rotate.schedule.interval.ms": "600000"
配置的方式是,即使未达到flush.size
的100,000条消息,数据也将每10分钟提交一次。我的主要问题是,给出给定的内存使用量的数学运算是什么:
"partition.duration.ms": "600000"
配置)S3接收器连接器配置
{
"name": "xxxxxxx",
"config": {
"connector.class": "io.confluent.connect.s3.S3SinkConnector",
"s3.region": "us-east-1",
"partition.duration.ms": "600000",
"topics.dir": "xxxxx",
"flush.size": "100000",
"schema.compatibility": "NONE",
"topics": "xxxxxx,xxxxxx",
"tasks.max": "16",
"s3.part.size": "52428800",
"timezone": "UTC",
"locale": "en",
"format.class": "xxx.xxxx.xxx.CustomByteArrayFormat",
"partitioner.class": "xxx.xxxx.xxx.CustomTimeBasedPartitioner",
"schema.generator.class": "io.confluent.connect.storage.hive.schema.DefaultSchemaGenerator",
"name": "xxxxxxxxx",
"storage.class": "io.confluent.connect.s3.storage.S3Storage",
"s3.bucket.name": "xxxxxxx",
"rotate.schedule.interval.ms": "600000",
"path.format": "YYYY/MM/dd/HH/mm",
"timestamp.extractor": "Record"
}
工作人员配置
bootstrap.servers=XXXXXX
key.converter=org.apache.kafka.connect.converters.ByteArrayConverter
value.converter=org.apache.kafka.connect.converters.ByteArrayConverter
internal.key.converter=org.apache.kafka.connect.json.JsonConverter
internal.value.converter=org.apache.kafka.connect.json.JsonConverter
internal.key.converter.schemas.enable=false
internal.value.converter.schemas.enable=false
consumer.auto.offset.reset=earliest
consumer.max.partition.fetch.bytes=2097152
consumer.partition.assignment.strategy=org.apache.kafka.clients.consumer.RoundRobinAssignor
group.id=xxxxxxx
config.storage.topic=connect-configs
offset.storage.topic=connect-offsets
status.storage.topic=connect-status
rest.advertised.host.name=XXXX
修改:
我忘记添加我遇到的错误的示例:
2018-06-21 14:54:48,644] ERROR Task XXXXXXXXXXXXX-15 threw an uncaught and unrecoverable exception (org.apache.kafka.connect.runtime.WorkerSinkTask:482)
java.lang.OutOfMemoryError: Java heap space
[2018-06-21 14:54:48,645] ERROR Task is being killed and will not recover until manually restarted (org.apache.kafka.connect.runtime.WorkerSinkTask:483)
[2018-06-21 14:54:48,645] ERROR Task XXXXXXXXXXXXXXXX-15 threw an uncaught and unrecoverable exception (org.apache.kafka.connect.runtime.WorkerTask:148)
org.apache.kafka.connect.errors.ConnectException: Exiting WorkerSinkTask due to unrecoverable exception.
at org.apache.kafka.connect.runtime.WorkerSinkTask.deliverMessages(WorkerSinkTask.java:484)
at org.apache.kafka.connect.runtime.WorkerSinkTask.poll(WorkerSinkTask.java:265)
at org.apache.kafka.connect.runtime.WorkerSinkTask.iteration(WorkerSinkTask.java:182)
at org.apache.kafka.connect.runtime.WorkerSinkTask.execute(WorkerSinkTask.java:150)
at org.apache.kafka.connect.runtime.WorkerTask.doRun(WorkerTask.java:146)
at org.apache.kafka.connect.runtime.WorkerTask.run(WorkerTask.java:190)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
答案 0 :(得分:4)
我终于能够理解Kafka Connect S3连接器中堆大小用法的工作原理
paths
paths
的分区方式取决于partitioner.class
参数; partition.duration.ms
的值将确定每个已分区的 paths
的持续时间。s3.part.size
分配paths
个字节的缓冲区
timestamp.extractor
设置为Record
,将partition.duration.ms
设置为1h,将s3.part.size
设置为50 MB
20 * 50 MB
= 1 GB; timestamp.extractor
设置为Record
时,具有对应于早于其读取时间的小时的时间戳的消息将被缓冲在此较早的时间缓冲区中。因此,实际上,连接器将需要最少20 * 50 MB * 2h
= 2 GB的内存,因为总会出现延迟的事件,而如果事件的延迟时间超过1小时,则连接器将需要更多的内存; timestamp.extractor
设置为Wallclock
,则情况并非如此,因为就Kafka Connect而言,几乎不会发生迟发事件。rotate.schedule.interval.ms
时间过去了
rotate.interval.ms
时间过去了 timestamp.extractor
时间
timestamp.extractor
设置为Record
,则Record
的10分钟时间可能会减少或超过10分钟的实际时间
rotate.interval.ms
设置为10分钟,则此条件将每秒触发一次(应有的时间); < / li>
rotate.interval.ms
时,该条件才会触发。flush.size
条消息的读取时间少于min(rotate.schedule.interval.ms
,rotate.interval.ms)
rotate.interval.ms
,如果没有足够的消息,这种情况可能永远不会触发。Kafka partitions * s3.part.size
堆大小
Record
时间戳进行分区,则应将其乘以max lateness in milliseconds / partition.duration.ms
max lateness in milliseconds
的所有范围中都经常发生延迟事件。consumer.max.partition.fetch.bytes
个字节