在Riak + Erlang的riakc客户端中完全混淆了MapReduce

时间:2013-04-11 13:31:29

标签: erlang riak

我在这里混淆的主要问题(我认为)是qfun的参数应该是什么以及返回值应该是什么。 README基本上没有说明这一点,它给出的例子抛弃了第二和第三个args。

现在我只是想了解这些论点,而不是将Riak用于任何实际的事情。最终,我将尝试用它来重建我们(基于MySQL的慢速)财务报告系统。所以在这里忽略了我的目标的无意义,为什么以下给我一个badfun例外?

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

现在{Name, Age}中存储了一些<<"people">>对,我想使用MapReduce(除了理解“如何”之外没有其他理由)将值恢复,在第一次使用时保持不变。 / p>

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\\\">"...>>}

如何通过我的map函数传递数据不变?有没有比README更好的Erlang客户端文档? README似乎假设您已经知道输入是什么。

3 个答案:

答案 0 :(得分:1)

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

第一个是riak_kv模块(riak_client.erl和riak_object.erl)中包含的内部Riak客户端。如果您连接到Riak控制台或者正在编写MapReduce函数或提交挂钩,则可以使用此方法。因为它是从Riak节点内运行的,所以它与qfuns一起运行良好。

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

答案 1 :(得分:0)

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

答案 2 :(得分:0)

经过几天的游戏,这里有一个巧妙的技巧,使开发更容易。利用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群集可见。如果需要,可以使用代码:delete / 1再次删除代码。