0

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

现在我只是想理解这些论点,而不是把 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 客户端文档?该自述文件似乎假设您已经知道输入是什么。

4

3 回答 3

1

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

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

另一个客户端是Erlang的官方Riak 客户端,由外部应用程序使用,并通过协议缓冲区接口连接到 Riak。这就是您在上面的示例中使用的内容。由于它通过协议缓冲区连接,因此通常建议将 Erlang 中的 MapReduce 函数编译并部署在集群的节点上作为命名函数。这也将使它们可以从其他客户端库访问。

于 2013-04-13T21:09:32.793 回答
0

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

于 2013-04-11T14:09:15.873 回答
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 集群可见。如果需要,可以使用 code:delete/1 再次删除代码。

于 2013-04-14T07:52:57.470 回答