最近公司的zk的down掉了,  storm job 重启的时候报出 kafka.common.OffsetOutOfRangeException 异常

网上查询了一些朋友的做法, 自己也看了一下代码, 最终还是解决了

原因:

zk挂掉的这几天, kafka中之前的数据已经被清掉了, 但是zk中保存的offset还是几天之前的, 导致KafkaSpout要获取的offset超过了当前kafka的offset, 就像ArrayIndexOutOfRangeException一样

解决方案:

KafkaSpout 配置项中可以选择读取的方式, 共有三种, 如果Topology启动的时候未进行配置, 则默认是从Zk中读取, 所以导致了异常

-2: 从最老的开始读

-1: 从最近的开始读

0: 从Zk中读

相关代码如下, storm.kafka.PartitionManager,

public PartitionManager(DynamicPartitionConnections connections, String topologyInstanceId, ZkState state, Map stormConf, SpoutConfig spoutConfig, GlobalPartitionId id) {
        _partition = id;
        _connections = connections;
        _spoutConfig = spoutConfig;
        _topologyInstanceId = topologyInstanceId;
        _consumer = connections.register(id.host, id.partition);
    _state = state;
        _stormConf = stormConf;         String jsonTopologyId = null;
        Long jsonOffset = null;
        try {
            Map<Object, Object> json = _state.readJSON(committedPath());
            if(json != null) {
                jsonTopologyId = (String)((Map<Object,Object>)json.get("topology")).get("id");
                jsonOffset = (Long)json.get("offset");
            }
        }
        catch(Throwable e) {
            LOG.warn("Error reading and/or parsing at ZkNode: " + committedPath(), e);
        }         if(!topologyInstanceId.equals(jsonTopologyId) && spoutConfig.forceFromStart) {
            _committedTo = _consumer.getOffsetsBefore(spoutConfig.topic, id.partition, spoutConfig.startOffsetTime, 1)[0];
        LOG.info("Using startOffsetTime to choose last commit offset.");
        } else if(jsonTopologyId == null || jsonOffset == null) { // failed to parse JSON?
            _committedTo = _consumer.getOffsetsBefore(spoutConfig.topic, id.partition, -1, 1)[0];
        LOG.info("Setting last commit offset to HEAD.");
        } else {
            _committedTo = jsonOffset;
        LOG.info("Read last commit offset from zookeeper: " + _committedTo);
        }         LOG.info("Starting Kafka " + _consumer.host() + ":" + id.partition + " from offset " + _committedTo);
        _emittedToOffset = _committedTo;

}

重点关注红色代码, spoutConfig.forceFromStart 为true的时候, 才会真正去读取自己设置的offset, 否则将会使用Zk中的offset

那么问题来了, 如何设置呢,  SpoutConfig很贴心的给我们提供了一个方法

public void forceStartOffsetTime(long millis) {
        startOffsetTime = millis;
        forceFromStart = true;

}

所以我们只需要在我们的Topology中添加如下代码即可

/* -2=最老 -1=最新, 0=zk offset*/
        if (args != null && args[1] != null && Integer.valueOf(args[1]) != 0) {
            if (Integer.valueOf(args[1]) == -2) {
                spoutConfig.forceStartOffsetTime(-2); //从kafka最老的记录读取
            } else if (Integer.valueOf(args[1]) == -1) {
                spoutConfig.forceStartOffsetTime(-1); //从kafka最新的记录读取
            }//其他情况则默认从zk的offset读取

}

发布Topology的时候, 如果需要从最新记录读取, 则像这样  storm jar com.abc.StormTopology stormTopology -1

其他链接:  http://blog.csdn.net/baiyangfu_love/article/details/8919699

Kafka kafka.common.OffsetOutOfRangeException 问题处理的更多相关文章

  1. [Kafka] - Kafka Java Consumer实现(一)

    Kafka提供了两种Consumer API,分别是:High Level Consumer API 和 Lower Level Consumer API(Simple Consumer API) H ...

  2. [Spark][kafka]kafka 生产者,消费者 互动例子

    [Spark][kafka]kafka 生产者,消费者 互动例子 # pwd/usr/local/kafka_2.11-0.10.0.1/bin 创建topic:# ./kafka-topics.sh ...

  3. [Kafka] - Kafka Java Consumer实现(二)

    Kafka提供了两种Consumer API,分别是:High Level Consumer API 和 Lower Level Consumer API(Simple Consumer API) H ...

  4. Zookeeper与Kafka Kafka

    Zookeeper与Kafka Kafka Kafka SocketServer是基于Java NIO开发的,采用了Reactor的模式(已被大量实践证明非常高效,在Netty和Mina中广泛使用). ...

  5. Kafka启动遇到ERROR Exiting Kafka due to fatal exception (kafka.Kafka$)

    ------------恢复内容开始------------ Kafka启动遇到ERROR Exiting Kafka due to fatal exception (kafka.Kafka$) 解决 ...

  6. 关于kafka定期清理日志后再消费报错kafka.common.OffsetOutOfRangeException的解决

    环境: kafka  0.10 spark  2.1.0 zookeeper  3.4.5-cdh5.14.0 公司阿里云测试机,十月一放假前,没有在继续消费,假期过后回来再使用spark strea ...

  7. Kafka – kafka consumer

    ConsumerRecords<String, String> records = consumer.poll(100);   /** * Fetch data for the topic ...

  8. [Kafka] - Kafka基本概念介绍

    Kafka官方介绍:Kafka是一个分布式的流处理平台(0.10.x版本),在kafka0.8.x版本的时候,kafka主要是作为一个分布式的.可分区的.具有副本数的日志服务系统(Kafka™ is ...

  9. [Kafka] - Kafka 安装介绍

    Kafka是由LinkedIn公司开发的,之后贡献给Apache基金会,成为Apache的一个顶级项目,开发语言为Scala.提供了各种不同语言的API,具体参考Kafka的cwiki页面: Kafk ...

随机推荐

  1. eclipse安装Memory Analyzer

    转载:http://blog.csdn.net/lindir/article/details/8743610 2个月没有写博客了,最近一直在考虑自己未来的方向,再加上项目较紧,一直未更新.今天想着要好 ...

  2. 23. Spring Boot启动加载数据CommandLineRunner【从零开始学Spring Boot】

    转:http://blog.csdn.net/linxingliang/article/details/52069503 实际应用中,我们会有在项目服务启动的时候就去加载一些数据或做一些事情这样的需求 ...

  3. 转:RC复位电路的原理及其复位时间的计算

    RC复位电路的原理及其复位时间的计算   低电平有效复位电路如下 此复位电路是针对低电平有效复位而言的,其中二极管是起着在断电的情况下能够很快的将电容两端的电压释放掉,为下次上电复位准备. 假设电容两 ...

  4. Android 开发资源

    0x00 Android 入门资料 a. Android 学习之路 b.<第一行代码> 介绍及购买链接:http://blog.csdn.net/guolin_blog/article/d ...

  5. SpringMVC hibernate增加多数据源 (SSHE/SYPRO增加多数据源为例)

    SpringMVC hibernate增加多数据源 (以类SSHE/SYPRO增加多数据源为例作说明) 注:适用与SpringMVC + Hibernate的项目.其它框架的仅仅能说作參考用 配置Sp ...

  6. 一文了解@Conditional注解说明和使用

    ​ @Conditional:Spring4.0 介绍了一个新的注解@Conditional,它的逻辑语义可以作为"If-then-else-"来对bean的注册起作用. @Con ...

  7. 【C/C++】高亮C++中函数的重写——函数名相同?参数列表相同?返回值相同?

    C++的重载给人留下了非常深刻的影响,原因是重载的条件很值得注意:函数名相同,参数列表不相同的两个函数构成重载函数,而无关乎二者的返回值. 但是C++中的函数重写又是另一码事.标准规定:只要函数名相同 ...

  8. HDFS源码分析心跳汇报之数据块汇报

    在<HDFS源码分析心跳汇报之数据块增量汇报>一文中,我们详细介绍了数据块增量汇报的内容,了解到它是时间间隔更长的正常数据块汇报周期内一个smaller的数据块汇报,它负责将DataNod ...

  9. Centos 7.0设置静态IP

    1.查看NetworkManager.service systemctl | grep "NetworkManager.service" 2.停止NetworkManager.se ...

  10. MySQL常见的数据类型(八)

    不多说,直接上干货! MySQL常见的数据类型 一.数据类型是什么? 数据类型是指列.存储过程参数.表达式和局部变量的数据特征,它决定了数据的存储格式,代表了不同的信息类型. 有一些数据是要存储为数字 ...