在riak中从桶中获取对象而不知道其密钥

时间:2012-11-10 12:55:42

标签: riak

我正在使用riak存储桶来存储消息列表,使用UUID作为密钥,使用json消息作为值。这很好。

我需要的是一种有效的方法从桶中获取单条消息而不知道其密钥,至少在以下两种情况之一中:

  1. 获取最后插入的对象(这是我最喜欢的方法)。
  2. 从存储桶中获取随机对象(如果无法使用第一个选项)。
  3. 有没有有效的方法来实现这一目标?

    我认为一种替代方法可能是检索存储桶中的密钥然后获取第一个密钥。但是这意味着对riak进行两次调用,一次调用获取所有键(仅丢弃除一个之外的所有键),第二次调用以获取对象。它看起来效率不高。

3 个答案:

答案 0 :(得分:2)

由于Riak是一个键值存储,因此最有效的检索数据的方法是通过密钥。列出或检索存储桶中的所有密钥,即使您最终只使用首先返回的密钥,也是您可以执行的效率最低的操作之一,因为它会导致Riak扫描系统中的所有密钥(而不仅仅是存储桶),以及通常建议不要在生产系统上使用它。

获取最后一个插入对象的最有效方法可能是将id存储在另一个桶中的单独的已知记录中。但是,这将要求您在每次插入时执行两次写入,对每次读取执行两次读取,但这样做会以最有效的方式执行。您可以在包含消息的存储桶上实现一个提交后挂钩(必须在Erlang中,因为它目前不可能使用JavaScript函数编写记录),以使系统为您执行更新,这将删除需要最后一次写作。

如果您将大量数据写入包含消息的存储桶,您可能需要调整单独的存储桶,以使其不允许多个值并且最后一个值获胜。这样,您可以降低因系统中此单条记录的频繁更新而产生大量兄弟姐妹的风险。这总是会给你一个最后写的记录,但不一定是最后一个(特别是如果你经常把消息写入数据库),因为Riak不支持任何类型的原子性并且是最终一致的数据库。

如果使用leveldb后端,也可以创建一个或多个辅助索引,并使用此索引将扫描限制为仅限于最近的记录,这比扫描所有密钥更有效。然后你可以通过mapreduce选择最新的密钥或随机密钥,但这比前面描述的方法效率低得多。

我想不出有任何有效的方法可以从Riak中检索存储桶中的随机记录,除非您知道已插入的密钥范围,并且可以在客户端上随机决定要获取哪个。一种方法是按顺序生成所有密钥而不是使用UUID,但这在高度并发的分布式系统中自然不是一个好主意。

答案 1 :(得分:0)

第一项任务很容易实现:

  • 添加post-commit hook,将最后插入的密钥写入某个预定义的密钥/存储区
  • 从预定义的密钥/存储桶中获取密钥并使用它们发出获取查询

它仍然是两个操作,但两者都是快速的。还有额外的开销,但也没有太重。

第二种情况也很简单,但实际使用效率太低:

  • 获取所有密钥(极其昂贵的操作)
  • 随机选择
  • 问题获取

答案 2 :(得分:0)

我想出了同样的情景。在我的场景中,我必须保存用户。为此我需要一个自动增量Id。所以我所做的是,我把最后一个插入的密钥放在一个单独的桶中,​​如同#34; Christian Dahlqvist"所提到的,每次我想插入新记录时,我都会从该密钥桶中取出最后一个插入的密钥。这里我们在该桶中只有一个值,其中键为" LastKey"我们一直都知道。然后我根据获取的密钥递增密钥,并再次更新密钥桶。所以密钥桶总是包含最新的密钥。