Storm最常用的消息源就是Kafka,在对接的时候大多需要使用KafkaSpout;

在网上大概有两种KafkaSpout,一种是只有几十行,一种却有一大啪啦类文件。


在kafka中,同一个partition中的消息只能被同一个组的一个consumer消费,不能并发,所以kafka的并发说的是多partition的并发;

kafka的consumer API分为high level consumer和low level consumer,官方建议使用前者,以为不用关心partition、offset那些,但是后者也有其存在的意义:1.多次读取的时候;2.选择性读取部分消息;3.控制消费过程。


写法比较简单的KafkaSpout:

  1. public class KafkaSpouttest implements IRichSpout {
  2.  
  3. private static final long serialVersionUID = 1L;
  4. private SpoutOutputCollector collector;
  5. private ConsumerConnector consumer;
  6. private String topic;
  7.  
  8. public KafkaSpouttest() {}
  9.  
  10. public KafkaSpouttest(String topic) {
  11. this.topic = topic;
  12. }
  13.  
  14. public void ack(Object arg0) {
  15.  
  16. }
  17.  
  18. private static ConsumerConfig createConsumerConfig() {
  19. Properties props = new Properties();
  20. // 设置zookeeper的链接地址
  21. props.put("zookeeper.connect", "localhost:2181");
  22. // 设置group id
  23. props.put("group.id", "1");
  24. // kafka的group 消费记录是保存在zookeeper上的, 但这个信息在zookeeper上不是实时更新的, 需要有个间隔时间更新
  25. props.put("auto.commit.interval.ms", "1000");
  26. props.put("zookeeper.session.timeout.ms", "10000");
  27. return new ConsumerConfig(props);
  28. }
  29.  
  30. public void activate() {
  31. consumer = kafka.consumer.Consumer.createJavaConsumerConnector(createConsumerConfig());
  32. Map < String,
  33. Integer > topickMap = new HashMap < String,
  34. Integer > ();
  35. topickMap.put(topic, 1);
  36.  
  37. System.out.println("*********Results********topic:" + topic);
  38.  
  39. Map < String,
  40. List < KafkaStream < byte[],
  41. byte[] >>> streamMap = consumer.createMessageStreams(topickMap);
  42. KafkaStream < byte[],
  43. byte[] > stream = streamMap.get(topic).get(0);
  44. ConsumerIterator < byte[],
  45. byte[] > it = stream.iterator();
  46. while (it.hasNext()) {
  47. String value = new String(it.next().message());
  48. SimpleDateFormat formatter = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss SSS");
  49. Date curDate = new Date(System.currentTimeMillis()); //获取当前时间
  50. String str = formatter.format(curDate);
  51.  
  52. System.out.println("storm接收到来自kafka的消息------->" + value);
  53.  
  54. collector.emit(new Values(value, 1, str), value);
  55. }
  56. }
  57.  
  58. public void close() {
  59. // TODO Auto-generated method stub
  60. }
  61.  
  62. public void deactivate() {
  63. // TODO Auto-generated method stub
  64. }
  65.  
  66. public void fail(Object arg0) {
  67. // TODO Auto-generated method stub
  68. }
  69.  
  70. public void nextTuple() {
  71. // TODO Auto-generated method stub
  72. }
  73.  
  74. public void open(Map arg0, TopologyContext arg1, SpoutOutputCollector collector) {
  75. this.collector = collector;
  76. }
  77.  
  78. public void declareOutputFields(OutputFieldsDeclarer declarer) {
  79. declarer.declare(new Fields("word", "id", "time"));
  80. }
  81.  
  82. public Map < String,
  83. Object > getComponentConfiguration() {
  84. System.out.println("getComponentConfiguration被调用");
  85. topic = "admln";
  86. return null;
  87. }
  88.  
  89. }

方法相关的不解释,和本主题相关的一句话是:

  1. byte[] >>> streamMap = consumer.createMessageStreams(topickMap);

想说的是它用的是High Level API


复杂的代码就多了,在github上有好几个,最官方的还是apache storm自带的:

里面和本主题相关的一句话是DynamicPartitionConnections.java中的60行:

  1. _connections.put(host, new ConnectionInfo(new SimpleConsumer(host.host, host.port, _config.socketTimeoutMs, _config.bufferSizeBytes, _config.clientId)));

它用的是low level API


apache KafkaSpout 在 topology 中的配置

  1. String zkConnString = "node1:2181,node2:2181,node3:2181";
  2. String topicName = "testtopic";
  3. BrokerHosts hosts = new ZkHosts(zkConnString);
  4. SpoutConfig spoutConfig = new SpoutConfig(hosts, topicName, "/" + topicName, UUID.randomUUID().toString());
  5. spoutConfig.forceFromStart = false;
  6. spoutConfig.zkPort = ;
  7. spoutConfig.zkServers = Arrays.asList(new String[]{"node1","node2","node3"});
  8.  
  9. spoutConfig.scheme = new SchemeAsMultiScheme(new StringScheme());
  10.  
  11. KafkaSpout kafkaSpout = new KafkaSpout(spoutConfig);
  12.  
  13. TopologyBuilder builder = new TopologyBuilder();
  14. // 构造NC数据流向图
  15. builder.setSpout("mrspout", kafkaSpout, );
  16. builder.setBolt("mrverifybolt", new MRVerifyBolt(), )
  17. .shuffleGrouping("mrspout");
  18. builder.setBolt("mr2storagebolt", new MR2StorageBolt(), )
  19. .shuffleGrouping("mrverifybolt");
  20. // 以类名作为STORM任务名
  21. String name = MRTopology.class.getSimpleName();
  22. // 传主机名则为集群运行模式,不传则为本地运行模式
  23. if (args != null && args.length > ) {
  24. Config conf = new Config();
  25. // 通过指定nimbus主机
  26. conf.put(Config.NIMBUS_HOST, args[]);
  27. conf.setNumWorkers();
  28. conf.setNumAckers();
  29. conf.setMaxSpoutPending();
  30. StormSubmitter.submitTopologyWithProgressBar(name, conf,
  31. builder.createTopology());
  32. } else {
  33. Map conf = new HashMap();
  34. conf.put(Config.TOPOLOGY_WORKERS, );
  35. conf.put(Config.TOPOLOGY_DEBUG, true);
  36. LocalCluster cluster = new LocalCluster();
  37. cluster.submitTopology(name, conf, builder.createTopology());
  38. }
  39. }

关于 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的选择的更多相关文章

  1. Storm中遇到的日志多次重写问题(一)

    业务描述: 统计从kafka spout中读取的数据条数,以及写入redis的数据的条数,写入hdfs的数据条数,写入kafaka的数据条数.并且每过5秒将数据按照json文件的形式写入日志.其中保存 ...

  2. storm中的一些概念

    1.topology 一个topolgy是spouts和bolts组成的图,通过stream groupings将图中的spout和bolts连接起来:如图所示: 一个topology会一直运行知道你 ...

  3. Storm中Spout使用注意事项小结

    Storm中Spout用于读取并向计算拓扑中发送数据源,最近在调试一个topology时遇到了系统qps低,处理速度达不到要求的问题,经过排查后发现是由于对Spout的使用模式不当导致的多线程同步等待 ...

  4. storm源码之理解Storm中Worker、Executor、Task关系 + 并发度详解

    本文导读: 1 Worker.Executor.task详解 2 配置拓扑的并发度 3 拓扑示例 4 动态配置拓扑并发度 Worker.Executor.Task详解: Storm在集群上运行一个To ...

  5. Storm中并发程度的理解

    Storm中涉及到了很多组件,例如nimbus,supervisor等等,在参考了这两篇文章之后,对这个有了更好的理解. Understanding the parallelism of a Stor ...

  6. 解决:IE中不能自动选择UTF-8编码的解决方法

    IE中不能自动选择UTF-8编码的解决办法 在windows操作系统上使用IE作为浏览器时.常常会发生这样的问题:在浏览使用UTF-8编码的网页时,浏览器无法自动侦测(即没有设定“自动选择”编码格式时 ...

  7. 【Storm篇】--Storm中的同步服务DRPC

    一.前述 Drpc(分布式远程过程调用)是一种同步服务实现的机制,在Storm中客户端提交数据请求之后,立刻取得计算结果并返回给客户端.同时充分利用Storm的计算能力实现高密度的并行实时计算. 二. ...

  8. Vue.js中使用select选择下拉框

    在Vue.js中使用select选择下拉框有两种方法: 第一种: Add.html: <select v-model="sysNotice.noticeType" id=&q ...

  9. storm中worker、executor、task之间的关系

    这里做一些补充: worker是一个进程,由supervisor启动,并只负责处理一个topology,所以不会同时处理多个topology. executor是一个线程,由worker启动,是运行t ...

随机推荐

  1. PHP 去掉emoji字符

    function isMatchEmoji($str) { $pattern='/./u'; $rs=preg_match_all($pattern,$str,$match); if($rs>0 ...

  2. 数独·唯一性技巧(Uniqueness)-1

    唯一性技巧基于这样一个事实——各类出版物上发布的数独题目都只有唯一解.事实上,绝大多数数独玩家有这样的共识:即合格的数独题目解应该是唯一的.因此,为了保证题目合格.有效,出题者在制作题目时,会将一些虽 ...

  3. MySQL 学习笔记(二):数据库更新、视图和数据控制

    基础准备: 在 school 数据库下建立student.course.sc 三个表: create table student( Sno ) primary key, Sname ) unique, ...

  4. centos6.5 git clone http 报错

    自己搭建服务器环境为centos6.5,需要使用git clone 命令的时候报错 首先查看centos上安装的git版本,我的版本为1.7.10 报错后,查阅相关资料需将centos升级,操作如下 ...

  5. 微信小程序HTTPS - cenos apache 下安装SSL证书

    1.yum install mod_ssl 2.接下来,我们需要创建一个新目录,我们将存储服务器密钥和证书 mkdir /root/ssl 3.vi /etc/httpd/conf.d/ssl.con ...

  6. CKEditor编辑器的使用方法

    CKEditor  网页中实现所见即所得的编辑器. 使用步骤: 1.下载CKEditor  下载地址:http://ckeditor.com/download 2.添加CKEditor的文件夹到项目中 ...

  7. 简单的IDEA破解到2099年

    原文链接:https://www.cnblogs.com/duende99/p/10038640.html 破解方式有2种,第一种比较方便 第一种比较方便1.使用注册码破解:http://idea.l ...

  8. 【智能算法】变邻域搜索算法(Variable Neighborhood Search,VNS)超详细解析和TSP代码实例以及01背包代码实例

    喜欢的话可以扫码关注我们的公众号哦,更多精彩尽在微信公众号[程序猿声] 00 目录 局部搜索再次科普 变邻域搜索 造轮子写代码 01 局部搜索科普三连 虽然之前做的很多篇启发式的算法都有跟大家提过局部 ...

  9. eclipse创建Java项目时提示Open Associated Perspective?

    在eclipse中,原先使用python进行编程,需要新建java项目时,会提示如下信息: 消息框内翻译如下: Open Associated Perspective? --开放关联视角? This ...

  10. c语言数据结构学习心得——查找

    顺序查找(线性查找) 主要用于在线性表中的查找 int Search1(int a[],int n,int key){ ;i<=n;i++){ //注意从1开始 if(a[i]==key)ret ...