5. Storm高级篇

序列化

分布式RPC

High level overview

LinearDRPCTopologyBuilder

Local mode DRPC

Remote mode DRPC

更复杂的例子

Non-linear DRPC topologies

LinearDRPCTopologyBuilder如何起作用

Advanced



分布式RPC

分布式 RPC(DRPC)的设计目标是充分利用 Storm 的计算能力实现高密度的并行实时计算。Storm 接收若干个函数参数作为输入流,然后通过 DRPC 输出这些函数调用的结果。严格来说,DRPC 并不能算作是 Storm 的一个特性,因为它只是一种基于 Storm 原语 (Stream、Spout、Bolt、Topology) 实现的计算模式。虽然可以将 DRPC 从 Storm 中打包出来作为一个独立的库,但是与 Storm 集成在一起显然更有用。

High level overview

分布式RPC是通过“DRPC server”协调处理的(Storm用一个包来实现该功能)。DRPC server 负责接收 RPC 请求,并将该请求发送到 Storm 中运行的 Topology,等待接收 Topology 发送的处理结果,并将该结果返回给发送请求的客户端。因此,从客户端的角度来说,DPRC 与普通的 RPC 调用并没有什么区别。例如,以下是一个使用参数 “http://twitter.com” 调用 “reach” 函数计算结果的例子:

DRPCClient client = new DRPCClient("drpc-host", 3772);
String result = client.execute("reach", "http://twitter.com");

分布式RPC工作流示意图如下所示:

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

LinearDRPCTopologyBuilder

Storm中提供了名为LinearDRPCTopologyBuilder 的topology builder,它几乎自动完成了DRPC的所有步骤,如下所示:

1.设置spout

2.向DRPC server返回运行结果。

3.给bolts提供了聚集元组的功能。

让我们一起看一下简单的例子,该例子是DRPC topology的一个实现并返回结果为输入附加字符串“!”。

public static class ExclaimBolt extends BaseBasicBolt {
public void execute(Tuple tuple, BasicOutputCollector collector) {
String input = tuple.getString(1);
collector.emit(new Values(tuple.getValue(0), input + "!"));
} public void declareOutputFields(OutputFieldsDeclarer declarer) {
declarer.declare(new Fields("id", "result"));
}}
public static void main(String[] args) throws Exception {
LinearDRPCTopologyBuilder builder = new LinearDRPCTopologyBuilder("exclamation");
builder.addBolt(new ExclaimBolt(), 3);
// ...}

正如你所见,当创建LinearDRPCTopologyBuilder 时,你需要让topology知道 DRPC函数的名字。单个DRPC server负责很多函数的协调处理,且这些函数的功能不同。你声明的第一个bolt将接受一个2元组,第一个域是请求id,第二个域是请求参数。LinearDRPCTopologyBuilder 中最后一个bolt会输出形式为[id,result]的2元组输出流。最后,所有中间结果的元组的第一个域必须包括请求id。

在本例子中,ExclaimBolt 只是简单地给第二个域附加字符串“!”。LinearDRPCTopologyBuilder 继续和DRPC server通信并将结果返回。

Local mode DRPC

DRPC可以以本地模式运行,下面以本地模式运行的例子:

LocalDRPC drpc = new LocalDRPC();
LocalCluster cluster = new LocalCluster();
cluster.submitTopology("drpc-demo", conf, builder.createLocalTopology(drpc));
System.out.println("Results for 'hello':" + drpc.execute("exclamation", "hello"));
cluster.shutdown();
drpc.shutdown();

首先你会创建一个 LocalDPRC 对象,该对象会在进程中模拟一个 DRPC 服务器,就像LocalCluster 在进程中模拟 Storm 集群的功能一样。然后,创建LocalCluster以本地模式运行topology 。LinearDRPCTopologyBuilder 有独立的方法用于创建本地topologies 和远程topologies 。在本地模式下,LocalDRPC 对象没有绑定任何端口所以topology需要知道正在和它进行通信的对象,这是方法createLocalTopology 接受LocalDRPC 对象作为输入参数的原因。

在启动拓扑后,你可以使用 execute 方法来完成 DRPC 调用。

Remote mode DRPC

在一个真实的集群中使用 DRPC 有以下三个步骤:

1.启动 DRPC Server;

2.配置 DRPC Server的地址;

3.将 DRPC topologies 提交到集群运行。

可以像 Nimbus、Supervisor 那样使用 storm 命令来启动 DRPC Serve,如下:

bin/storm drpc

接下来,你需要在集群上配置 DRPC Server的地址。这是为了让 DRPCSpout 获取从哪里触发函数调用的方法。可以通过编辑 storm.yaml 或者添加拓扑配置的方式实现配置。配置 storm.yaml 的方式类似于下面这样:

drpc.servers:
- "drpc1.foo.com"
- "drpc2.foo.com"

最后,你可以像其他拓扑一样使用 StormSubmitter 来启动拓扑。以下是使用远程模式构造拓扑的一个例子:

StormSubmitter.submitTopology("exclamation-drpc", conf, builder.createRemoteTopology());

createRemoteTopology 方法是用来创建集群模式下运行的topologies 。

更复杂的例子

上面描述的exclamation DRPC是为了说明DRPC的简单例子。下面让我们共同学习一下更复杂的例子-Storm集群并行计算的DRPC函数调用,该例子是计算Twitter上URL的访问。

URL访问是指不同的人在Twitter上发的推文,你需要完成如下计算:

1.获取所有tweeted了该URL的所有人。

2.获取所有关注了1中的所有人。

3.2中所有人的set集合。

4.统计3中set集合的个数。

一次计算可能涉及上百次的数据库调用和数以千万计的关注记录,这计算规模确实很大。正如你所见,实现Storm函数是非常简单的。在单台机器上,计算需要1分钟;但在集群中,即使最难计算的URL访问也只需数秒。

一个简单的访问topology 可以在storm-starter中找到。下面是定义访问topology 的具体步骤:

LinearDRPCTopologyBuilder builder = new LinearDRPCTopologyBuilder("reach");
builder.addBolt(new GetTweeters(), 3);
builder.addBolt(new GetFollowers(), 12)
.shuffleGrouping();builder.addBolt(new PartialUniquer(), 6)
.fieldsGrouping(new Fields("id", "follower"));
builder.addBolt(new CountAggregator(), 2)
.fieldsGrouping(new Fields("id"));

topology 的执行按照以下四步骤:

1.GetTweeters 得到tweeted了URL的用户。它将[id,url]格式的输入流转换为[id,tweeter]格式的输出流。每个url将映射为多个tweeter元组。

2.GetFollowers得到tweeters的关注者。它将[id,tweeter]格式的输入流转换为[id,follower]格式的输出流。这些任务中,可能有重复的元组,因为一些人可能关注了多个人都tweeted了同样的URL。

3.PartialUniquer根据关注者id分组。这会导致同样的关注者在同样的任务中处理,所以每个PartialUniquer 的任务将会接受多个互补的关注者集合。一旦PartialUniquer 接受了所有的关注者元组,它将会输出关注者子集合元素的个数。

4.最后,CountAggregator 从PartialUniquer 接受部分count值然后累加完成整个计算,并返回结果。

下面看PartialUniquer bolt的代码实现:

public class PartialUniquer extends BaseBatchBolt {
BatchOutputCollector _collector;
Object _id;
Set<String> _followers = new HashSet<String>(); @Override
public void prepare(Map conf, TopologyContext context, BatchOutputCollector collector, Object id) {
_collector = collector;
_id = id;
} @Override
public void execute(Tuple tuple) {
_followers.add(tuple.getString(1));
} @Override
public void finishBatch() {
_collector.emit(new Values(_id, _followers.size()));
} @Override
public void declareOutputFields(OutputFieldsDeclarer declarer) {
declarer.declare(new Fields("id", "partial-count"));
}}

PartialUniquer 通过继承BaseBatchBolt 间接实现了IBatchBolt 接口。batch bolt提供了第一个类API,用于将一批元组作为一个具体单元进行处理。对于每个请求id,会创建一个新的batch bolt实例,在适当时候Storm也会清理这些实例。

当PartialUniquer 在execute方法中接受了一个关注者元组时,会将该元组添加到请求id的set集合中。

当任务中的一批元组处理完成后会调用batch bolts的finishBatch 方法,该方法输出关注者id集合元素个数形式的一元组。在后台,CoordinatedBolt 用来监测何时给定bolt已经接受到了请求id所有的元组,它用direct stream来管理。

topology 中剩下的部分都能很容易明白,正如你看到的,每个访问计算步骤都是并行完成的,并且定义DRPC topology是非常简单的。

Non-linear DRPC topologies

LinearDRPCTopologyBuilder 只处理线性DRPC的topology,它的计算是一个序列步骤。不难想象功能需求将需要更复杂的topology ,它可能涉及到bolts的分支与整合。

LinearDRPCTopologyBuilder如何起作用

DRPCSpout 发送[args,return-info]元组。return-info是DRPC server的主机名、端口号和生成的id。

topology的构造参数包括:

DRPCSpout

PrepareRequest (生成请求id和创建返回信息stream和参数stream)

CoordinatedBolt wrappers and direct groupings

JoinResult (返回信息进行join操作)

ReturnResult (连接到DRPC server并返回结果)

LinearDRPCTopologyBuilder 是一个很好的例子

Advanced

KeyedFairBolt 同时处理多个请求。

如何直接使用CoordinatedBolt。

【原】Storm分布式RPC的更多相关文章

  1. Storm常见模式——分布式RPC

    Storm常见模式——分布式RPC 本文翻译自:https://github.com/nathanmarz/storm/wiki/Distributed-RPC,作为学习Storm DRPC的资料,转 ...

  2. Storm分布式实时流计算框架相关技术总结

    Storm分布式实时流计算框架相关技术总结 Storm作为一个开源的分布式实时流计算框架,其内部实现使用了一些常用的技术,这里是对这些技术及其在Storm中作用的概括介绍.以此为基础,后续再深入了解S ...

  3. 基于Storm 分布式BP神经网络,将神经网络做成实时分布式架构

    将神经网络做成实时分布式架构: Storm 分布式BP神经网络:    http://bbs.csdn.net/topics/390717623 流式大数据处理的三种框架:Storm,Spark和Sa ...

  4. [源码解析] PyTorch 分布式(15) --- 使用分布式 RPC 框架实现参数服务器

    [源码解析] PyTorch 分布式(15) --- 使用分布式 RPC 框架实现参数服务器 目录 [源码解析] PyTorch 分布式(15) --- 使用分布式 RPC 框架实现参数服务器 0x0 ...

  5. 基于netty轻量的高性能分布式RPC服务框架forest<下篇>

    基于netty轻量的高性能分布式RPC服务框架forest<上篇> 文章已经简单介绍了forest的快速入门,本文旨在介绍forest用户指南. 基本介绍 Forest是一套基于java开 ...

  6. 基于netty轻量的高性能分布式RPC服务框架forest<上篇>

    工作几年,用过不不少RPC框架,也算是读过一些RPC源码.之前也撸过几次RPC框架,但是不断的被自己否定,最近终于又撸了一个,希望能够不断迭代出自己喜欢的样子. 顺便也记录一下撸RPC的过程,一来作为 ...

  7. 一个轻量级分布式RPC框架--NettyRpc

    1.背景 最近在搜索Netty和Zookeeper方面的文章时,看到了这篇文章<轻量级分布式 RPC 框架>,作者用Zookeeper.Netty和Spring写了一个轻量级的分布式RPC ...

  8. 轻量级分布式 RPC 框架

    @import url(/css/cuteeditor.css); 源码地址:http://git.oschina.net/huangyong/rpc RPC,即 Remote Procedure C ...

  9. 基于开源Dubbo分布式RPC服务框架的部署整合

    一.前言 Dubbo 作为SOA服务化治理方案的核心框架,用于提高业务逻辑的复用.整合.集中管理,具有极高的可靠性(HA)和伸缩性,被应用于阿里巴巴各成员站点,同时在包括JD.当当在内的众多互联网项目 ...

随机推荐

  1. Intellij IDEA调试功能

    public class Demo { public static void f1() { System.out.println("one"); System.out.printl ...

  2. 写出优秀论文How To Write A Great Essay About Anything

    There is an assumption in the world that an essay is something literary you write for school about a ...

  3. 结构体struct和typedef后面接指针的含义

    typedef struct file { ... }FileInfo, *FileP; 上述程序中定义了一个结构体,结构体的名字为file,并且给其指针 取个别名为FileP,所以后续程序中出现Fi ...

  4. Codeforces Round #207 (Div. 1)B(数学)

    数学so奇妙.. 这题肯定会有一个循环节 就是最小公倍数 对于公倍数内的相同的数的判断 就要借助最大公约数了 想想可以想明白 #include <iostream> #include< ...

  5. 函数buf_LRU_old_adjust_len

    调整LUR_old位置,放到八分之五位置,是新的,后八分之三是旧的 512个页全变成新的,然后从后往前数,数到8分之3,设置为旧的 /********************************* ...

  6. Qt之自定义界面(右下角冒泡)

    简述 网页右下角上经常会出现一些提示性的信息,桌面软件中也比较常见,类似360新闻.QQ消息提示一样! 这种功能用动画实现起来很简单,这节我们暂时使用定时器来实现,后面章节会对动画框架进行详细讲解. ...

  7. Asp.Net MVC Views页面不包含“GetEnumerator”的公共定义

    “/”应用程序中的服务器错误. 编译错误 说明: 在编译向该请求提供服务所需资源的过程中出现错误.请检查下列特定错误详细信息并适当地修改源代码. 编译器错误消息: CS1579: “Web.Model ...

  8. php和java的一些比较

    现在市场上的电子商务软件基本上可归结为两大阵营,即PHP阵营和Java阵营.但对接触电子商务不久的用户来说,看到的往往只是它们的表相,只是明显的价格差异,却很难看出它们之间的实际差异.其实,PHP+ ...

  9. HDU 1150 Machine Schedule (最小覆盖,匈牙利算法)

    题意: 有两台不同机器A和B,他们分别拥有各种运行模式1~n和1~m.现有一些job,需要在某模式下才能完成,job1在A和B上需要的工作模式又可能会不一样.两台机器一开始处于0模式,可以切换模式,但 ...

  10. angular js 指令的数据传递 及作用域数据绑定

    <div my-directive my-url="http://google.com" my-link-text="Click me to go to Googl ...