我正在学习使用NoSQL引擎Raik。鉴于我有一个帖子的用户“时间轴”,并且该帖子的范围可能从数百万到数十亿,我怎么能从raik桶中获取最后N个帖子?我的意思是,最后创建的。
我读到当使用二级索引时,Raik将返回按键排序的帖子。所以我决定使用UUID1作为帖子密钥并为帖子作者提供一个二级索引,以便我可以使用它的密钥从该作者那里获取所有帖子。
然而帖子排序正在进行中!我还想使用max_results参数作为SQL LIMIT。
然而,此查询返回该用户的第一个N个帖子,而不是最后一个。鉴于我已经看到一些StackOverflow帖子,并且建议的解决方案,MapReduce对于大型存储桶效率不高,您将如何建模数据或编写查询?
由于
答案 0 :(得分:3)
当来自SQL环境时,很容易将存储桶视为表并在那里存储小的单个记录,通常依赖于二级索引来获取数据。由于Riak是一个使用一致哈希的键值存储,但这通常不是最有效或可扩展的方法。
基于Riak中的密钥的查找允许直接识别保存数据的分区,并且协调节点可以直接查询这些分区。在查询secondary index时,Riak不知道哪些分区上可能存在与索引匹配的数据。因此,它需要将查询发送到大量分区,以确保可以找到所有匹配的对象。这被称为“覆盖查询”,意味着,假设n_val为3用于存储桶,则需要查询至少1/3的所有分区。这通常会导致群集上的负载更高,并且不会像直接键查找那样进行扩展。延迟也往往更高。
使用Riak时,通常建议您构建数据,以便尽可能使用直接键查找,例如:通过去标准化。
如果您的消息/帖子可以某种方式分组,例如通过用户或对话,将它们存储在表示该分组的单个对象中而不是作为单独的对象可能是有意义的。
如果我们假设您的帖子可以包含文本或图像并且链接到会话线程,则可以创建表示会话线程的对象。这将包含有关对话的信息以及帖子列表。这个帖子列表可以是例如包含海报的ID,时间戳和包含帖子的记录的密钥。如果帖子是一条相当短的短信,它甚至可能包含整个帖子,减少了需要提取的记录数量。
随着帖子进入此对话,记录会更新,帖子列表会更长。将allow_mult
设置为true以启用兄弟节点可能是明智的,因为这将允许您处理并发写入。这种方法允许您通过单个直接键查找始终获得对话以及最新帖子。
当对象的大小保持在几MB以下时,Riak效果最佳。因此,您需要在某个时刻将最旧的帖子移动到单独的对象以保持大小。如果您在主对话对象中保留这些相关对象的列表,可能还有一些有关它们所涵盖的时间间隔的信息,您可以通过直接键查找轻松访问这些对象,如果您需要向后滚动旧帖子。
由于最常见的查询通常是针对最近的条目,因此始终可以通过主会话对象来实现。
我还想指出,我们确实有一个非常活跃的mailing list,这些问题经常被讨论。
答案 1 :(得分:0)
我知道帮助你可能已经太晚了,但是我发现这篇文章是因为想知道同样的事情。我提出并一直使用的解决方法是创建两个辅助索引,一个具有实时时间戳,另一个具有(MAX_DATE - timestamp)。对第一个查询执行查找会获得升序结果,对第二个查询执行查找会得到降序结果(一旦您进行数学计算以将其转换回实际日期)。您可以在Javascript规范中找到最大日期值,例如在MDN中报告的8640000000000000.我无法说明它在重负载下的性能如何,但我可以告诉您,为了我的目的它速度非常快,我非常满意。我刚刚来到这里希望能找到一种不太常见的方法。