【问题标题】:Understanding internal data storing by cassandra理解 cassandra 的内部数据存储
【发布时间】:2015-08-29 21:36:44
【问题描述】:

我有这张桌子

create table comment_by_post
(
    postId uuid,
    userId uuid,
    cmntId timeuuid,
    cmntTxt text,   
    cmntBy text,
    time bigint, 
    primary key ((postId, userId),cmntId)
)

这是该表中的内部数据

RowKey: 4978f728-0f96-11e5-a6c0-1697f925ec7b:4978f728-0f96-12e5-a6c0-1697f92e537a
=> (name=d3f02a30-126f-11e5-879b-e700f669bcfc:, value=, timestamp=1434270721107000)
=> (name=d3f02a30-126f-11e5-879b-e700f669bcfc:cmnttxt, value=636d6e743434, timestamp=1434270721107000)
-------------------
RowKey: 4978f728-0f96-11e5-a6c0-1697f925ec7b:4978f728-0f96-12e5-a6c0-1697f92eec7a
=> (name=465fee30-126f-11e5-879b-e700f669bcfc:, value=, timestamp=1434270483603000)
=> (name=465fee30-126f-11e5-879b-e700f669bcfc:cmnttxt, value=636d6e7432, timestamp=1434270483603000)
=> (name=4ba89f40-126f-11e5-879b-e700f669bcfc:, value=, timestamp=1434270492468000)
=> (name=4ba89f40-126f-11e5-879b-e700f669bcfc:cmnttxt, value=636d6e7431, timestamp=1434270492468000)
=> (name=504a61f0-126f-11e5-879b-e700f669bcfc:, value=, timestamp=1434270500239000)
=> (name=504a61f0-126f-11e5-879b-e700f669bcfc:cmnttxt, value=636d6e7433, timestamp=1434270500239000)
-------------------
RowKey: 4978f728-0f96-11e5-a6c0-1697f925ec7b:4978f728-0f96-12e5-a6c0-1697f92e237a
=> (name=cd1e8f30-126f-11e5-879b-e700f669bcfc:, value=, timestamp=1434270709667000)
=> (name=cd1e8f30-126f-11e5-879b-e700f669bcfc:cmnttxt, value=636d6e7433, timestamp=1434270709667000)

如果我这样做 primary key (postId, userId,cmntId) 那么它就像:

RowKey: 4978f728-0f96-11e5-a6c0-1697f925ec7b
=> (name=4978f728-0f96-12e5-a6c0-1697f92eec7a:971da150-1260-11e5-879b-e700f669bcfc:, value=, timestamp=1434264176613000)

=> (name=4978f728-0f96-12e5-a6c0-1697f92eec7a:971da150-1260-11e5-879b-e700f669bcfc:cmnttxt, value=636d6e7431, timestamp=1434264176613000)

=> (name=4978f728-0f96-12e5-a6c0-1697f92eec7a:a0d4a900-1260-11e5-879b-e700f669bcfc:, value=, timestamp=1434264192912000)

=> (name=4978f728-0f96-12e5-a6c0-1697f92eec7a:a0d4a900-1260-11e5-879b-e700f669bcfc:cmnttxt, value=636d6e7432, timestamp=1434264192912000)

=> (name=4978f728-0f96-12e5-a6c0-1697f92eec7a:a5d94c30-1260-11e5-879b-e700f669bcfc:, value=, timestamp=1434264201331000)

为什么会这样?两者都有什么好处?

【问题讨论】:

标签: cassandra cql cql3 cassandra-cli


【解决方案1】:

Christopher 已经解释了如何将分区键连接在一起以生成用于存储的行键,所以我不会重新散列(不是双关语)。但我会解释这两种方法的优缺点。

PRIMARY KEY (postId, userId,cmntId)

使用此 PRIMARY KEY,您的数据将按 postId 进行分区,并按 userId 和 cmntId 进行聚类。这意味着,在一个帖子上创建的所有 cmets 将按postId 一起存储在磁盘上,然后按userId 和cmntId (分别)排序。

这里的优点是您具有查询灵活性。您可以在所有 cmets 中查询某个帖子,也可以在所有 cmets 中查询某个特定用户的帖子。

缺点是,与其他解决方案相比,您有更高的无限行增长机会。如果每个 postId 的总列数超过 20 亿,您将最大限度地利用每个 postId 可以存储的数据量。但是你在每个帖子中存储这么多评论数据的几率很低,所以你应该没问题。

PRIMARY KEY ((postId, userId),cmntId)

此解决方案通过postId 和userId 的串联行键(按cmntId 排序)将评论数据存储在一起,有助于消除无限行增长的可能性。这是您优于其他解决方案的优势。

缺点是失去了查询的灵活性,因为现在您需要为每个查询提供postId 和userId。此 PRIMARY KEY 定义根本不支持仅使用 postId 的 cmets 查询,因为 Cassandra CQL 要求您为查询提供整个分区键。

【讨论】:

  • 可能值得注意的是,使用PRIMARY KEY ((postId, userId),cmntId) 形式的帖子的 cmets 将被放置在集群中的多个节点上,而不是像使用不太具体的分区键 PRIMARY KEY(postId, usedId,cmndId) 提到的那样放在一个节点上.
  • 我的理解是,在PRIMARY KEY (postId, userId,cmntId) 的情况下,列数可能会迅速增长,但查询会很容易。在PRIMARY KEY ((postId, userId),cmntId) 的情况下,列数将受到控制,但从查询的角度来看,它不会那么容易。对吗?
【解决方案2】:

第一个主键使用postId 和userId 作为分区键,cmntId 作为集群列。请注意,用于RowKey 的值包含来自postId 和userId 的值,由: 分隔。接下来,聚类列的值将用于该行中每个单元格的名称。

在您的第二个示例中,主键缺少分区键周围的括号。它们可以被省略,但通常更喜欢出现,因为我们可以明确地确定主键的哪些部分用于分区和集群。如果不包含额外的括号,只有第一列用作分区键(在 cassandra-cli 的 RowKey 值中可见)。假设所有后续列都是聚类列,我们可以通过查看单元名称来验证。

【讨论】:

  • 两者的优缺点是什么?
猜你喜欢
  • 2015-07-18
  • 2017-12-20
  • 1970-01-01
  • 1970-01-01
  • 2021-08-26
  • 2015-04-05
  • 2011-11-14
  • 1970-01-01
  • 2014-07-20
相关资源
最近更新 更多