Scala 将应用程序从卡夫卡0.8.2.1移植到卡夫卡0.9.0。阅读补偿问题

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

我们遇到了一个与应用程序代码从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.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代理读取数据

希望这有帮助