kafka使用getOffsetsBefore()获取获取offset异常分析
根据时间戳获取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异常分析的更多相关文章
- python使用traceback获取详细的异常信息
原创来自:https://blog.csdn.net/mengtao0609/article/details/55049059 python使用traceback获取详细的异常信息 2017年02月1 ...
- Redisson分布式锁学习总结:可重入锁 RedissonLock#lock 获取锁源码分析
原文:Redisson分布式锁学习总结:可重入锁 RedissonLock#lock 获取锁源码分析 一.RedissonLock#lock 源码分析 1.根据锁key计算出 slot,一个slot对 ...
- 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 ...
- kafka C客户端librdkafka producer源码分析
from:http://www.cnblogs.com/xhcqwl/p/3905412.html kafka C客户端librdkafka producer源码分析 简介 kafka网站上提供了C语 ...
- Android异常分析(转)
关于异常 异常? 异常就是一种程序中没有预料到的问题,既然是没有预料到的,就可能不在原有逻辑处理范围内,脱离了代码控制,软件可能会出现各种奇怪的现象.比如:android系统常见异常现象有应用无响应. ...
- 4种Kafka网络中断和网络分区场景分析
摘要:本文主要带来4种Kafka网络中断和网络分区场景分析. 本文分享自华为云社区<Kafka网络中断和网络分区场景分析>,作者: 中间件小哥. 以Kafka 2.7.1版本为例,依赖zk ...
- 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. 公司搜索相 ...
- Kafka文件存储机制及offset存取
Kafka是什么 Kafka是最初由Linkedin公司开发,是一个分布式.分区的.多副本的.多订阅者,基于zookeeper协调的分布式日志系统(也可以当做MQ系统),常见可以用于web/nginx ...
- Linux Kernel Oops异常分析
1.PowerPC小系统内核异常分析 1.1 异常打印 Unable to handle kernel paging request for data at address 0x36fef31eFa ...
随机推荐
- C语言数据类型取值范围
一.获取数据类型在系统中的位数 在不同的系统中,数据类型的字节数(bytes)不同,位数(bits)也有所不同,那么对应的取值范围也就有了很大的不同,那我们怎么知道你当前的系统中C语言的某个数据类型的 ...
- Hive:常用的一些命令
1.一般可以通过beeline,代理方式登录hive; 2.使用数据库abc_hive_db:use abc_hive_db; 3.查看数据库中有哪些表:show tables :有哪些特定表 sho ...
- Spring
Spring 一个支持DI/IOC和AOP的开源容器框架 特点 DI/IOC DI 依赖注入(组件以特定方式接收来自容器的资源注入) IOC 控制反转(反转资源获取的方向) AOP 面向切面编程 开发 ...
- 前端forEach在Array、map、set中的使用
数组: var s = ['a','b','c']; s.forEach(function(ele,index,array){ console.log(ele); }); Map: var map = ...
- Java绘图
paintComponent(Graphics g)方法: 1.不调用super.paintComponent(g)的话,rePaint()的时候就会把你写的paintComponent中的内容绘制上 ...
- 利用zlib库进行zip解压
1:到zlib官网上下载zlib,本文下载的是1.2.8的版本. 2:进行./configure,然后make. 3:进入zlib库中的contrib/minizip/路径下make,生成的miniz ...
- Android--带你一点点封装项目 MVP+BaseActivity+Retrofit+Dagger+RxJava(一)
1,其实早就想把这些东西给封装封装的,一直没有时间,今天刚好项目进入到测试阶段了,Bug同事在哪儿测试的飞起,但发现提bug的尽然是我(得意脸),然后上午把ios的包测试了一下,顺便把服务器给测挂了( ...
- Find cmd
Find cmd with python programing python at page320 Unix find cmd: find . -name "*.py " -pri ...
- NODEJS 在Centos下面的自动启动
直接上代码 #!/bin/sh ## chkconfig: 345 99 10# description: Node.js /home/cekimy/index.js# . /etc/rc.d/ini ...
- [Struts2] Action Implements SessionAware
struts2 的Action中若希望访问Session对象,可采用两种方式: 1.从ActionContext中获取: 2.实现SessionAware接口. 1.从ActionContext中获取 ...