【问题标题】:Riak solution for querying data by books or unique pages通过书籍或唯一页面查询数据的 Riak 解决方案
【发布时间】:2013-03-17 05:07:05
【问题描述】:

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

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

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

在 Riak 中完成此任务的最佳方法是什么?

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

这可以通过二级索引来实现吗?

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

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

【问题讨论】:

标签: riak riak-search


【解决方案1】:

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

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

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

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

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

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

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

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

【讨论】:

  • 感谢您的深入回答。我认为这种方法的最大警告是您提到的最后一部分 - 关于添加/删除页面。您是否发现仅存储页面并使用二级索引来存储每个页面的书的唯一 ID 有什么缺点?
  • 在定义为记录元数据的Riak二级索引中,为了修改一组对象的索引,需要读取并修改所有对象。我在这里的假设是必须可以通过页码识别和检索特定页面/页面集。如果您选择将其放在键和/或二级索引中,则在插入或删除页面时可能需要更新多个页面,因为您更改的页面之后的所有页面可能都需要重新编号。出于这个原因,我认为将索引保存在单个对象中会使更新更容易也更有效。
  • 感谢您的评论(很抱歉长时间回复)。 book/pages 示例确实是一个概括。实际上,在某些情况下,我们有属于目录的项目或在其他情况下属于 pdf 的页面。关键是我们需要能够单独访问以及在组中访问的项目(不同的粒度级别)。集合中项目的顺序无关紧要。我只需要能够访问“名为 X 的集合中的所有项目”或“单个特定项目 Y”。为此,我认为二级索引是完美的。你同意吗?
  • 我不认为它可以与二级索引一起使用,但根据您的访问模式,它可能是也可能不是最有效和可扩展的方法。我更新了我的回复,提出了一些需要考虑的事项。
  • 感谢您清晰而有见地的回答。感谢您解决了我对“书”的更新/删除的担忧,并指出了两种可能方法的优缺点,无论我们主要是阅读还是更新。总的来说,您的回答让我更好地了解了 Riak 的最佳实践。
【解决方案2】:

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

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

缺点:

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

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

【讨论】:

    猜你喜欢
    • 2015-11-23
    • 1970-01-01
    • 2015-03-10
    • 1970-01-01
    • 2010-09-22
    • 1970-01-01
    • 1970-01-01
    • 2023-01-23
    • 1970-01-01
    相关资源
    最近更新 更多