Storm常见模式——批处理
Storm对流数据进行实时处理时,一种常见场景是批量一起处理一定数量的tuple元组,而不是每接收一个tuple就立刻处理一个tuple,这样可能是性能的考虑,或者是具体业务的需要。
例如,批量查询或者更新数据库,如果每一条tuple生成一条sql执行一次数据库操作,数据量大的时候,效率会比批量处理的低很多,影响系统吞吐量。
当然,如果要使用Storm的可靠数据处理机制的话,应该使用容器将这些tuple的引用缓存到内存中,直到批量处理的时候,ack这些tuple。
下面给出一个简单的代码示例:
现在,假设我们已经有了一个DBManager数据库操作接口类,它至少有两个接口:
(1)getConnection(): 返回一个java.sql.Connection对象;
(2)getSQL(Tuple tuple): 根据tuple元组生成数据库操作语句。
为了在Bolt中缓存一定数量的tuple,构造Bolt时传递int n参数赋给Bolt的成员变量int count,指定每个n条tuple批量处理一次。
同时,为了在内存中缓存缓存Tuple,使用java concurrent中的ConcurrentLinkedQueue来存储tuple,每当攒够count条tuple,就触发批量处理。
另外,考虑到数据量小(如很长时间内都没有攒够count条tuple)或者count条数设置过大时,因此,Bolt中加入了一个定时器,保证最多每个1秒钟进行一次批量处理tuple。
下面是Bolt的完整代码(仅供参考):

import java.util.Map;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement; import backtype.storm.task.OutputCollector;
import backtype.storm.task.TopologyContext;
import backtype.storm.topology.IRichBolt;
import backtype.storm.topology.OutputFieldsDeclarer;
import backtype.storm.tuple.Tuple; public class BatchingBolt implements IRichBolt {
private static final long serialVersionUID = 1L;
private OutputCollector collector;
private Queue<Tuple> tupleQueue = new ConcurrentLinkedQueue<Tuple>();
private int count;
private long lastTime;
private Connection conn; public BatchingBolt(int n) {
count = n; //批量处理的Tuple记录条数
conn = DBManger.getConnection(); //通过DBManager获取数据库连接
lastTime = System.currentTimeMillis(); //上次批量处理的时间戳
} @Override
public void prepare(Map stormConf, TopologyContext context,
OutputCollector collector) {
this.collector = collector;
} @Override
public void execute(Tuple tuple) {
tupleQueue.add(tuple);
long currentTime = System.currentTimeMillis();
// 每count条tuple批量提交一次,或者每个1秒钟提交一次
if (tupleQueue.size() >= count || currentTime >= lastTime + 1000) {
Statement stmt = conn.createStatement();
conn.setAutoCommit(false);
for (int i = 0; i < count; i++) {
Tuple tup = (Tuple) tupleQueue.poll();
String sql = DBManager.getSQL(tup); //生成sql语句
stmt.addBatch(sql); //加入sql
collector.ack(tup); //进行ack
}
stmt.executeBatch(); //批量提交sql
conn.commit();
conn.setAutoCommit(true);
System.out.println("batch insert data into database, total records: " + count);
lastTime = currentTime;
}
} @Override
public void cleanup() {
} @Override
public void declareOutputFields(OutputFieldsDeclarer declarer) {
} @Override
public Map<String, Object> getComponentConfiguration() {
// TODO Auto-generated method stub
return null;
}
}

Storm常见模式——批处理的更多相关文章
- Storm常见模式——分布式RPC
Storm常见模式——分布式RPC 本文翻译自:https://github.com/nathanmarz/storm/wiki/Distributed-RPC,作为学习Storm DRPC的资料,转 ...
- Storm入门(九)Storm常见模式之流聚合
流聚合(stream join)是指将具有共同元组(tuple)字段的数据流(两个或者多个)聚合形成一个新的数据流的过程. 从定义上看,流聚合和SQL中表的聚合(table join)很像,但是二者有 ...
- Storm常见模式——流聚合
转自:http://www.cnblogs.com/panfeng412/archive/2012/06/04/storm-common-patterns-of-stream-join.html 流聚 ...
- Twitter Storm: storm的一些常见模式
这篇文章列举出了storm topology里面的一些常见模式: 流聚合(stream join) 批处理(Batching) BasicBolt 内存内缓存 + fields grouping 组合 ...
- 浅议NetMQ常见模式和消息加密机制
浅议NetMQ常见模式和消息加密机制 概述 在传统企业级开发中,消息队列机制已经成为一种非常常见的技术实现手段,而基于NetMQ则看起来有点像一朵"奇葩",看起来从名字似乎是一个消 ...
- 【原】Storm Local模式和生产环境中Topology运行配置
Storm入门教程 1. Storm基础 Storm Storm主要特点 Storm基本概念 Storm调度器 Storm配置 Guaranteeing Message Processing(消息处理 ...
- 【js基础】创建对象的几种常见模式(工厂模式,构造函数模式,原型模式,构造原型组合模式)
一.工厂模式 缺点:没有解决对象识别的问题 优点:解决了创建多个相似对象的问题 function createPerson(name,age,job){ var o = new Object(); o ...
- RabbitMQ Queue一些常见模式
懒队列:lazy Queue,即用到的时候才会加载,3.6.0及之后新添加的.当新添加数据后,不会将其放入到内存中,而是将其放入到磁盘中. 普通队列:1).in-memory,数据直接放入到内存中. ...
- Storm本地模式异常
来自:http://isuifengfei.iteye.com/blog/1998265 问题1 java.net.SocketException: Address family not supp ...
随机推荐
- vim 模式基础操作
作者:枫雪庭 出处:http://www.cnblogs.com/FengXueTing-px/ 欢迎转载 前言 虽然Emacs已经可以完成大部分的编辑操作,但有时候为了方便也会用到vim.所以记录了 ...
- UVALive 7141 BombX
离散化,线段树.$2014$年$ACM/ICPC$亚洲区域赛上海站$D$题. 可以处理出炸任意相邻的$h$行能消灭的点的数量,以及炸任意相邻的$w$列能消灭的点的数量,分别用$py[i]$和$px[i ...
- c++ 常见问题之 const
const 默认状态下const对象仅在文件内有效,添加extern关键字可以在多个文件共享 const 引用: 可以把引用绑定到const对象上,对常量的引用不能被用作修改它所绑定的对象 const ...
- java基础<迷你DVD系统>
一.写在main方法中 import java.util.*; public class MyDVDMgr { public static void main(String[] args){ Scan ...
- Redis配置成系统服务(CentOS7)
1. 进入到redis安装目录,具体位置看你安装时的路径了. cd /usr/local/redis/ 2. 编辑配置文件 sudo vim ./redis.conf 3. 将如下配置项注释掉 #bi ...
- netty中级篇(2)
上一篇 netty入门篇(1) 一.编码解码技术 如何评价一个编解码技术: 是否支持跨语言,或者说支持的语言是否丰富 编码码流大小,影响传输速度 编码和解码的性能,即时间 类库是否精致,API是否方便 ...
- Android使用Home键后应用程序重启的问题
正常情况应该是在点击 home 按键后,程序在后台暂停运行,点击 后退键 才会退出应用的,但是今天遇到个问题,点击 home 键后,重新再打开应用却每次都返回应用启动页面,有些莫名其妙,一番googl ...
- HDU 5877 Weak Pair
$dfs$序,线段树. 可以统计每一个节点作为$root$的子树上对答案的贡献,可以将树转换成序列.问题就变成了一段区间上求小于等于某个值的数有几个.用线段树记录排好序之后的区间序列,询问的时候,属于 ...
- VS2012及以上版本 程序打包部署详解
引用: http://blog.csdn.net/zhang_xinxiu/article/details/9099757 程序编写测试完成后接下来我们要做的是打包部署程序,但VS2012让人心痛的 ...
- Python初识与简介【开篇】
目录 1.扯淡 2.Python历史 3.Python简介 4.Python应用 5.为什么是python而不是其他语言? 6.Python的种类 7.Python的特点 8.Python设计哲学 9 ...