jStorm 流分发-订阅机制测试
来源:互联网 发布:读博士 知乎 编辑:程序博客网 时间:2024/05/21 08:47
摘要
在 Storm 的拓扑中,存在若干种流分发策略;而在拓扑的创建中,也容许一个拓扑中接收消息的为不同类型的 bolt。那么在复杂拓扑结构中,流分发机制是否可靠?本文以实验的方式模拟稍微复杂的网络拓扑,并发送数据流进行了验证,得出 jStorm 可以很好地识别 bolt 类型,不同组 bolt 订阅相同流互相不影响的结论。随后将对 jStorm 如何做到这种类似消息队列的消费者 offset 维护将进行浅析。
拓扑结构
如下图所示,TestSpout 通过 static Atomic Integer 原子操作类型进行线程安全的多线程计数,并将该值发送至两个不同处理逻辑的 Bolt。之后对两个 Bolt 的输入日志进行分析。
测试结论
- 不同的 Bolt 组订阅消息满足不同 groupping 的预期,即流量分发均可拿到全量数据而互不干扰;
- 只要有流出异常,如果两边都有 ack 机制,那么任务会被停止;
- 否则,如果未出异常,那么两边均正常 ack 后,继续发送下一个 tuple(从这里猜测,应该是 spout 内部维护了一个同步发送队列,即所有需要 ack 的流都被应答后,才同时广播给所有 Bolt 下一个数据)。
- 变换 worker 数目后发现,不同的 task(bolt/spout均被按顺序编号task-id)几乎会均匀的分配到不同的 worker(同一个worker间的task之间数据收发通过队列,不同的worker的task之间数据收发通过netty),未产生流丢失的现象,且日志分别在不同的两个worker所在机器上。
测试代码
/*** @Description 测试spout的流订阅机制* @param spoutSize* @param boltSize* @param workers* @return* @throws Exception */ private boolean testSample(Integer spoutSize, Integer boltSize, Integer workers) throws Exception { TopologyBuilder builder = new TopologyBuilder(); builder.setSpout("testSpout", new TestSpout(), spoutSize); builder.setBolt("TestBoltOrig", new TestBoltOrig(), 2).fieldsGrouping("testSpout",new Fields("modVal")); builder.setBolt("TestBoltDouble", new TestBoltDouble(), 3).fieldsGrouping("testSpout",new Fields("modVal")); conf.put(backtype.storm.Config.TOPOLOGY_WORKERS, 2); // 设置Worker的数量 try { //提交测试拓扑 StormSubmitManager.getInstance().submitTopology(builder, "testSample", conf); LOGGER.info("submit success!"); return true; } catch (Exception e) { LOGGER.error("submit failed : " + e.getMessage(), e); throw e; } }/** * @Description 测试 wordCount * @author cathar * @Date 2017年1月4日 下午8:25:07 */public class TestSpout extends BaseRichSpout { private SpoutOutputCollector collector; private boolean completed = false; private static final Logger LOGGER = Logger.getLogger(TestSpout.class); //全局共享的,在spout初始化的时候,每个线程获取一次作为自己的编号 static AtomicInteger sAtomicInteger = new AtomicInteger(0); //多线程共享的变量 static AtomicInteger pendNum = new AtomicInteger(0); private int sqnum; @Override public void open(Map conf, TopologyContext context, SpoutOutputCollector collector) { //spout 线程编号 sqnum = sAtomicInteger.incrementAndGet(); //初始化发射器 this.collector = collector; } @Override public void nextTuple() { //模拟一直发送递增的全局数字 while (true) { int a = pendNum.incrementAndGet(); //如果有多个线程,这里输出的数字是连续的,共同改变 LOGGER.info(String.format("spout %d, send pendNum %d", sqnum, a)); this.collector.emit(new Values(a%10, a)); try { Thread.sleep(10000); } catch (InterruptedException e) { e.printStackTrace(); } } } @Override public void declareOutputFields(OutputFieldsDeclarer declarer) { // TODO Auto-generated method stub //declarer.declare(new Fields("word")); declarer.declare(new Fields("modVal","val")); } /** * 启用 ack 机制,详情参考:https://github.com/alibaba/jstorm/wiki/Ack-%E6%9C%BA%E5%88%B6 * @param msgId */ @Override public void ack(Object msgId) { super.ack(msgId); } /** * 消息处理失败后需要自己处理 * @param msgId */ @Override public void fail(Object msgId) { super.fail(msgId); LOGGER.info("ack fail,msgId"+msgId); }}public class TestBoltOrig implements IRichBolt {//...@Override public void execute(Tuple input) { Integer partition = input.getIntegerByField("modVal"); Integer val = input.getIntegerByField("val"); LOGGER.error(String.format("TestBoltOrig received partition %d: val %d", partition,val)); this.collector.ack(input); try { Thread.sleep(10000); } catch (InterruptedException e) { e.printStackTrace(); } }//...}public class TestBoltDouble implements IRichBolt {//...@Override public void execute(Tuple input) { Integer partition = input.getIntegerByField("modVal"); Integer val = input.getIntegerByField("val"); LOGGER.error(String.format(" TestBoltDouble received partition %d: val %d", partition,val*10)); this.collector.ack(input); try { Thread.sleep(10000); } catch (InterruptedException e) { e.printStackTrace(); } }//...}
0 0
- jStorm 流分发-订阅机制测试
- jstorm的acker机制
- Android 事件分发机制测试以及总结
- android-----事件分发机制测试系列
- android-----事件分发机制测试系列(二)
- android-----事件分发机制测试系列(三)
- android-----事件分发机制测试系列(四)
- android-----事件分发机制测试系列(五)
- Android事件分发机制(Demo测试)
- 测试订阅
- cocos2dx 3.2 新的事件分发机制 (观察者/订阅者模式)
- 利用单例+观察者设计一个简易的分发/订阅消息机制
- 利用单例+观察者设计一个简易的分发/订阅消息机制
- MSSQLSERVER之发布-分发-订阅
- Kafka 消息订阅与分发
- jstorm
- jstorm
- Jstorm
- import export default export的使用
- 将数组a中的n个整数按相反顺序存放。(指针)
- android studio 导入新项目很慢的解决方法
- DataView详解
- Uva400 Unix is
- jStorm 流分发-订阅机制测试
- 第八天、实现Socket服务端和客户端即时通信
- Ubuntu16.04出现黑屏问题,没有账户的图标,进入不了图形
- Ubuntu16.04下Caffe环境搭建:cuda8.0 + opencv2.4.13
- HDOJ(HDU).2660 Accepted Necklace (DFS)
- 监督学习-朴素贝叶斯算法模板
- OSI模型中完整7层定义
- sudo apt-get install libopencv-dev 遇到ppa获取错误的问题
- HDU 1002:A + B Problem II