当来自 SQL 环境时,很容易将存储桶视为表并在其中存储小的单独记录,通常依靠二级索引来获取数据。由于 Riak 是使用一致散列的键值存储,但这通常不是最有效或可扩展的方法。
Riak 中基于键的查找可以直接识别保存数据的分区,协调节点可以直接查询这些分区。在查询二级索引时,Riak 不知道可能与索引匹配的数据将驻留在哪些分区上。因此,它需要将查询发送到大量分区,以确保可以找到所有匹配的对象。这称为“覆盖查询”,意味着假设存储桶使用的 n_val 为 3,则至少需要查询所有分区的 1/3。这通常会导致集群负载更高,并且不会像直接键查找那样扩展。延迟也往往更高。
因此,在使用 Riak 时,通常建议您对数据进行结构化,以便您可以尽可能多地使用直接键查找,例如通过反规范化。
如果您的消息/帖子可以以某种方式分组,例如按用户或对话,则将它们存储在表示此分组的单个对象中而不是单独的对象中可能是有意义的。
如果我们假设您的帖子可以包含文本或图像并链接到对话线程,您可以创建一个表示对话线程的对象。这将包含有关对话的信息以及帖子列表。该帖子列表可以例如包含发布者的id、时间戳和包含帖子的记录的键。如果帖子是相当短的文本消息,它甚至可能包含整个帖子,从而减少需要获取的记录数量。
随着帖子进入此对话,记录会更新,帖子列表会变长。allow_mult
设置为 true 以启用兄弟姐妹可能是明智的,因为这将允许您处理并发写入。这种方法使您始终可以通过单个直接键查找来获取对话以及最新帖子。
当对象的大小保持在几 MB 以下时,Riak 效果最好。因此,您需要在某个时候将最旧的帖子移至单独的对象,以控制大小。如果您在主对话对象中保留这些相关对象的列表,可能连同有关它们所涵盖的时间间隔的一些信息,如果您需要回滚旧帖子,您也可以通过直接键查找轻松访问这些对象。
由于最常见的查询通常是针对最近的条目,因此始终可以通过主对话对象来完成。
我还想指出,我们确实有一个非常活跃的邮件列表,其中经常讨论此类问题。