• storm 事务和DRPC结合


    示例代码:

    package com.lky.topology;
    
    import backtype.storm.Config;
    import backtype.storm.LocalCluster;
    import backtype.storm.LocalDRPC;
    import backtype.storm.coordination.BatchOutputCollector;
    import backtype.storm.drpc.LinearDRPCTopologyBuilder;
    import backtype.storm.task.TopologyContext;
    import backtype.storm.topology.BasicOutputCollector;
    import backtype.storm.topology.OutputFieldsDeclarer;
    import backtype.storm.topology.base.BaseBasicBolt;
    import backtype.storm.topology.base.BaseBatchBolt;
    import backtype.storm.tuple.Fields;
    import backtype.storm.tuple.Tuple;
    import backtype.storm.tuple.Values;
    import backtype.storm.utils.Utils;
    
    import java.util.*;
    
    import org.apache.commons.logging.Log;
    import org.apache.commons.logging.LogFactory;
    
    
    /**
     * @Title: ReachTopology.java
     * @Package com.lky.topology
     * @Description: 计算一个包含特定url的微博,最终能被多少人看到
     * @author lky
     * @date 2015年10月23日 下午9:09:22
     * @version V1.0
     */
    public class ReachTopology {
        private static Log log = LogFactory.getLog(ReachTopology.class);
        public static Map<String, List<String>> TWEETERS_DB = new HashMap<String, List<String>>() {
            {
                put("foo.com/blog/1", Arrays.asList("sally", "bob", "tim", "george", "nathan"));
                put("engineering.twitter.com/blog/5", Arrays.asList("adam", "david", "sally", "nathan"));
                put("tech.backtype.com/blog/123", Arrays.asList("tim", "mike", "john"));
            }
        };
    
        public static Map<String, List<String>> FOLLOWERS_DB = new HashMap<String, List<String>>() {
            {
                put("sally", Arrays.asList("bob", "tim", "alice", "adam", "jim", "chris", "jai"));
                put("bob", Arrays.asList("sally", "nathan", "jim", "mary", "david", "vivian"));
                put("tim", Arrays.asList("alex"));
                put("nathan", Arrays.asList("sally", "bob", "adam", "harry", "chris", "vivian", "emily", "jordan"));
                put("adam", Arrays.asList("david", "carissa"));
                put("mike", Arrays.asList("john", "bob"));
                put("john", Arrays.asList("alice", "nathan", "jim", "mike", "bob"));
            }
        };
    
        /**
         * @Title: ReachTopology.java
         * @Package com.lky.topology
         * @Description: 获取包含该特定url的所有用户,随机发放到下游bolt中
         * @author lky
         * @date 2015年10月23日 下午11:46:19
         * @version V1.0
         */
        @SuppressWarnings("serial")
        public static class GetTweeters extends BaseBasicBolt {
    
            @Override
            public void execute(Tuple input, BasicOutputCollector collector) {
                Object id = null;
                String url = null;
                try {
                    id = input.getValue(0);
                    url = input.getString(1);
                    List<String> tweeters = new ArrayList<String>();//获取包含该url的所有用户
    
                    if (null != id && null != url) {
                        tweeters = TWEETERS_DB.get(url);
                        if (null != tweeters) {
                            for (String tweeter : tweeters) {
                                log.info("execute1------>[id = " + id + " ]["+url+"---->tweeter=" + tweeter + "]");
                                collector.emit(new Values(id, tweeter));
                            }
                        }
                    }
                } catch (Exception e) {
                    log.error("execute 发射消息错误!!!!!");
                }
            }
    
            @Override
            public void declareOutputFields(OutputFieldsDeclarer declarer) {
                declarer.declare(new Fields("id", "tweeter"));
            }
    
        }
    
        /**
         * @Title: ReachTopology.java
         * @Package com.lky.topology
         * @Description:获取每一个用户的粉丝,然后按字段分组(id,fllower)到下游bolt中,保证同一类url的相同用户被分到相同的批次
         * @author lky
         * @date 2015年10月23日 下午11:47:45
         * @version V1.0
         */
        @SuppressWarnings("serial")
        public static class GetFollowers extends BaseBasicBolt {
    
            @Override
            public void execute(Tuple input, BasicOutputCollector collector) {
                Object id = null;
                String _follower = null;
    
                try {
                    id = input.getValue(0);
                    _follower = input.getString(1);
                    List<String> followers = new ArrayList<String>();
    
                    if (null != id && null != _follower) {
                        followers = FOLLOWERS_DB.get(_follower);//获取该用户的所有粉丝
                        if (null != followers) {
                            for (String follower : followers) {
                                log.info("execute2------>[id = " + id + " ]["+_follower+"------>follower=" + follower + "]");
                                collector.emit(new Values(id, follower));
                            }
                        }
                    }
    
                } catch (Exception e) {
                    log.error("execute 发射消息异常!!!");
                }
    
            }
    
            @Override
            public void declareOutputFields(OutputFieldsDeclarer declarer) {
                declarer.declare(new Fields("id", "follower"));
            }
    
        }
    
        /**
         * @Title: ReachTopology.java
         * @Package com.lky.topology
         * @Description: 按批次统计粉丝数量
         * @author lky
         * @date 2015年10月23日 下午11:50:51
         * @version V1.0
         */
        @SuppressWarnings({ "serial", "rawtypes" })
        public static class PartialUniquer extends BaseBatchBolt {
            private BatchOutputCollector collector;
            private Object id;
            private Set<String> _followerSet = new HashSet<String>();
    
            @Override
            public void prepare(Map conf, TopologyContext context, BatchOutputCollector collector, Object id) {
                this.collector = collector;
                this.id = id;
            }
    
            @Override
            public void execute(Tuple tuple) {
                String uname = null;
    
                try {
                    uname = tuple.getString(1);
                    if (null != uname) {
                        log.info("execute3------>[id = " + tuple.getValue(0) + " ][ uname=" + uname + "]");
                        _followerSet.add(uname);
                    }
                } catch (Exception e) {
                    log.error("execute 接收消息异常!!!");
                }
            }
    
            @Override
            public void finishBatch() {
                log.info("execute4------>[id = " + id + " ][ size=" + _followerSet.size() + "]");
                collector.emit(new Values(id, _followerSet.size()));
            }
    
            @Override
            public void declareOutputFields(OutputFieldsDeclarer declarer) {
                declarer.declare(new Fields("id", "count"));
            }
    
        }
    
        /**
         * @Title: ReachTopology.java
         * @Package com.lky.topology
         * @Description: 按相同的id汇总批次
         * @author lky
         * @date 2015年10月23日 下午11:51:49
         * @version V1.0
         */
        @SuppressWarnings({ "serial", "rawtypes" })
        public static class CountAggregator extends BaseBatchBolt {
            private BatchOutputCollector collector;
            private Object id;
            private int _count = 0;
    
            @Override
            public void prepare(Map conf, TopologyContext context, BatchOutputCollector collector, Object id) {
                this.collector = collector;
                this.id = id;
            }
    
            @Override
            public void execute(Tuple tuple) {
                Integer count = null;
                try {
                    count = tuple.getInteger(1);
                    log.info("execute5------>[id = " + tuple.getValue(0) + " ][ count=" + count + "]");
                    _count += count;
                } catch (Exception e) {
                    log.error("execute 接收消息异常");
                }
            }
    
            @Override
            public void finishBatch() {
                collector.emit(new Values(id, _count));
            }
    
            @Override
            public void declareOutputFields(OutputFieldsDeclarer declarer) {
                declarer.declare(new Fields("id", "result"));
            }
        }
    
        @SuppressWarnings("deprecation")
        public static LinearDRPCTopologyBuilder construct() {
            LinearDRPCTopologyBuilder builder = new LinearDRPCTopologyBuilder("reach");
            builder.addBolt(new GetTweeters(), 4);
            builder.addBolt(new GetFollowers(), 12).shuffleGrouping();
            builder.addBolt(new PartialUniquer(), 6).fieldsGrouping(new Fields("id", "follower"));
            builder.addBolt(new CountAggregator(), 3).fieldsGrouping(new Fields("id"));
            return builder;
        }
    
        @SuppressWarnings("deprecation")
        public static void main(String[] args) {
            LinearDRPCTopologyBuilder builder = construct();
    
            Config conf = new Config();
            conf.setMaxTaskParallelism(3);
            LocalDRPC drpc = new LocalDRPC();
            LocalCluster cluster = new LocalCluster();
            cluster.submitTopology("reach-drpc", conf, builder.createLocalTopology(drpc));
    
            String[] urlsToTry = new String[] { "foo.com/blog/1", "engineering.twitter.com/blog/5", "notaurl.com" };
            for (String url : urlsToTry) {
                System.out.println("Reach of " + url + ": " + drpc.execute("reach", url));
            }
    
            Utils.sleep(1000 * 10);
            cluster.shutdown();
            drpc.shutdown();
        }
    }
  • 相关阅读:
    (转)ELK Stack 中文指南--性能优化
    (转)如何在CentOS / RHEL 7上安装Elasticsearch,Logstash和Kibana(ELK)
    (转)GlusterFS 01 理论基础,企业实战,故障处理
    (转)CentOS7.4环境下搭建--Gluster分布式集群存储
    (转)DB2性能优化 – 如何通过调整锁参数优化锁升级
    (转)架构师之DNS实战CentOS7VSCentOS6
    PHP:计算文件或数组中单词出现频率
    [获取行数]php读取大文件提供性能的方法,PHP的stream_get_line函数读取大文件获取文件的行数的方...
    Windows下配置环境变量和需不需要重启问题
    CENTOS 下安装APK反编译工具 APKTOOL
  • 原文地址:https://www.cnblogs.com/dmir/p/4906210.html
Copyright © 2020-2023  润新知