我目前正在尝试在多个节点上运行一些Elixir代码,我已经使用了两种方法: 1) :rpc.multicall/4 & 2) :rpc.pmap/3。
我可以看到两者都在多个节点上运行代码,并且我知道这些调用的结果是不同的(tuple vs list)。
这两个函数之间是否还有其他重要的区别,或者这两个函数是否等价,唯一的区别在于它们的调用方式和返回值?
提前感谢!
发布于 2017-03-13 05:08:27
它们真的彼此不同,
pmap将执行类似于:list.map (这里更多是http://erlang.org/doc/man/lists.html)的映射,但其优点是,只要节点可用、已连接并且列表中有值可供执行映射,此调用就会在节点之间发生。
其他方式的multicall将始终执行相同的调用,在多个节点中使用相同的参数。multicall/4在所有连接的节点中执行相同的函数调用。rpc在开头有一个额外的参数,即将执行multicall/5的节点的列表。
当我们有一个由3个shell组成的集群时,更好地举例说明
iex --sname node1iex --sname node2iex --sname node3然后我们在node1执行时相互连接
Node.connect :"node2@mymachine"
# => false
Node.connect :"node3@mymachine"
# => false我们可以定义一个函数,它将2个值相加,并返回执行此操作的节点的值,如下所示:
iex(node1@mymachine)> defmodule Operation do
...(node1@mymachine)> def sum(a, b), do: {Node.self(), a + b}
...(node1@mymachine)> end有必要在每个shell中定义这个函数。因此,现在可以只用多个值调用我们的pmap,看看会发生什么。在我的电脑里,从node1调用时发生了这样的事情。
iex(node1@mymachine)> :rpc.pmap {Operation, :sum}, [1], [1,2,3]
[node3@mymachine: 2, node2@mymachine: 3, node1@mymachine: 4]对于每个节点,在最后一个位置使用不同的参数调用sum/2函数,从而导致不同的输出。如果我的:rpc.map/3的最后一个参数是一个元素少于可用节点的列表,那么就没有必要调用所有节点。但这些都是完成操作所必需的。如果我传递了很多参数,它会以一种更平衡的方式返回调用。您可以尝试在每个节点上执行:rpc.pmap {Operation, :sum}, [1], Enum.to_list 1..20,然后自己查看结果。
另一方面,当我们使用:rpc.multicall/5时,您传递的不是要并行执行的参数列表,而是要在多个节点中同时执行的相同参数。例如
iex(node1@mymachine)> :rpc.multicall(Operation, :sum, [2, 2], :infinity)
# => {[node1@mymachine: 4, node2@mymachine: 4, node3@mymachine: 4], []}最后一个参数是在每个节点中执行的超时时间,如果满足这个超时时间,这个节点的结果将不会显示在元组的第一个列表中。
使用:rpc.multicall/5,可以将此调用将被执行的节点列表作为第一个参数进行传递。例如,如果我只想在任何节点内的node2和node3中执行,那么我只需要执行
iex(node1@mymachine)> :rpc.multicall([:"node2@mymachine", :"node3@mymachine"] Operation, :sum, [2, 2], :infinity)
# => {[node2@mymachine: 4, node3@mymachine: 4], []}需要注意的一件事是,:rpc.multicall/4和:rpc.pmap/3都是在没有Node的情况下工作的,这是因为对于erlangvm,每当您启动iex或erl时,您就已经在一个节点集群上了。
发布于 2017-03-13 01:21:40
从文档中找到。
:rpc.multicall/5
多路呼叫是从一个客户端并发发送到多个服务器的远程过程调用。这对于从一组节点收集信息,或者调用一组节点上的函数以实现一些副作用非常有用。
:rpc.pmap/3
并行地为List1中的每个元素Elem计算apply(Module,Function,Elem|ExtraArgs)。按与List1相同的顺序返回返回值列表。
因此,multicall/5将在给定的一组节点上调用单个函数。它将返回一个元组,其中第一个元素是结果列表,第二个元素是由于某种原因没有完成函数的节点列表。
而pmap/3类似于调用map,不同之处在于工作可能在不同的节点上完成,也可能不在不同的节点上完成。重要的是要知道,结果列表仍将具有与起始列表相同的顺序。
https://stackoverflow.com/questions/42749089
复制相似问题