根据时间戳获取kafka的topic的偏移量,结果获取的偏移量量数据组的长度为0,就会出现如下的数组下标越界的异常,实现的原理是使用了kafka的getOffsetsBefore()方法:

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException : 0

at co.gridport.kafka.hadoop.KafkaInputFetcher.getOffset(KafkaInputFetcher.java:126)

at co.gridport.kafka.hadoop.TestKafkaInputFetcher.testGetOffset(TestKafkaInputFetcher.java:68)

at co.gridport.kafka.hadoop.TestKafkaInputFetcher.main(TestKafkaInputFetcher.java:80)

OffsetResponse(0,Map([barrage_detail,0] -> error: kafka.common.UnknownException offsets: ))

源码如下:

/*

* 得到partition的offset Finding Starting Offset for Reads

*/

public Long getOffset(Long time) throws IOException {

TopicAndPartition topicAndPartition = new TopicAndPartition(this.topic , this.partition );

Map<TopicAndPartition, PartitionOffsetRequestInfo> requestInfo = new HashMap<TopicAndPartition, PartitionOffsetRequestInfo>();

requestInfo.put( topicAndPartition, new PartitionOffsetRequestInfo(time, 1));

kafka.javaapi.OffsetRequest request = new kafka.javaapi.OffsetRequest(

requestInfo, kafka.api.OffsetRequest.CurrentVersion(), this. client_id);

OffsetResponse response = this. kafka_consumer.getOffsetsBefore( request);

if ( response.hasError()) {

log.error( "Error fetching data Offset Data the Broker. Reason: " + response.errorCode(this.topic, this. partition));

throw new IOException ( "Error fetching kafka Offset by time:" + response.errorCode(this.topic, this. partition));

}

//         if (response.offsets(this.topic, this.partition).length == 0){

//              return getOffset(kafka.api.OffsetRequest

//                         .EarliestTime());

//         }

return response.offsets( this. topic, this. partition)[0];

}

返回的response对象会有error: kafka.common.UnknownException offsets如下异常:

OffsetResponse(0,Map([barrage_detail,0] -> error: kafka.common.UnknownException offsets: ))

同时呢,response.hasError()检查不到error。

是什么原因造成了response.offsets(this.topic,this.partition)的返回数组的长度为0呢?

分析了getOffsetsBefore()方法的源码,并做源码了大量的测试,终于重现了这种情况?

1.getOffsetsBefore()的功能以及实现原理:

getOffsetsBefore的功能是返回某个时间点前的maxOffsetNum个offset(时间点指的是kafka日志文件的最后修改时间,offset指的是log文件名中的offset,这个offset是该日志文件的第一条记录的offset,即base offset;maxNumOffsets参数即返回结果的最大个数,如果该参数为2,就返回指定时间点前的2个offset,如果是负数,就报逻辑错误,怎么能声明一个长度为负数的数组呢,呵呵);

根据这个实现原理,所以返回的结果长度为0是合理的,反映的是这个时间点前没有kafka日志这种情况,该情况自然就没有offset了。

说明我们指定的时间参数太早了,正常的时间范围为:最早的时间之后的时间参数都可以有返回值。

其实合理的处理方式应该为如果这个时间点前没有值,就返回最早的offset了,对api的使用者就友好多了我们可以自己来实现这个功能。

代码如下:

/*

* 得到partition的offset Finding Starting Offset for Reads

*/

public Long getOffset(Long time ) throws IOException {

TopicAndPartition topicAndPartition = new TopicAndPartition(this .topic , this.partition);

Map<TopicAndPartition, PartitionOffsetRequestInfo> requestInfo = new HashMap<TopicAndPartition, PartitionOffsetRequestInfo>();

requestInfo.put( topicAndPartition, new PartitionOffsetRequestInfo(time, 1));

kafka.javaapi.OffsetRequest request = new kafka.javaapi.OffsetRequest(

requestInfo, kafka.api.OffsetRequest.CurrentVersion(), this. client_id);

OffsetResponse response = this. kafka_consumer.getOffsetsBefore( request);

if ( response.hasError()) {

log.error( "Error fetching data Offset Data the Broker. Reason: " + response.errorCode(this.topic, this. partition));

throw new IOException ( "Error fetching kafka Offset by time:" + response.errorCode(this.topic, this. partition));

}

//如果返回的数据长度为0,就获取最早的offset。

if ( response.offsets( this. topic, this. partition). length == 0){

return getOffset(kafka.api.OffsetRequest

. EarliestTime());

}

return response.offsets( this. topic, this. partition)[0];

}

kafka使用getOffsetsBefore()获取获取offset异常分析的更多相关文章

  1. python使用traceback获取详细的异常信息

    原创来自:https://blog.csdn.net/mengtao0609/article/details/55049059 python使用traceback获取详细的异常信息 2017年02月1 ...

  2. Redisson分布式锁学习总结:可重入锁 RedissonLock#lock 获取锁源码分析

    原文:Redisson分布式锁学习总结:可重入锁 RedissonLock#lock 获取锁源码分析 一.RedissonLock#lock 源码分析 1.根据锁key计算出 slot,一个slot对 ...

  3. Kafka+SparkStreaming+Zookeeper(ZK存储Offset,解决checkpoint问题)

    创建一个topic ./kafka-topics.sh --create --zookeeper 192.168.1.244:2181,192.168.1.245:2181,192.168.1.246 ...

  4. kafka C客户端librdkafka producer源码分析

    from:http://www.cnblogs.com/xhcqwl/p/3905412.html kafka C客户端librdkafka producer源码分析 简介 kafka网站上提供了C语 ...

  5. Android异常分析(转)

    关于异常 异常? 异常就是一种程序中没有预料到的问题,既然是没有预料到的,就可能不在原有逻辑处理范围内,脱离了代码控制,软件可能会出现各种奇怪的现象.比如:android系统常见异常现象有应用无响应. ...

  6. 4种Kafka网络中断和网络分区场景分析

    摘要:本文主要带来4种Kafka网络中断和网络分区场景分析. 本文分享自华为云社区<Kafka网络中断和网络分区场景分析>,作者: 中间件小哥. 以Kafka 2.7.1版本为例,依赖zk ...

  7. Canal 同步异常分析:Could not find first log file name in binary log index file

    文章首发于[博客园-陈树义],点击跳转到原文Canal同步异常分析:Could not find first log file name in binary log index file. 公司搜索相 ...

  8. Kafka文件存储机制及offset存取

    Kafka是什么 Kafka是最初由Linkedin公司开发,是一个分布式.分区的.多副本的.多订阅者,基于zookeeper协调的分布式日志系统(也可以当做MQ系统),常见可以用于web/nginx ...

  9. Linux Kernel Oops异常分析

    1.PowerPC小系统内核异常分析 1.1  异常打印 Unable to handle kernel paging request for data at address 0x36fef31eFa ...

随机推荐

  1. C语言数据类型取值范围

    一.获取数据类型在系统中的位数 在不同的系统中,数据类型的字节数(bytes)不同,位数(bits)也有所不同,那么对应的取值范围也就有了很大的不同,那我们怎么知道你当前的系统中C语言的某个数据类型的 ...

  2. Hive:常用的一些命令

    1.一般可以通过beeline,代理方式登录hive; 2.使用数据库abc_hive_db:use abc_hive_db; 3.查看数据库中有哪些表:show tables :有哪些特定表 sho ...

  3. Spring

    Spring 一个支持DI/IOC和AOP的开源容器框架 特点 DI/IOC DI 依赖注入(组件以特定方式接收来自容器的资源注入) IOC 控制反转(反转资源获取的方向) AOP 面向切面编程 开发 ...

  4. 前端forEach在Array、map、set中的使用

    数组: var s = ['a','b','c']; s.forEach(function(ele,index,array){ console.log(ele); }); Map: var map = ...

  5. Java绘图

    paintComponent(Graphics g)方法: 1.不调用super.paintComponent(g)的话,rePaint()的时候就会把你写的paintComponent中的内容绘制上 ...

  6. 利用zlib库进行zip解压

    1:到zlib官网上下载zlib,本文下载的是1.2.8的版本. 2:进行./configure,然后make. 3:进入zlib库中的contrib/minizip/路径下make,生成的miniz ...

  7. Android--带你一点点封装项目 MVP+BaseActivity+Retrofit+Dagger+RxJava(一)

    1,其实早就想把这些东西给封装封装的,一直没有时间,今天刚好项目进入到测试阶段了,Bug同事在哪儿测试的飞起,但发现提bug的尽然是我(得意脸),然后上午把ios的包测试了一下,顺便把服务器给测挂了( ...

  8. Find cmd

    Find cmd with python programing python at page320 Unix find cmd: find . -name "*.py " -pri ...

  9. NODEJS 在Centos下面的自动启动

    直接上代码 #!/bin/sh ## chkconfig: 345 99 10# description: Node.js /home/cekimy/index.js# . /etc/rc.d/ini ...

  10. [Struts2] Action Implements SessionAware

    struts2 的Action中若希望访问Session对象,可采用两种方式: 1.从ActionContext中获取: 2.实现SessionAware接口. 1.从ActionContext中获取 ...