【问题标题】:Completely confused about MapReduce in Riak + Erlang's riakc client对 Riak + Erlang 的 riakc 客户端中的 MapReduce 完全感到困惑
【发布时间】:2013-04-03 17:28:37
【问题描述】:

我在这里感到困惑的主要事情(我认为)是 qfun 的参数应该是什么以及返回值应该是什么。 README 基本上没有说明这一点,它给出的示例丢弃了第二个和第三个参数。

现在我只是想理解这些论点,并没有将 Riak 用于任何实际操作。最终,我将尝试用它重建我们的(缓慢的、基于 MySQL 的)财务报告系统。所以在这里忽略我的目标毫无意义,为什么下面给我一个badfun 异常?

数据只是名称和年龄的元组(对),键是名称。在从 Erlang 控制台插入数据之前,我没有对 JSON 等进行任何转换。

现在有一些 {Name, Age} 对存储在 <<"people">> 中,我想使用 MapReduce(除了了解“如何”之外没有其他原因)来取回值,在第一次使用时保持不变。

riakc_pb_socket:mapred(
    Pid, <<"people">>,
    [{map, {qfun, fun(Obj, _, _) -> [Obj] end}, none, true}]).

不过,这让我很不开心:

{error,<<"{\"phase\":0,\"error\":\"{badfun,#Fun<erl_eval.18.17052888>}\",\"input\":\"{ok,{r_object,<<\\\"people\\\">>,<<\\\"elaine\\\">"...>>}

我如何通过我的地图函数原封不动地传递数据?有没有比 README 更好的 Erlang 客户端文档?该自述文件似乎假设您已经知道输入是什么。

【问题讨论】:

    标签: erlang riak


    【解决方案1】:

    有 2 个 Riak Erlang 客户端用于不同的目的。

    第一个是包含在 riak_kv 模块中的内部 Riak 客户端(riak_client.erl 和 riak_object.erl)。如果您连接到 Riak 控制台,或者您正在编写 MapReduce 函数或提交挂钩,则可以使用此功能。由于它是在 Riak 节点中运行的,因此它与 qfuns 配合得非常好。

    另一个客户端是官方的Riak client for Erlang,供外部应用使用,通过protocol buffers接口连接到Riak。这就是您在上面的示例中使用的内容。由于它通过协议缓冲区连接,因此通常建议编译 Erlang 中的 MapReduce 函数并deployed on the nodes of the cluster as named functions。这也将使它们可以从其他客户端库访问。

    【讨论】:

    • 我现在正在连接到 Riak 集群并在我的应用启动时执行远程代码加载。这使我的应用程序与 Riak 集群分离了一点,使开发变得更加容易。我将发布一个示例。
    【解决方案2】:

    我认为我的代码实际上是正确的,我的问题在于我试图使用 shell 来执行代码。我需要实际编译代码才能在 Riak 中运行。这是 Erlang shell 及其编译方式的限制。

    【讨论】:

    【解决方案3】:

    玩了几天之后,这里有一个巧妙的技巧,可以让开发变得更容易。利用 Erlang 的 RPC 支持以及它具有运行时代码加载的事实,将您的代码分发到所有 Riak 节点:

    %% Call this somewhere during your app's initialization routine.
    %% Assumes you have a list of available Riak nodes in your app's env.
    load_mapreduce_in_riak() ->
      load_mapreduce_in_riak(application:get_env(app_name, riak_nodes, [])).
    
    load_mapreduce_in_riak([]) ->
      ok;
    load_mapreduce_in_riak([{Node, Cookie}|Tail]) ->
      erlang:set_cookie(Node, Cookie),
      case net_adm:ping(Node) of
        pong ->
          {Mod, Bin, Path} = code:get_object_code(app_name_mapreduce),
          rpc:call(Node, code, load_binary, [Mod, Path, Bin]);
        pang ->
          io:format("Riak node ~p down! (ping <-> pang)~n", [Node])
      end,
      load_mapreduce_in_riak(Tail).
    

    现在您可以引用模块app_name_mapreduce 中的任何函数,它们将对Riak 集群可见。如果需要,可以使用 code:delete/1 再次删除代码。

    【讨论】:

      猜你喜欢
      • 2011-03-06
      • 2014-07-05
      • 2018-08-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多