【问题标题】:Cassandra partition keys organisationCassandra 分区键组织
【发布时间】:2018-02-14 17:07:13
【问题描述】:

我正在尝试将以下结构存储在 cassandra 中。

ShopID, UserID , FirstName , LastName etc....

上面的查询最多的是

select * from table where  ShopID = ? , UserID = ? 

这就是为什么将 (ShopID, UserID) 设置为主键很有用的原因。

根据文档,Cassandra 的默认分区键是主键的第一列 - 就我而言,它是 ShopID,但我想在 Cassandra 集群上均匀分布数据,我不能允许来自一个 @ 的所有数据987654325@只存储在一个分区中,因为有些商店有10M的记录,有些只有1k。

我可以将 (ShopID, UserID) 设置为分区键,然后我可以在 Cassandra 集群中实现记录的均匀分布。但是之后我无法接收属于某个shopid的所有用户。

select * 
from table 
where ShopID = ?

很明显,这个查询需要对整个集群进行全面扫描,但我没有任何可能这样做。它看起来像非常硬的约束。

我的问题是如何重组数据以同时解决这两个问题(统一数据分区、进行全扫描查询的可能性)。

【问题讨论】:

    标签: cassandra


    【解决方案1】:

    一般情况下,您需要将用户 id 设置为集群列,并在保存过程中向您的表和分区键添加一些人工信息。它允许将大型自然分区打破为多个合成。但是现在你需要在读取过程中查询所有合成分区以组合回自然分区。因此,我们的目标是在合成分区的数量(大小)和读取查询之间找到合理的折衷以组合所有分区。

    可以在herehere找到可能实现的全面描述 (示例 2:用户组)。

    还可以看看solution(示例3:按加入日期划分的用户组)在通过日期类型的聚类列进行查询/排序/分组时。如果您也有类似的查询,它会很有用。

    【讨论】:

    • 谢谢@Nikita。似乎它只是这个问题的唯一一种可能的解决方案。我已经看到了综合分片解决方案。它看起来很难看,并且使解决方案无法扩展。另一种可能性可能是将 ShopID 作为表名 - 但这种解决方案不适用于或多或少的大量 shopID
    • 是的,在您的情况下,合成分片似乎是唯一可能的解决方法,不幸的是这不是很优雅。但是您能解释一下为什么它使您的解决方案无法扩展吗?
    • 如果我从 3 台机器开始,我将生成 shard_id 从 0 到 2 。然后我添加一些机器。要使用它们,如果我想统一使用我的所有机器,我必须更改所有历史数据的 shard_id。我可以从 0 到 100 生成 shard_id 开始,然后我会收到更多或更少可扩展的解决方案。但随后我需要为每个项目查询多发出 x100 个请求。
    • 我对可扩展性和分区之间关系的解释超过了允许的最大评论大小,所以我将其作为第二个答案附上。
    【解决方案2】:

    Cassandra 中的每个节点负责一些令牌范围。 Cassandra 使用散列从行的分区键中派生一个令牌,并将记录发送到其令牌范围包括该令牌的节点。不同的记录可以具有相同的标记,并且它们被分组在分区中。为简单起见,我们可以假设每个 cassandra 节点存储相同数量的分区。我们还希望分区大小相等,以便在节点之间均匀分布。如果我们有一个太大的分区,这意味着我们的一个节点需要更多的资源来处理它。但是,如果我们将它分成多个更小的部分,我们会增加它们在所有节点之间均匀分布的机会。

    但是,节点之间的令牌范围分布与分区之间的记录分布无关。当我们添加一个新节点时,它只对来自其他节点的偶数部分令牌范围负责,结果是偶数个分区。如果我们有 2 个具有 3 GB 数据的节点,则在添加第三个节点后,每个节点都存储 2 GB 数据。这就是为什么可扩展性不受分区影响,并且您无需在添加新节点后更改历史数据。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-06-21
      • 2016-12-21
      • 2016-05-11
      • 1970-01-01
      • 1970-01-01
      • 2017-05-22
      • 1970-01-01
      • 2017-04-10
      相关资源
      最近更新 更多