0

考虑一组名为Library的数据,其中包含一组Books,每本书包含一组Pages

假设您正在使用 Riak 存储这些数据,并且您需要以两种可能的方式访问数据: - 查询特定页面(具有唯一 id) - 查询特定书籍中的所有页面(具有唯一名称)

此外,您需要能够轻松更新和删除特定Book的页面。

在 Riak 中实现这一目标的最佳方法是什么?

显然,Riak Search 可以解决问题,但对于我想要做的事情来说可能效率低下。我想知道设置存储桶是否有意义,其中每个存储桶都可以是一本书(这可能会产生数百万个“书”存储桶)。也许这是个坏主意……

这可以通过二级索引来完成吗?

我试图保持这个简单......

我是 Riak 的新手,我正在尝试找到完成可能相对简单的事情的最佳方法。我会感谢 Stack Overflow 社区的任何帮助。谢谢!

4

2 回答 2

1

最有效的方法是将洞书存储为一个对象,并将其页面复制为另一个单独的对象。优点:

  • 您将能够通过其键选择任何对象(riak 中最便宜的操作是 kv 查询)
  • 任何查询都会被延迟预测
  • 这是 riak 的自然存储方式

缺点:

  • 如果您需要更新任何页面,则必须更新整本书,然后再更新页面。由于 riak 没有原子操作,因此您必须考虑如何恢复任何故障情况(例如:书已更新,但页面未更新)。

Riak 是关于可用性可预测延迟的,所以如果你将使用 2i 之类的东西来收集结果,它会进行不可预测的时间查询,它会随着页码的增长而增长

于 2013-03-17T13:46:52.640 回答
1

在 Riak 中对主从关系建模的一种常见方法是让主记录包含一个详细记录 ID 列表,可能还包括一些关于详细记录的信息,这些信息在决定要检索哪些详细记录时可能很有用。

在您的示例中,您可以有两个称为“书籍”和“页面”的存储桶。“图书”存储桶中的主记录将包含有关图书整体的元数据和信息,以及图书中包含的页面列表。每个页面将包含保存页面数据的“页面”记录的 ID 以及相应的页码。例如,如果您希望能够按章节查询,您还可以添加有关某个页面所属章节的信息。

“页面”存储桶将包含页面的文本,并可能包含指向该页面中包含的图像和其他媒体数据的链接。该数据可以存储在另一个存储桶中。

为了获取特定页面或一系列页面,首先从“书籍”存储桶中检索主记录,然后根据记录的内容获取适当的页面。尽管这需要多次 GET 操作,但它们都是基于键的直接查找,这是从 Riak 检索数据的最有效和可扩展的方式,因此它的性能和扩展性都很好。

这种方法还可以轻松更改页面和/或章节的顺序,因为只需要更新主记录。然而,添加、删除或修改页面将需要更新、添加或删除主记录以及一个或多个详细记录。

您当然也可以通过向对象添加二级索引并基于此进行查询来解决此问题。然而,Riak 中的二级索引查询确实必须包括对分区覆盖集(通常是环大小/n_val)的处理才能满足请求,因此会给系统带来更多的负载,并且通常会导致比检索更高的延迟通过直接键查找包含键的单个对象(只需要涉及实际存储对象的分区)。

尽管在插入或删除页面/条目时维护一个包含索引的单独对象会增加一些额外的工作,但这种方法通常会导致更有效的读取,因为只需要直接键查找。如果您的应用程序的读取量很大,那么使用这种方法可能是有意义的,而二级索引对于写入量大的应用程序可能更有效,因为插入和修改成本更低,但读取成本更高。但是,您始终可以添加二级索引以防万一,以保持您的选择开放。

在这种情况下,我通常会建议执行一些基准测试来测试解决方案并检查哪种解决方案最符合您的特定性能和扩展要求。

于 2013-03-23T20:47:53.580 回答