Distributed RPC
来源:互联网 发布:linux c编程 编辑:程序博客网 时间:2024/05/16 07:58
在distributedRPC (DRPC)中的思想是对Storm上许多Function计算的并行化。Stormtopology以function参数流作为输入,emits这些Function调用的结果作为输出。DRPC并不是Storm的特征,而是由Storm的primitive,即由streams,spouts, bolts, and topologies表达的pattern。DRPC被打包为独立于Storm的library,但非常有用以至于被Storm绑定。
概览
Distributed RPC由"DRPC server"协调,DRPC server协调接收一个RPC request,分发request给Storm topology,接收Storm topology的结果并发送结果给等待的client。DistributedRPC调用如同普通的RPCcall,比如,how a client如何计算带有参数"http://twitter.com"的function“reach”的结果:
DRPCClient client = new DRPCClient("drpc-host", 3772);String result = client.execute("reach", "http://twitter.com");
distributed RPC 工作流如下:
client向DRPCserver发送需要执行的function和arguments。topology使用DRPCSpout
从
DRPCserver
接收一个
Function
调用流,
每一个function调用被DRPC server打上unique id作为标签,topology计算结果,最后由topology最后一个名为ReturnResults
的
bolt连接DRPC server并返回Function调用id的结果。DRPCserver用此id匹配client正在等待的结果,unblocks等待的client并发送结果给它。
LinearDRPCTopologyBuilder
Storm中名为LinearDRPCTopologyBuilder的topology builder 自动完成DRPC调用几乎全部步骤:
设置spout
返回结果给DRPCserver
赋予bolts功能,为每组tuple实现最终的汇总操作
如下例,实现一个DRPCtopology,为输入参数添加"!":
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");//告诉topology需要执行的DRPC function名,DRPC server利用此名与其他Function调用相区分加以协调。builder.addBolt(new ExclaimBolt(), 3);//首个bolt带有2-tuple参数,request id和此request的参数;而最后一个bolt emit一个形如[id,result] 2-tuple的输出流;最后,所有中间tuple必须以request id作为第一个Field。 // ...}此例,ExclaimBolt为tuple的第二个field添加
"!",LinearDRPCTopologyBuilder处理
连接DRPC server和返回结果的协调工作。
Local mode DRPC
以上实例的在Local mode下:
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();
首先创建一个LocalDRPC
对象,在流程中它仿真DRPC server,正如LocalCluster
仿真Stormcluster。然后创建LocalCluster
在local mode下运行topology,
LinearDRPCTopologyBuilder
分别拥有创建localtopologies和remote topologies的方法。在localmode下,LocalDRPC
对象并不绑定任何port,topology知道它通信的对象。这是为什么createLocalTopology
以
LocalDRPC
对象作为输入。发起
topology
之后,
DRPC调用在LocalDRPC
上的
execute
方法。
Remote mode DRPC
在真实的Storm集群上使用DRPC:
发起DRPC server(s)
配置DRPCservers地址
在Storm集群上提交DRPC topologies
发起一个DRPCserver可由storm脚本完成,正如发起Nimbus或者UI:
bin/storm drpc
接下来,在Stormcluster中配置DRPCserver(s)的地址,由此DRPCSpout
知道在哪里读取
function invocations。这可由storm.yaml
文件或
topology configurations完成,storm.yaml
完成的配置如下:
drpc.servers: - "drpc1.foo.com" - "drpc2.foo.com"
最后,StormSubmitter
发起DRPCtopologies,以remote mode运行上例:
StormSubmitter.submitTopology("exclamation-drpc", conf, builder.createRemoteTopology());
createRemoteTopology
用于创建适于Storm clusters的topologies。
A more complex example
此例需要在Stormcluster上并行计算DRPCfunction。它计算Twitter上URL的reach,reach就是一个人在Twitter上打开此URL的次数,为此:
获取所有tweeted到此URL的人
获取这些人的所有followers
followers集合去重
计算followers集合唯一计数
计算过程中,需要调用上千次database calls并访问千万级的followerrecords,属于密集计算。在单机上,此计算需要花费数分钟;在Storm集群上,可在秒级完成最难的URLreach计算。定义reach 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"));
执行如下4steps:
GetTweeters
获取所有tweeted URL的用户,它转换输入流[id,url]
为输出流[id,tweeter]
,每一
url
tuple将匹配多个tweeter
tuples.GetFollowers
获取tweeters的followers。它转换输入流[id,tweeter]
为输出流[id,follower]
。
跨越所有的task,这必然存在重复的followertuples,因为一个人可以follow多个人去tweeted相同的URL。PartialUniquer
由followerid为followers流分组,有效的将相同的follower化入同一个task,PartialUniquer
的每一个task将接受彼此独立的followers集合,OncePartialUniquer
一旦为
requestid
直接接受所有的
followertuples,则emit此followers子集合的去重计数。最后,
CountAggregator
接受每个
PartialUniquer
部分计数并作总计。
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
,
batchbolt提供API将批量tuples作为一个实际单位进行处理,为每一个requestid创建一个batchbolt的新实例,Storm在适当的时候负责清理实例。
PartialUniquer
的
execute
函数接受一
follower tuple并将之加入到为此requestid设置的HashSet
。
finishBatch
函数在本task批处理完成后调用,PartialUniquer
emits一单个tuple,其中包含follower ids的子集和它的去重计数。
在底层,CoordinatedBolt
用于知道一个给定的
bolt
何时接受到一
requestid
对应的所有
tuples
,
CoordinatedBolt
使用
directstreams
来管理此协调。
Non-linear DRPC topologies
LinearDRPCTopologyBuilder
仅处理线性
DRPCtopologies,其计算为一序列步骤,直接利用CoordinatedBolt
,
因此不能胜任解决bolt之间的分支、合并等复杂计算。
- Distributed RPC
- Distributed RPC(分布式RPC)-Storm
- Twitter Storm Distributed RPC
- Using Hadoop IPC/RPC for distributed applications
- Distributed Computing Environment/Remote Procedure Call (DCE/RPC)
- Storm Distributed RPC(DRPC)分布式远程过程调用
- RPC
- RPC
- RPC
- RPC
- RPC
- RPC
- RPC
- RPC
- RPC
- RPC
- RPC
- rpc
- UglyNumbers
- 取巧获取整个页面的高度
- html中空元素的写法问题
- STL 学习1
- QML官方系列教程——Qt Quick Dialogs
- Distributed RPC
- 枚举,结构,类
- 算法6-1:哈希函数
- 《hadoop 权威指南》 学习笔记(2)Hadoop 分布式文件系统
- window 2012 VDI之 快速部署(基于会话)
- c++中const成员变量赋值问题
- LeetCode Longest Palindromic Substring
- android代码设置EditText只输入数字、字母
- 算法6-2:解决哈系冲突之独立链表