storm中KafkaSpout的选择
Storm最常用的消息源就是Kafka,在对接的时候大多需要使用KafkaSpout;
在网上大概有两种KafkaSpout,一种是只有几十行,一种却有一大啪啦类文件。
在kafka中,同一个partition中的消息只能被同一个组的一个consumer消费,不能并发,所以kafka的并发说的是多partition的并发;
kafka的consumer API分为high level consumer和low level consumer,官方建议使用前者,以为不用关心partition、offset那些,但是后者也有其存在的意义:1.多次读取的时候;2.选择性读取部分消息;3.控制消费过程。
写法比较简单的KafkaSpout:
public class KafkaSpouttest implements IRichSpout {
private static final long serialVersionUID = 1L;
private SpoutOutputCollector collector;
private ConsumerConnector consumer;
private String topic;
public KafkaSpouttest() {}
public KafkaSpouttest(String topic) {
this.topic = topic;
}
public void ack(Object arg0) {
}
private static ConsumerConfig createConsumerConfig() {
Properties props = new Properties();
// 设置zookeeper的链接地址
props.put("zookeeper.connect", "localhost:2181");
// 设置group id
props.put("group.id", "1");
// kafka的group 消费记录是保存在zookeeper上的, 但这个信息在zookeeper上不是实时更新的, 需要有个间隔时间更新
props.put("auto.commit.interval.ms", "1000");
props.put("zookeeper.session.timeout.ms", "10000");
return new ConsumerConfig(props);
}
public void activate() {
consumer = kafka.consumer.Consumer.createJavaConsumerConnector(createConsumerConfig());
Map < String,
Integer > topickMap = new HashMap < String,
Integer > ();
topickMap.put(topic, 1);
System.out.println("*********Results********topic:" + topic);
Map < String,
List < KafkaStream < byte[],
byte[] >>> streamMap = consumer.createMessageStreams(topickMap);
KafkaStream < byte[],
byte[] > stream = streamMap.get(topic).get(0);
ConsumerIterator < byte[],
byte[] > it = stream.iterator();
while (it.hasNext()) {
String value = new String(it.next().message());
SimpleDateFormat formatter = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss SSS");
Date curDate = new Date(System.currentTimeMillis()); //获取当前时间
String str = formatter.format(curDate);
System.out.println("storm接收到来自kafka的消息------->" + value);
collector.emit(new Values(value, 1, str), value);
}
}
public void close() {
// TODO Auto-generated method stub
}
public void deactivate() {
// TODO Auto-generated method stub
}
public void fail(Object arg0) {
// TODO Auto-generated method stub
}
public void nextTuple() {
// TODO Auto-generated method stub
}
public void open(Map arg0, TopologyContext arg1, SpoutOutputCollector collector) {
this.collector = collector;
}
public void declareOutputFields(OutputFieldsDeclarer declarer) {
declarer.declare(new Fields("word", "id", "time"));
}
public Map < String,
Object > getComponentConfiguration() {
System.out.println("getComponentConfiguration被调用");
topic = "admln";
return null;
}
}
方法相关的不解释,和本主题相关的一句话是:
byte[] >>> streamMap = consumer.createMessageStreams(topickMap);
想说的是它用的是High Level API
复杂的代码就多了,在github上有好几个,最官方的还是apache storm自带的:

里面和本主题相关的一句话是DynamicPartitionConnections.java中的60行:
_connections.put(host, new ConnectionInfo(new SimpleConsumer(host.host, host.port, _config.socketTimeoutMs, _config.bufferSizeBytes, _config.clientId)));
它用的是low level API
apache KafkaSpout 在 topology 中的配置
String zkConnString = "node1:2181,node2:2181,node3:2181";
String topicName = "testtopic";
BrokerHosts hosts = new ZkHosts(zkConnString);
SpoutConfig spoutConfig = new SpoutConfig(hosts, topicName, "/" + topicName, UUID.randomUUID().toString());
spoutConfig.forceFromStart = false;
spoutConfig.zkPort = ;
spoutConfig.zkServers = Arrays.asList(new String[]{"node1","node2","node3"}); spoutConfig.scheme = new SchemeAsMultiScheme(new StringScheme()); KafkaSpout kafkaSpout = new KafkaSpout(spoutConfig); TopologyBuilder builder = new TopologyBuilder();
// 构造NC数据流向图
builder.setSpout("mrspout", kafkaSpout, );
builder.setBolt("mrverifybolt", new MRVerifyBolt(), )
.shuffleGrouping("mrspout");
builder.setBolt("mr2storagebolt", new MR2StorageBolt(), )
.shuffleGrouping("mrverifybolt");
// 以类名作为STORM任务名
String name = MRTopology.class.getSimpleName();
// 传主机名则为集群运行模式,不传则为本地运行模式
if (args != null && args.length > ) {
Config conf = new Config();
// 通过指定nimbus主机
conf.put(Config.NIMBUS_HOST, args[]);
conf.setNumWorkers();
conf.setNumAckers();
conf.setMaxSpoutPending();
StormSubmitter.submitTopologyWithProgressBar(name, conf,
builder.createTopology());
} else {
Map conf = new HashMap();
conf.put(Config.TOPOLOGY_WORKERS, );
conf.put(Config.TOPOLOGY_DEBUG, true);
LocalCluster cluster = new LocalCluster();
cluster.submitTopology(name, conf, builder.createTopology());
}
}
关于 spoutConfig.servers 和 spoutConfig.port 在实际应用中其实不设置也可以,因为在集群中如果不设置 storm 默认会把 storm 配置中的 zookeeper 地址和端口,设置的用处是在 eclipse 中测试运行的时候因为是模拟 storm cluster, 所以主动设置。
两者各有优劣,相同点性能,简单测试过,low level的要好点,但是相差不大(都在合适的配置下,小集群);
不同点是high level 的代码简单,而low level的代码很多,配置也多,用着麻烦(也不是很麻烦);
low level的优点是支持重读,就是配置中的 spoutConfig.forceFromStart = false; ,支持重读的另一个好处是和storm的acker结合,可以重发,防止丢数据,这一点比low level的要安全一点,另一个好处是配置多,使用就很难灵活,比如设置KafkaSpout的fetchSizeBytes,和kafka的bufferSizeBytes对应,是优化的一个手段。
至于选择哪种,支持后者,反正storm中已经自带了,不需要自己写,配置就好,而且0.9.4中优化了很多KafkaSpout的问题。
storm中KafkaSpout的选择的更多相关文章
- Storm中遇到的日志多次重写问题(一)
业务描述: 统计从kafka spout中读取的数据条数,以及写入redis的数据的条数,写入hdfs的数据条数,写入kafaka的数据条数.并且每过5秒将数据按照json文件的形式写入日志.其中保存 ...
- storm中的一些概念
1.topology 一个topolgy是spouts和bolts组成的图,通过stream groupings将图中的spout和bolts连接起来:如图所示: 一个topology会一直运行知道你 ...
- Storm中Spout使用注意事项小结
Storm中Spout用于读取并向计算拓扑中发送数据源,最近在调试一个topology时遇到了系统qps低,处理速度达不到要求的问题,经过排查后发现是由于对Spout的使用模式不当导致的多线程同步等待 ...
- storm源码之理解Storm中Worker、Executor、Task关系 + 并发度详解
本文导读: 1 Worker.Executor.task详解 2 配置拓扑的并发度 3 拓扑示例 4 动态配置拓扑并发度 Worker.Executor.Task详解: Storm在集群上运行一个To ...
- Storm中并发程度的理解
Storm中涉及到了很多组件,例如nimbus,supervisor等等,在参考了这两篇文章之后,对这个有了更好的理解. Understanding the parallelism of a Stor ...
- 解决:IE中不能自动选择UTF-8编码的解决方法
IE中不能自动选择UTF-8编码的解决办法 在windows操作系统上使用IE作为浏览器时.常常会发生这样的问题:在浏览使用UTF-8编码的网页时,浏览器无法自动侦测(即没有设定“自动选择”编码格式时 ...
- 【Storm篇】--Storm中的同步服务DRPC
一.前述 Drpc(分布式远程过程调用)是一种同步服务实现的机制,在Storm中客户端提交数据请求之后,立刻取得计算结果并返回给客户端.同时充分利用Storm的计算能力实现高密度的并行实时计算. 二. ...
- Vue.js中使用select选择下拉框
在Vue.js中使用select选择下拉框有两种方法: 第一种: Add.html: <select v-model="sysNotice.noticeType" id=&q ...
- storm中worker、executor、task之间的关系
这里做一些补充: worker是一个进程,由supervisor启动,并只负责处理一个topology,所以不会同时处理多个topology. executor是一个线程,由worker启动,是运行t ...
随机推荐
- 关于.net DateTime 的一些事儿
最近开发的过程中遇到一种情况,在.net 程序中获取的Datetime格式的时间,在存入SQL server中,毫秒部分丢失. 这个是个很奇怪的状况,因为在Debug的时候,Datetime的变量的确 ...
- java中公用类型Car必须在它自己的文件中定义
熟悉java的过程中发现了一些小问题,定义的类Car老是提示必须在它自己的文件中定义.自己想了想试试把Car继承的类Vehicle中的public换到Car类中,结果发现输出问题很大.它只显示了一个输 ...
- 动态往 datagridview 追加行、列操作
DataGridViewTextBoxColumn acCode = new DataGridViewTextBoxColumn(); acCode.Name = "acCode" ...
- web端访问文件没有权限的问题
背景 : ftp的PHP项目中的某些文件没有写入的权限..系统报注意错误!!! 原因 : 一般情况下,web端访问网站一般使用的是WWW权限(有限制的权限组)去访问, 但是我们编程开发的时候, 有可能 ...
- 基于stor2RRD 的 SAN、存储监控
一. 配置用法在官网都有的详见网页: http://www.stor2rrd.com/install.htm?1.2 二 . 在这里我只是想记录一下我是如何编译安装Apache的,避免踩坑: 安装包如 ...
- Struts2学习第3天--OGNL、EL、值栈
JAVA中的OGNL: 1 调用对象的方法: 2 访问对象的静态方法: 3 获取OGNLContext.Root中的数据. User: 4 访问Context: 关键还是在Struts2环境中的使用: ...
- sklearn的train_test_split函数
train_test_split函数用于将矩阵随机划分为训练子集和测试子集,并返回划分好的训练集测试集样本和训练集测试集标签. from sklearn.model_selection import ...
- oracle闪回存储过程
源地址:https://www.baidu.com/link?url=qgVCi_BLGOYqxJN0Fqqt-9N0SmCwtGI70SIh-TFpx1nP6oaVoMj8H6yjEqilto6TM ...
- SDUT OJ 数据结构实验之二叉树四:(先序中序)还原二叉树
数据结构实验之二叉树四:(先序中序)还原二叉树 Time Limit: 1000 ms Memory Limit: 65536 KiB Submit Statistic Discuss Problem ...
- CBoard 看板参数管理
看板设计采用简单Row+Column布局模式,每行总长度为12,每列对应一个图表,行高度可以调节,列高度集成行高 左边栏看板分类中,我的看板为当前用户创建的看板,普通看板分类通过分类管理维护,保存看板 ...