zoukankan      html  css  js  c++  java
  • 【Storm篇】--Storm中的同步服务DRPC

    一、前述

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

    二、具体原理

    DRPC 是通过一个 DRPC 服务端(DRPC server)来实现分布式 RPC 功能的。
    DRPC Server 负责接收 RPC 请求,并将该请求发送到 Storm中运行的 Topology,等待接收 Topology 发送的处理结果,并将该结果返回给发送请求的客户端。
    (其实,从客户端的角度来说,DPRC 与普通的 RPC 调用并没有什么区别。

    DRPC设计目的是为了充分利用Storm的计算能力实现高密度的并行实时计算。
    (Storm接收若干个数据流输入,数据在Topology当中运行完成,然后通过DRPC将结果进行输出。)

    流程图如下:

    解释:

    客户端通过向 DRPC 服务器发送待执行函数的名称以及该函数的参数来获取处理结果。实现该函数的拓扑使用一个DRPCSpout 从 DRPC 服务器中接收一个函数调用流DRPC 服务器会为每个函数调用都标记了一个唯一的 id。随后拓扑会执行函数来计算结果,并在拓扑的最后使JoinResult的Bolt实现数据的聚合, ReturnResults 的 bolt 连接到 DRPC 服务器,根据函数调用的 id 来将函数调用的结果返回。

    三、实现方式

     方法1.

    通过LinearDRPCTopologyBuilder (该方法也过期,不建议使用)
    该方法会自动为我们设定Spout、将结果返回给DRPC Server等,我们只需要将Topology实现

    package com.sxt.storm.drpc;
    
    import backtype.storm.Config;
    import backtype.storm.LocalCluster;
    import backtype.storm.LocalDRPC;
    import backtype.storm.StormSubmitter;
    import backtype.storm.drpc.LinearDRPCTopologyBuilder;
    import backtype.storm.topology.BasicOutputCollector;
    import backtype.storm.topology.OutputFieldsDeclarer;
    import backtype.storm.topology.base.BaseBasicBolt;
    import backtype.storm.tuple.Fields;
    import backtype.storm.tuple.Tuple;
    import backtype.storm.tuple.Values;
    
    
    public class BasicDRPCTopology {
        public static class ExclaimBolt extends BaseBasicBolt {
            @Override
            public void execute(Tuple tuple, BasicOutputCollector collector) {
                String input = tuple.getString(1);
                collector.emit(new Values(tuple.getValue(0), input + "!"));
            }
    
            @Override
            public void declareOutputFields(OutputFieldsDeclarer declarer) {
                declarer.declare(new Fields("id", "result"));
            }
    
        }
    
        public static void main(String[] args) throws Exception {
            LinearDRPCTopologyBuilder builder = new LinearDRPCTopologyBuilder("exclamation");//通过LinearDRPCTopologyBuilder 定义拓扑 //exclamation是函数名称
            builder.addBolt(new ExclaimBolt(), 3);
    
            Config conf = new Config();
    
            if (args == null || args.length == 0) {
                LocalDRPC drpc = new LocalDRPC();
                LocalCluster cluster = new LocalCluster();
    
                cluster.submitTopology("drpc-demo", conf, builder.createLocalTopology(drpc));//这是拓扑名称
    
                for (String word : new String[] { "hello", "goodbye" }) {
                    System.err.println("Result for "" + word + "": " + drpc.execute("exclamation", word));
                }
    
                cluster.shutdown();
                drpc.shutdown();
            } else {
                conf.setNumWorkers(3);
                StormSubmitter.submitTopologyWithProgressBar(args[0], conf, builder.createRemoteTopology());
            }
        }
    }

    方法2:

    直接通过普通的拓扑构造方法TopologyBuilder来创建DRPC拓扑
    需要手动设定好开始的DRPCSpout以及结束的ReturnResults

    package com.sxt.storm.drpc;
    
    import backtype.storm.Config;
    import backtype.storm.LocalCluster;
    import backtype.storm.LocalDRPC;
    import backtype.storm.drpc.DRPCSpout;
    import backtype.storm.drpc.ReturnResults;
    import backtype.storm.topology.BasicOutputCollector;
    import backtype.storm.topology.OutputFieldsDeclarer;
    import backtype.storm.topology.TopologyBuilder;
    import backtype.storm.topology.base.BaseBasicBolt;
    import backtype.storm.tuple.Fields;
    import backtype.storm.tuple.Tuple;
    import backtype.storm.tuple.Values;
    
    public class ManualDRPC {
        public static class ExclamationBolt extends BaseBasicBolt {
    
            @Override
            public void declareOutputFields(OutputFieldsDeclarer declarer) {
                declarer.declare(new Fields("result", "return-info"));
            }
    
            @Override
            public void execute(Tuple tuple, BasicOutputCollector collector) {
                String arg = tuple.getString(0);
                Object retInfo = tuple.getValue(1);
                collector.emit(new Values(arg + "!!!", retInfo));
            }
    
        }
    
        public static void main(String[] args) {
            TopologyBuilder builder = new TopologyBuilder();
            LocalDRPC drpc = new LocalDRPC();
    
            DRPCSpout spout = new DRPCSpout("exclamation", drpc);//自定义drpc spout
            builder.setSpout("drpc", spout);
            builder.setBolt("exclaim", new ExclamationBolt(), 3).shuffleGrouping("drpc");
            builder.setBolt("return", new ReturnResults(), 3).shuffleGrouping("exclaim");//自定义结束的ReturnResults
    LocalCluster cluster
    = new LocalCluster(); Config conf = new Config(); cluster.submitTopology("exclaim", conf, builder.createTopology()); System.err.println(drpc.execute("exclamation", "aaa")); System.err.println(drpc.execute("exclamation", "bbb")); } }

     四、Storm运行模式

    1、本地模式

        public static void main(String[] args) {
            TopologyBuilder builder = new TopologyBuilder();
            LocalDRPC drpc = new LocalDRPC();
    
            DRPCSpout spout = new DRPCSpout("exclamation", drpc);
            builder.setSpout("drpc", spout);
            builder.setBolt("exclaim", new ExclamationBolt(), 3).shuffleGrouping("drpc");
            builder.setBolt("return", new ReturnResults(), 3).shuffleGrouping("exclaim");
    
            LocalCluster cluster = new LocalCluster();
            Config conf = new Config();
            cluster.submitTopology("exclaim", conf, builder.createTopology());
    
            System.err.println(drpc.execute("exclamation", "aaa"));
            System.err.println(drpc.execute("exclamation", "bbb"));
    
        }

     2.远程模式(集群模式)

    修改配置文件conf/storm.yaml
    drpc.servers:
        - "node1“

    启动DRPC Server
    bin/storm drpc &

    通过StormSubmitter.submitTopology提交拓扑

    public static void main(String[] args) {
            
    
            DRPCClient client = new DRPCClient("node1", 3772);//通信端口
            
            try {
                String result = client.execute("exclamation", "11,22");
                
                System.out.println(result);
            } catch (TException e) {
                e.printStackTrace();
            } catch (DRPCExecutionException e) {
                e.printStackTrace();
            } 

    总结:Drpc分布式远程调用帮我们

    1、 实现了drpcSpout用来向后发送数据,我们只需要传参即可。

    2、 实现了最后的JoinResult用来汇合结果,ReturnResult用来将结果返回客户端。从而达到实时的目的。

    3.、我们可以修改并行度,使集群的并行计算能力达到最优,主要实现并行计算。

     

  • 相关阅读:
    数据库连接池的作用及c3p0的详解(转载他人的--合理掌握学习方式)
    JAVA读取propertise文件内容两种方式(起始还是有很多种的)
    servlet--生命周期
    UML学习(三)-----序列图
    UML学习(一)-----用例图
    UML学习(二)-----类图
    Java静态域与静态方法
    spring boot启动原理三(结合web容器,如:tomcat(默认),jetty)
    spring源码相关第五篇----------------------------spring tx实现原理源码解读
    spring源码相关第四篇----------------------------spring aop实现原理源码解读
  • 原文地址:https://www.cnblogs.com/LHWorldBlog/p/8353706.html
Copyright © 2011-2022 走看看