【问题标题】:Difference between Erlang's rpc:multicall/4 vs rpc:pmap/3Erlang 的 rpc:multicall/4 与 rpc:pmap/3 之间的区别
【发布时间】:2017-08-02 14:39:22
【问题描述】:

我目前正在尝试在多个节点上运行一些 Elixir 代码,我使用了两种方法:1):rpc.multicall/4 和 2):rpc.pmap/3

我可以看到两者都在多个节点上运行代码,并且我知道这些调用的结果是不同的(元组与列表)。

我遗漏的两者之间是否还有其他重要区别,或者这两个函数是否等效,唯一的区别是它们的调用方式和返回值?

提前致谢!

【问题讨论】:

    标签: concurrency erlang elixir rpc


    【解决方案1】:

    他们真的很不一样,

    pmap 将执行类似于:list.map 的映射(更多此处为http://erlang.org/doc/man/lists.html),但优点是只要节点可用连接并且列表上有要执行的值,此调用将在节点之间发生地图。

    multicall 以其他方式将始终执行相同的调用,在多个节点中使用相同的参数。 multicall/4 在所有连接的节点中执行相同的函数调用。 multicall/5 在开头有一个额外的参数,即将执行 rpc 的节点列表。

    当我们有一个由 3 个 shell 组成的集群时更好地举例说明

    • iex --sname node1
    • iex --sname node2
    • iex --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 都可以在没有节点的情况下工作,这是因为对于 erlangvm,每当你触发 iexerl 时,你已经在一个单节点集群上.

    【讨论】:

      【解决方案2】:

      来自文档。

      :rpc.multicall/5

      多重调用是从一个客户端并发发送到多个服务器的 RPC。这对于从一组节点收集信息或在一组节点上调用函数以实现一些副作用很有用。

      :rpc.pmap/3

      并行计算 List1 中每个元素 Elem 的 apply(Module, Function, [Elem|ExtraArgs])。以与 List1 中相同的顺序返回返回值列表。

      所以multicall/5 将在给定的一组节点上调用一个函数。它会返回一个元组,其中第一个元素是结果列​​表,第二个元素是由于某种原因未完成函数的节点列表。

      pmap/3 将类似于调用map,除了工作可能会或可能不会在不同的节点上完成。重要的是要知道结果列表仍将与起始列表具有相同的顺序。

      【讨论】:

        猜你喜欢
        • 2018-11-15
        • 2011-10-04
        • 1970-01-01
        • 1970-01-01
        • 2018-07-07
        • 1970-01-01
        • 1970-01-01
        • 2017-11-20
        • 2019-04-09
        相关资源
        最近更新 更多