【问题标题】:Duplicates when linkswalking riak using ripple使用涟漪链接行走 riak 时重复
【发布时间】:2012-07-20 08:04:47
【问题描述】:

我正在做一个项目,我将 Riak 与 Ripple 结合使用,但我偶然发现了一个问题。 出于某种原因,我在链接结构时会出现重复。当我使用 curl 链接 walk 时,我看不到重复项。

我的基于 curl 的链接步行的区别

curl -v http://127.0.0.1:8098/riak/users/2306403e5177b4716da9df93b67300824aa2fd0e/_,projects,0/_,tasks,1

和我的基于 ruby​​ 波纹/riak-client 的链接步行

      result =   Riak::MapReduce.new(self.robject.bucket.client).
            add(self.robject.bucket,self.key).
            link(Riak::WalkSpec.new({:key => 'projects'})).
            link(Riak::WalkSpec.new({:key => 'tasks', :bucket=>'tasks'})).
            map("function(v){ if(!JSON.parse(v.values[0].data).completed) {return [v];} else { return [];} }", {:keep => true}).run

尽我所能告诉最后的地图。

但是,map/reduce 的结果包含多个重复项。我无法理解为什么。现在我已经决定根据密钥删除重复项,但我希望 riak 结果不包含重复项,因为最后删除重复项似乎很浪费。

我尝试了以下方法:

  • 确保我的波纹对象的链接集中没有重复项
  • 在没有 map reduce 的情况下加载数据,但链接遍历包含重复的键。

感谢任何帮助。

【问题讨论】:

    标签: ruby riak


    【解决方案1】:

    您在这里遇到的是 Map/Reduce 查询的一个有趣的副作用/挑战。

    M/R 查询没有任何读取仲裁值的概念,它们必须命中每个节点上的每个对象(当然,在输入过滤的限制范围内)。 这意味着,当 N > 1 时,查询必须命中每个对象的每个 副本

    例如,假设 N=3,默认情况下。这意味着,对于每个写入的对象,有 3 个副本,每个副本位于 3 个不同的节点上。 当您为对象发出读取时(假设使用默认仲裁值 R=2),协调节点(从您的客户端接收读取请求)联系所有 3 个节点(并可能接收 3 个不同的值,3 个不同的副本对象)。 然后,它检查以确保这些副本中至少有 2 个具有相同的值(以满足 R=2 的要求),将商定的值返回给请求的客户端,并丢弃其他副本。 因此,在常规操作(读/写,还有链接遍历)中,协调节点会为您过滤掉重复项。

    Map/Reduce 查询没有那么奢侈。它们实际上并没有与之关联的仲裁值——它们被用来迭代所有节点上的每个(相关)键和对象。而且由于 M/R 代码在每个单独的节点(靠近数据)上运行,而不仅仅是在协调节点上,它们本质上不能真正过滤掉任何重复项。例如,它们的设计目的之一是更新(或删除)所有节点上的所有对象副本。因此,每个 Map 阶段(在上述情况下)在每个节点上运行,为每个副本返回匹配的“完成”值,并将结果发送回协调节点以返回给客户端。而且由于您的 N>1 很可能,结果集中会有重复项。

    现在,您可以通过在 Reduce 阶段编写代码来显式过滤掉重复项,以检查是否已经存在密钥,如果存在则拒绝重复项等。 但老实说,如果我遇到你的情况,我只会在客户端过滤掉 ruby​​ 中的重复项,而不是弄乱 reduce 代码。

    无论如何,我希望这能揭开这个谜团。

    【讨论】:

      猜你喜欢
      • 2016-11-26
      • 2018-11-13
      • 2016-04-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-11
      相关资源
      最近更新 更多