1

我正在使用 riak 存储桶来存储消息列表,使用 UUID 作为键,使用 json 消息作为值。这工作正常。

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

  1. 获取最后插入的对象(这是我的首选方法)。
  2. 从桶中获取一个随机对象(如果第一个替代方案不可行)。

有没有有效的方法来实现这一目标?

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

4

3 回答 3

2

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

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

如果您将大量数据写入包含消息的存储桶,您可能需要调整单独的存储桶,使其不允许多个值并且最后一个值获胜。这样,您将降低由于在系统中频繁更新此单个记录而创建大量同级的风险。这将始终为您提供最后写入的记录之一,但不一定是最后一条(尤其是如果您经常向数据库写入消息),因为 Riak 不支持任何类型的原子性并且是最终一致的数据库。

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

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

于 2012-11-11T08:47:13.790 回答
0

我想出了同样的场景。在我的场景中,我必须保存用户。为此,我需要一个自动增量 ID。所以我所做的是,我将最后插入的密钥放在单独的存储桶中,如“Christian Dahlqvist”所述,每次我想插入新记录时,我都会从该密钥存储桶中获取最后插入的密钥。在这里,我们在该桶中只有一个值,其键为“LastKey”,我们始终知道。我根据获取的密钥增加了密钥,并再次更新了密钥桶。因此,密钥桶中始终包含最新的密钥。

于 2014-03-21T12:12:41.233 回答
0

第一个任务很容易实现:

  • 添加提交后挂钩,将最后插入的密钥写入某个预定义的密钥/存储桶位置
  • 从该预定义的密钥/存储桶中获取密钥并使用它们发出获取查询

它仍然是两个操作,但两者都只是快速获取。加上挂钩上的额外开销,但也没有太重。

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

  • 获取所有密钥(极其昂贵的操作)
  • 随机选择
  • 问题得到
于 2012-11-15T20:13:40.607 回答