我正在使用DSL API编写Kafka Streams应用程序,该API将读取kafka主题中的元组。在拓扑中,我要批处理元组。然后,如果(1)30秒过去了,或者(2)批处理的大小超过1 GB,那么我想将浴写入磁盘上的文件中。
我用TimeWindowedKStream编写的拓扑组元组。然后调用聚合并传递窗口存储。
我的问题是,当状态存储尝试写入Kafka ChangeLog时,我得到了
org.apache.kafka.common.errors.RecordTooLargeException
例外。
尤其是:
起因:org.apache.kafka.streams.errors.StreamsException:任务 [1_1]由于先前记录(键)捕获了错误,因此中止发送 \ x00 \ x00 \ x00 \ x06 \ x00 \ x00 \ x01h $ \ xE7 \ x88 \ x00 \ x00 \ x00 \ x00值 [B @ 419761c时间戳记1546807396524) ibv2-capt-consumer-group-3-record-store-changelog由于 org.apache.kafka.common.errors.RecordTooLargeException:请求 包含大于服务器将允许的最大邮件大小的邮件 接受..
我曾尝试将CACHE_MAX_BYTES_BUFFERING_CONFIG
设置为1MB,但由于文档指出此配置是否适用于整个拓扑。
这是我的拓扑
这是我一直在使用的Scala代码。请注意,我在这里使用kafka-streams-scala。
val builder = new StreamsBuilderS()
import com.lightbend.kafka.scala.streams.DefaultSerdes._
implicit val recordSerde = (new RecordSerde).asInstanceOf[Serde[Record]]
implicit val recordSeqSerde = (new RecordSeqSerde).asInstanceOf[Serde[RecordSeq]]
val inputStream: KStreamS[String, Record] = builder.stream[String,Record](topic)
val keyed = inputStream.selectKey[Int]((k,r) => random.nextInt(10))
val grouped: TimeWindowedKStreamS[Int, Record] = keyed.groupByKey.windowedBy(TimeWindows.of(TimeUnit.SECONDS.toMillis(30L)))
import org.apache.kafka.common.utils.Bytes
val windowedStore: Materialized[Int, RecordSeq, WindowStore[Bytes, Array[Byte]]] = Materialized
.as[Int,RecordSeq,WindowStore[Bytes, Array[Byte]]]("record-store")
.withKeySerde(integerSerde)
.withValueSerde(recordSeqSerde)
.withLoggingEnabled(ChangeLogConfig.getChangeLogConfig.asJava) // increased max.request.size to 10 x default
val records: KTableS[Windowed[Int], RecordSeq] = grouped.aggregate(
() => RecordSeq(Seq()),
(randon: Int, record: Record, recordSeq: RecordSeq) => RecordSeq(recordSeq.records :+ record),
windowedStore
)
val recordSeqStream: KStreamS[String, RecordSeq] = records.toStream((ws, r) => s"${ws.key()}-${ws.window().start()}-${ws.window().end()}")
recordSeqStream.foreach((k: String, rs: RecordSeq) => WrappedRecordFileWriter.write(k, rs))
注意:案例类RecordSeq(records:Seq [Record])
答案 0 :(得分:1)
主题可以具有message.max.bytes
属性中定义的最大大小的记录。这是代理可以接收并附加在主题中的最大消息大小。您的记录大小可能超过了该限制。因此,您需要更改此属性的配置以允许更大的记录大小。
可以在代理级别以及主题级别进行设置。您可以在此处参考更多详细信息: