一、DRPC简介和工作流程
1、 DRPC 简介
分布式RPC( distributed RPC,DRPC) 用于对storm上大量的函数调用进行并行计算。对于每一次函数调用,storm集群上运行的拓扑接收调用函数的参数信息作为输入流,并将计算结果作为输出流发射出去。
一句话概括:storm进行计算,根据客户端提交的请求参数,而返回storm计算的结果。
DRPC通过DRPC Server来实现,DRPC Server的整体工作过程如下:
接收到一个 RPC 调用请求;
发送请求到storm上的拓扑;
从storm上接收计算结果;
将计算结果返回给客户端;
注:在client客户端来看,一个DRPC调用看起来和普通的RPC调用没什么区别;
2、工作流程
DRPC的工作流程如下
client客户端给DRPC Server发送要被调用执行DRPC函数名称及参数。
storm上的topology通过DRPC Spout实现这一函数,从DRPC Server接收到函数调用流,DRPC Server为每次函数调用生成唯一的id;
storm上运行的Topology开始计算结果,最后通过一个 ReturnResults 的Bolt连接到DRPC服务器,发送指定id的计算结果给DRPC Server。
DRPC Server 通过使用之前为每个函数调用生成的id,将结果关联到对应的发起调用的client,将计算结果返回给client。
3、LinearDRPCTopologyBuilder类
LinearDRPCTopologyBuilder 类是官方封装好的,专门用于DRPC的builder,但是从 storm0.82 已经不推荐使用该类,原因是因为在trident已经有更好的封装;
Storm自带了一个称作 LinearDRPCTopologyBuilder 的topology builder, 它把实现DRPC的几乎所有步骤都自动化了。
包括:
1. 构建spout;
2. 向DRPC Server返回结果;
3. 为bolt提供函数用于对tuple进行处理;
二、官方DRPC入门案例
在官方给出的storm-starter-master工程,storm.starter包,有DRPC案例;
1、BasicDRPCTopology案例
用官方封装好的 LinearDRPCTopologyBuilder 类,比较简单。本地提交。
package storm.starter;
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;
/**
* This topology is a basic example of doing distributed RPC on top of Storm. It implements a function that appends a
* "!" to any string you send the DRPC function.
* <p/>
* See https://github.com/nathanmarz/storm/wiki/Distributed-RPC for more information on doing distributed RPC on top of
* Storm.
*/
public class BasicDRPCTopology {
public static class ExclaimBolt extends BaseBasicBolt {
@Override
public void execute(Tuple tuple, BasicOutputCollector collector) {
String input = tuple.getString(1);
// 发射的第一列是请求id,第二列是数据。对收到的数据加上 "!" 之后返回到 DRPC Server,
collector.emit(new Values(tuple.getValue(0),