Scala 将应用程序从卡夫卡0.8.2.1移植到卡夫卡0.9.0。阅读补偿问题
我们遇到了一个与应用程序代码从Apache Kafka的0.8.2.1版迁移到0.9.0.0版相关的问题 在本例中,我们指的是Cloudera发布的卡夫卡版本: 卡夫卡2.10-0.8.2.0-1.3.2 卡夫卡2.11-0.9.0-2.0.2 我们在读取和写入uu consumer_offset元数据主题上的偏移量时检测到了问题。 特别是,我们使用BlockingChannel连接到Kafka代理,在receive()方法调用时,我们得到一个EOFEException 特别是:Scala 将应用程序从卡夫卡0.8.2.1移植到卡夫卡0.9.0。阅读补偿问题,scala,apache-spark,apache-kafka,kafka-consumer-api,Scala,Apache Spark,Apache Kafka,Kafka Consumer Api,我们遇到了一个与应用程序代码从Apache Kafka的0.8.2.1版迁移到0.9.0.0版相关的问题 在本例中,我们指的是Cloudera发布的卡夫卡版本: 卡夫卡2.10-0.8.2.0-1.3.2 卡夫卡2.11-0.9.0-2.0.2 我们在读取和写入uu consumer_offset元数据主题上的偏移量时检测到了问题。 特别是,我们使用BlockingChannel连接到Kafka代理,在receive()方法调用时,我们得到一个EOFEException 特别是: java.io
java.io.EOFException
at org.apache.kafka.common.network.NetworkReceive.readFromReadableChannel (NetworkReceive.java:83)
at kafka.network.BlockingChannel.readCompletely (BlockingChannel.scala: 129)
at kafka.network.BlockingChannel.receive (BlockingChannel.scala: 120)
一个可能的原因可能是卡夫卡API的两个版本之间的差异
卡夫卡0.8.2
在我们的应用程序中,我们调用
ConsumerMetadataResponse.readFrom(channel.receive().buffer())
接收方法如下所示
def receive(): Receive = {
if(!connected)
throw new ClosedChannelException()
val response = new BoundedByteBufferReceive()
response.readCompletely(readChannel)
response
}
def receive(): NetworkReceive = {
if(!connected)
throw new ClosedChannelException()
val response = readCompletely(readChannel)
response.payload().rewind()
response
}
private def readCompletely(channel: ReadableByteChannel): NetworkReceive = {
val response = new NetworkReceive
while (!response.complete())
response.readFromReadableChannel(channel)
response
}
如我们所见,它返回一个kafka.network.Receive,这是扩展trait kafka.network.Transmission的trait。
在此接收中,缓冲区方法存在并在kafka.network.BoundedByteBufferReceive中被重写
def buffer: ByteBuffer = {
expectComplete()
contentBuffer
}
卡夫卡0.9.0
我们把前一行改为
GroupCoordinatorResponse.readFrom(channel.receive().payload())
此版本API中的receive方法如下
def receive(): Receive = {
if(!connected)
throw new ClosedChannelException()
val response = new BoundedByteBufferReceive()
response.readCompletely(readChannel)
response
}
def receive(): NetworkReceive = {
if(!connected)
throw new ClosedChannelException()
val response = readCompletely(readChannel)
response.payload().rewind()
response
}
private def readCompletely(channel: ReadableByteChannel): NetworkReceive = {
val response = new NetworkReceive
while (!response.complete())
response.readFromReadableChannel(channel)
response
}
如我们所见,这将返回一个kafka.network.NetworkReceive,它是一个实现接口kafka.network.Receive的类,该接口现在是用java编写的,与前面的接口完全不同。
这里没有buffer方法,只有一个payload方法返回
private ByteBuffer buffer;
我们怎么解决呢?
提前感谢卡夫卡0.9维护旧卡夫卡消费者,以实现与卡夫卡0.8.2的向后兼容性。 您正在使用Kafka 0.9中仍然存在的旧使用者来读取来自Kafka 0.9的消息。 您应该开始使用Kafka 0.9的新消费者API从Kafka 0.9代理读取数据 希望这有帮助