2

我正在学习使用 NoSQL 引擎 Raik。鉴于我有一个包含帖子的用户“时间线”,并且该帖子的范围可能从数百万到数十亿,我如何才能从 raik 存储桶中获取最后 N 个帖子?我的意思是,最后一个创建。

我读到,当使用二级索引时,Raik 将返回按键排序的帖子。所以我决定使用 UUID1 作为帖子键,并为帖子作者设置一个二级索引,这样我就可以使用它的键从该作者那里获取所有帖子。

但是帖子按升序排序!我还想使用 max_results 参数作为 SQL LIMIT。

但是,此查询返回该用户的前 N ​​个帖子,而不是最后一个。鉴于我已经看过一些 StackOverflow 帖子,并且建议的解决方案 MapReduce 对于大存储桶效率不高,您将如何建模数据或编写查询?

谢谢

4

2 回答 2

3

当来自 SQL 环境时,很容易将存储桶视为表并在其中存储小的单独记录,通常依靠二级索引来获取数据。由于 Riak 是使用一致散列的键值存储,但这通常不是最有效或可扩展的方法。

Riak 中基于键的查找可以直接识别保存数据的分区,协调节点可以直接查询这些分区。在查询二级索引时,Riak 不知道可能与索引匹配的数据将驻留在哪些分区上。因此,它需要将查询发送到大量分区,以确保可以找到所有匹配的对象。这称为“覆盖查询”,意味着假设存储桶使用的 n_val 为 3,则至少需要查询所有分区的 1/3。这通常会导致集群负载更高,并且不会像直接键查找那样扩展。延迟也往往更高。

因此,在使用 Riak 时,通常建议您对数据进行结构化,以便您可以尽可能多地使用直接键查找,例如通过反规范化。

如果您的消息/帖子可以以某种方式分组,例如按用户或对话,则将它们存储在表示此分组的单个对象中而不是单独的对象中可能是有意义的。

如果我们假设您的帖子可以包含文本或图像并链接到对话线程,您可以创建一个表示对话线程的对象。这将包含有关对话的信息以及帖子列表。该帖子列表可以例如包含发布者的id、时间戳和包含帖子的记录的键。如果帖子是相当短的文本消息,它甚至可能包含整个帖子,从而减少需要获取的记录数量。

随着帖子进入此对话,记录会更新,帖子列表会变长。allow_mult设置为 true 以启用兄弟姐妹可能是明智的,因为这将允许您处理并发写入。这种方法使您始终可以通过单个直接键查找来获取对话以及最新帖子。

当对象的大小保持在几 MB 以下时,Riak 效果最好。因此,您需要在某个时候将最旧的帖子移至单独的对象,以控制大小。如果您在主对话对象中保留这些相关对象的列表,可能连同有关它们所涵盖的时间间隔的一些信息,如果您需要回滚旧帖子,您也可以通过直接键查找轻松访问这些对象。

由于最常见的查询通常是针对最近的条目,因此始终可以通过主对话对象来完成。

我还想指出,我们确实有一个非常活跃的邮件列表,其中经常讨论此类问题。

于 2013-10-10T07:59:10.293 回答
0

我知道现在帮助你可能为时已晚,但我通过对同一件事的疑惑找到了这篇文章。我提出并使用效果良好的解决方法是创建两个二级索引,一个带有真实时间戳,另一个是(MAX_DATE - 时间戳)。对第一个查询执行查找会得到升序结果,对第二个查询执行查找会得到降序结果(一旦您进行数学运算将其转换回真实日期)。您可以在 Javascript 规范中找到最大日期值,例如MDN中的报告,即 8640000000000000。我无法说出它在非常重的负载下的性能如何,但我可以告诉你,就我的目的而言,它已经非常出色了很快,我很满意。我只是来这里希望找到一种不那么老套的方法来做到这一点。

于 2014-12-12T16:05:08.900 回答