KafkaSpout分析:配置
public KafkaSpout(SpoutConfig spoutConf) {
_spoutConfig = spoutConf;
}
基于0.93版本的Storm
SpoutConfig继承自KafkaConfig。由于SpoutConfig和KafkaConfig所有的instance field全是public, 因此在使用构造方法后,可以直接设置各个域的值。
public class SpoutConfig extends KafkaConfig implements Serializable {
public List<String> zkServers = null; //记录Spout读取进度所用的zookeeper的host
public Integer zkPort = null;//记录进度用的zookeeper的端口
public String zkRoot = null;//进度信息记录于zookeeper的哪个路径下
public String id = null;//进度记录的id,想要一个新的Spout读取之前的记录,应把它的id设为跟之前的一样。
public long stateUpdateIntervalMs = 2000;//多久往Zookeeper记录一次进度。
public SpoutConfig(BrokerHosts hosts, String topic, String zkRoot, String id) {
super(hosts, topic);
this.zkRoot = zkRoot;
this.id = id;
}
}
public class KafkaConfig implements Serializable {
public final BrokerHosts hosts; //用以获取Kafka broker和partition的信息
public final String topic;//从哪个topic读取消息
public final String clientId; // SimpleConsumer所用的client id
public int fetchSizeBytes = 1024 * 1024; //发给Kafka的每个FetchRequest中,用此指定想要的response中总的消息的大小
public int socketTimeoutMs = 10000;//与Kafka broker的连接的socket超时时间
public int fetchMaxWait = 10000; //当服务器没有新消息时,消费者会等待这些时间
public int bufferSizeBytes = 1024 * 1024;//SimpleConsumer所使用的SocketChannel的读缓冲区大小
public MultiScheme scheme = new RawMultiScheme();//从Kafka中取出的byte[],该如何反序列化
public boolean forceFromStart = false;//是否强制从Kafka中offset最小的开始读起
public long startOffsetTime = kafka.api.OffsetRequest.EarliestTime();//从何时的offset时间开始读,默认为最旧的offset
public long maxOffsetBehind = Long.MAX_VALUE;//KafkaSpout读取的进度与目标进度相差多少,相差太多,Spout会丢弃中间的消息
public boolean useStartOffsetTimeIfOffsetOutOfRange = true;//如果所请求的offset对应的消息在Kafka中不存在,是否使用startOffsetTime
public int metricsTimeBucketSizeInSecs = 60;//多长时间统计一次metrics
public KafkaConfig(BrokerHosts hosts, String topic) {
this(hosts, topic, kafka.api.OffsetRequest.DefaultClientId());
}
public KafkaConfig(BrokerHosts hosts, String topic, String clientId) {
this.hosts = hosts;
this.topic = topic;
this.clientId = clientId;
}
}
对Zookeeper的使用
KafkaSpout的配置中有两个地方可以用到Zookeeper
- 用Zookeeper来记录KafkaSpout的处理进度,在topology重新提交或者task重启后继续之前的处理进度。在SpoutConfig中的zkServers, zkPort和zkRoot与此相关。如果zkServer和zkPort没有设置,那么KafkaSpout会使用Storm集群所用的Zookeeper记录这些信息。
- 用Zookeeper来获取Kafka中一个topic的所有partition,和每个partition的leader。这需要实现BrokerHosts的子类ZkHosts.但是,这个Zookeepr是可选的。如果使用BrokerHosts的另一个子类StaticHosts,把partition和leader的对应关系硬编码,则不需要Zookeeper来提供此功能。KafkaSpout会从Kafka集群使用的Zookeeper中提取partition和leader的对应关系。而且:
- 如果使用StatisHosts,那么KafkaSpout会使用StaticCoordinator,这个coordinator不能响应partition leader的变化。
- 如果使用ZkHosts,那么KafkaSpout会使用ZkCoordinator, 当其refresh()方法被调用后,这个cooridnator会检查发生leader变更的partition,并为之生成新的PartitionManager.从而能够在leader变更后,继续读取消息。
影响初始读取进度的配置项
在一个topology上线后,它从哪个offset开始读取消息呢?有一些配置项对此有影响:
- SpoutConfig中的id字段。如果想要一个topology从另一个topology之前的处理进度继续处理,它们需要有相同的id。
- KafkaConfig的forceFromStart字段。如果此字段设为true, 那么它一个topology上线后,它会忽略之前相同id的topology的进度,并且从Kafka中最早的消息开始处理。
- KafkaConfig的startOffsetTime字段。默认为kafka.api.OffsetRequest.EarliestTime()开始读,也就是从Kafka中最早的消息开始处理。也可以设成kafka.api.OffsetRequest.LatestOffset,也就是最早的消息开始读。也可以自己指定具体的值。
- KafkaConfig的maxOffsetBehind字段。这个字段对于KafkaSpout的多个处理流程都有影响。当提交一个新topology时,如果没有forceFromStart, 当KafkaSpout对某个partition的处理进度落后startOffsetTime对应的offset多于此值时,KafkaSpout会丢弃中间的消息,从而强制赶上目标进度.比如,如果startOffsetTime设成了lastestTime,那么如果进度落后超过maxOffsetBehind,KafkaSpout会直接从latestTime对应的offset开始处理。如果设成了froceFromStart,则在提交新任务时,始终会从EarliestTime开始读。
- KafkaSpout的userStartOffsetTimeIfOffsetOutOfRange字段。如果设成true,那么当fetch消息时出错,且FetchResponse显示的出错原因是OFFSET_OUT_OF_RANGE,那么就会尝试从KafkaSpout指定的startOffsetTime对应的消息开始读。例如,如果有一批消息因为超过了保存期限被Kafka删除,并且zk里记录的消息在这批被删除的消息里。如果KafkaSpout试图从zk的记录继续读,那么就会出现OFFSET_OUT_OF_RANGE的错误,从而触发这个配置。
实际上maxOffsetBehind有时候有点名不符实。当startOffsetTime为A, zk里的进度为B, A - B > maxOffsetBehind时,应该从A - maxOffsetBehind除开始读或许更好一些,而不是直接跳到startOffsetTime。此处的逻辑参见PartitionManager的实现。
附:其中KafkaConfig的maxWait的意义请参见这篇文章 《卡夫卡的炼狱》
实际上,KafkaSpout的一些行为可能会比较诡异,特别是与maxOffsetBehind有关的部分。这些行为由PartitionManager决定,参见对PartitionManager的分析这篇文章。
KafkaSpout分析:配置的更多相关文章
- 精尽Spring Boot源码分析 - 配置加载
该系列文章是笔者在学习 Spring Boot 过程中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合我的源码注释 Spring Boot 源码分析 GitHub 地址 进行阅读 Sprin ...
- MyBatis 源码分析——配置信息
MyBatis框架的启动前期需要加载相关的XML配置信息.从官网上我们可以了解到他具有十几个节点.其中笔者认为比较重要的节点是settings节点.properties节点.environments节 ...
- nginx源代码分析--配置信息的继承&合并
这里仅仅讲述http{}模块下的配置: 在ngx_http_block()函数内(这个函数别调用时在ngx_inti_cycle内的ngx_conf_parse函数,这个函数遇到http命令时 回调n ...
- 分析配置DispatcherServlet类时load-on-startup标签作用
<servlet> <servlet-name>DispatcherServlet</servlet-name> <servlet-class>org. ...
- web_profile(网站分析)配置
web_profiler: # DEPRECATED, it is not useful anymore and can be removed # safely from your configura ...
- U-Boot Makefile分析(1)配置脚本mkconfig分析
我们在编译U-Boot之前,需要根据当前使用的板子进行配置,例如make s5p_goni_config,接着才能进行编译make.下面首先分析配置阶段U-Boot做了哪些事情. 由于执行这些命令是在 ...
- SpringMVC入门案例及请求流程图(关于处理器或视图解析器或处理器映射器等的初步配置)
SpringMVC简介:SpringMVC也叫Spring Web mvc,属于表现层的框架.Spring MVC是Spring框架的一部分,是在Spring3.0后发布的 Spring结构图 Spr ...
- Sonar安装配置
https://www.sonarqube.org/downloads/ 下载sonar.当前版本为6.2 解压压缩包,进行配置: 修改sonarqube-6.2\conf\sonar.propert ...
- Solr:文本分析
文本分析时搜索引擎的核心工作之一,对文本包含许多处理步骤,比如:分词.大写转小写.词干化.同义词转化等.简单的说,文本分析就说将一个文本字段的值转为一个一个的token,然后被保存到Lucene的索引 ...
随机推荐
- Cocos2d-x手机游戏开发中-组合动作
动作往往不是单一,而是复杂的组合.我们可以按照一定的次序将上述基本动作组合起来,形成连贯的一套组合动作.组合动作包括以下几类:顺序.并列.有限次数重复.无限次数重复.反动作和动画.动画我们会在下一节介 ...
- Object类型
Object类型 我们看到的大多数引用类型值都是Object类型的实例,虽然Object类型不具备多少功能,但是在储存和传输数据上的确是不错的选择. 2.对象字面量表示法 调用Object构造函数: ...
- [C#]线程处理
线程处理用于使程序能够执行并发处理,同时执行多个操作.C#中有三种线程的使用方法,BackgroundWorker组件.线程池.自己创建使用线程,接下来分别介绍如何使用. 1.使用Background ...
- 页面get请求 中文参数方法乱码问题
对于get方式,请求参数中存在中文,可以使用下面的方法进行处理: 两次使用encodeURI()方法:例如:encodeURI(encodeURI(“中文”)),然后再服务器中使用URLDecoder ...
- zz 李治国:地图大战本质是争抢O2O入口
导航免费,这一天早该到来了!高德.百度免费之争,其实也是为了抢占生活服务这一最关键的入口,从而获得该战场的翻盘机会. 导航地图免费,实则是生活服务的入口之争.我在08年时就在阿里内部讲过这个事,并建议 ...
- 清理c盘垃圾(将一下代码复制到记事本然后把后缀名改为xxx.bat,然后双击,就ok了!!)
@echo off echo 正在清除系统垃圾文件,请稍等...... del /f /s /q %systemdrive%\*.tmp del /f /s /q %systemdrive%\*._m ...
- PDF编辑、删除、替换某页面或文字
在工作中,我们常常会用到PDF,当然尤其是会计,我虽然是程序员,但是“小老鼠”是会计,前几天,突然问我,怎么样将PDF中的某个页面替换掉,也就是删掉某页然后再从另外一个地方找一页补上来: 还需要改变这 ...
- jquery ListBox 左右移动
<head runat="server"> <title>无标题页</title> <script type="text/jav ...
- Export功能 导致 页面显示很多非法字符,还可能页面显示两次
private void exportBinaryToExcel(byte[] bytes, string filename) { Response.AddHeader("Content-D ...
- Mysql 存储过程小例子
创建存储过程: DELIMITER $$ USE `database_name`$$ DROP PROCEDURE IF EXISTS `add_or_update_user`$$ )) BEGIN ...