Storm常用计算模式


Apache Storm是目前最流行的实时计算框架之一,基于 streams, spouts, bolts, and topologies这些基本组件,可以组合出一些计算模式,每个模式对应解决一类现实中的问题。

下面介绍几种计算模式,并给出代码示例,希望对读者有所帮助:

模式1: JOIN

Join一般是指基于某个共同的属性,把2类内容合并到一起。传统数据库的join,定义和逻辑都非常明确,有left join, right join , full join 等。

两个实时流之间的join,指的是在某个时间窗口内,两个流根据某些共同的字段来做匹配。比如有这个需求:某个网络广告系统,实时地产生所投放的广告的点击日志和展示日志,需要统计出广告每分钟的点击率(点击量/展示量)。输入是2个日志流点击日志和展示日志,输出是所有广告前一分钟的实时点击率(每5秒刷新一次)。
下面给出一个Join Bolt execute里的代码
@Override
public void execute(TupleWindow inputWindow) {

    Map<String, Integer> pvmap = new HashMap<>();
    Map<String, Integer> clickmap = new HashMap<>();
    for(Tuple tuple: inputWindow.get()) {
        if(tuple.getSourceComponent().equalsIgnoreCase("log_pv")) { 
            String brand = tuple.getStringByField("brand");
            pvmap.put(brand, (pvmap.get(brand) != null ? pvmap.get(brand) : 0) + 1);
        }
        if(tuple.getSourceComponent().equalsIgnoreCase("log_click")) {
            String brand = tuple.getStringByField("brand");
            clickmap.put(brand, (clickmap.get(brand) != null ? clickmap.get(brand) : 0) + 1);
        }
        _collector.ack(tuple);
    }
    for(String brand : pvmap.keySet()){
        _collector.emit(new Values(
                new Object [] {brand, ((clickmap.get(brand) != null ? clickmap.get(brand) : 0)/(double)pvmap.get(brand))}));
    }
}

模式2: 精简模式

很多时候,实时处理的工作很简单,只是对输入的数据进行筛选、转换格式等,这时候可以用精简模式把代码了减到最少。
看看一个简单的Bolt可以有多简洁:
public class BriefBold extends BaseBasicBolt {

    @Override
    public void execute(Tuple tuple, BasicOutputCollector basicOutputCollector) {
        String v = tuple.getString(0);
        if (v == null || v.length() <= 5) {
        } else {
            basicOutputCollector.emit(new Values(v));
        }
    }

    @Override
    public void declareOutputFields(OutputFieldsDeclarer outputFieldsDeclarer) {
        outputFieldsDeclarer.declare(new Fields("value_out"));
    }
}

模式3:TOP N模式

实时地显示排名是个常见的需求,比如阿里巴巴的双十一,需要实时显示前10秒订单数Top 10的商家。这个时候的输入是商家名+成交单数的实时流,输出是排名前十的商家名和成交单数。

最简单的方法是计算并保存所有商家的成交单数,按单数排序并输出前10,可是如果商家非常多,如何“并行”计算呢?
TOP N 模式的逻辑是:首先按商家名进行“feildsGrouping", 可以设置很多个worker同时统计,每个worker保存它所看到的商家名和订单数,并维护一个topN列表,根据设置的实际间隔emit出topN的值。
下面再接一个”globalGrouping“, 也就是这个worker只接收潜在topN的商家信息,归并排序后即可得到最终的topN。

TopN的代码有点复杂,不在这里贴了,推荐一个帖子(storm starter 里演示topN功能的例子就是这个帖子的作者写的)
http://www.michael-noll.com/blog/2013/01/18/implementing-real-time-trending-topics-in-storm/

下面是几个实用工具

1 LRU cache:Least Recently Used Cache,当cache容量满了以后,删除最少使用的那个值。LRU cache 可以通过java自带的LinkedHashMap很方便地实现。

2 TimeCacheMap: 删除超过设定时间没有被更新的值

3 Tick tuple: 如何让spout/bolt定时地做一些事?比如隔几秒钟就把数据写入外部数据库,隔一段时间就上报目前的状态等。只需要简单价格配置
conf.put(Config.TOPOLOGY_TICK_TUPLE_FREQ_SECS, seconds);
就可以没隔设定的实际收到一个特殊的tuple,然后就可以在execute函数里做设定的定时动作了。


展开阅读全文

没有更多推荐了,返回首页