【问题标题】:Cassandra Data modelling with multiple tables for same dataCassandra 使用多个表对相同数据进行数据建模
【发布时间】:2021-06-29 19:19:37
【问题描述】:

Cassandra 数据建模查询 你好,

我正在处理的数据模型如下,相同数据集的不同表用于满足不同类型的查询。数据主要存储一些活动在电子邮件、网络、移动应用、短信等多个渠道发送的事件数据。事件可以包括不同订阅者的页面访问、电子邮件打开、链接点击等。

表 1:

(enterprise_id int, domain_id text, campaign_id int, event_category text, event_action text, datetime timestamp, subscription_id text, event_label text, ........) (many more columns not part of primary key)

PRIMARY KEY ((enterprise_id,campaign_id),domain_id, event_category, event_action, datetime, subscription_id))

CLUSTERING ORDER BY (domain_id DESC, event_category DESC, event_action DESC, datetime DESC, subscription_id DESC)

表 1 的键和数据大小:

我的分区键为 enterprise_id + campaign_id。每个企业可以有几个活动。数据存储区可能包含数百个活动的数据。每个活动最多可以有 2-3 百万条记录。因此,100 个企业可能有 3000 个分区,每个分区有 2-3 百万条记录。

Cassandra 查询:始终使用分区键 + 主键(包括日期时间字段)进行查询。订阅 id 包含在主键中以保持每条记录的唯一性,因为我们可以为主键中的其余键拥有多个具有相似值的记录。 enterprise_id +c ampaign_id 始终可用作查询中的过滤器。

表 2:

(enterprise_id int, domain_id text, event_category text, event_action text, datetime timestamp, subscription_id text, event_label text, campaign_id int........) (many more columns not part of primary key)

PRIMARY KEY (enterprise_id, domain_id, event_category, event_action, datetime, subscription_id))

CLUSTERING ORDER BY (domain_id DESC, event_category DESC, event_action DESC, datetime DESC, subscription_id DESC)

表 2) 的键和数据大小:我仅将分区键作为企业 ID。每个企业可以有几个活动。可能是几百个活动。每个活动最多可以有 2-3 百万条记录。在这种情况下,分区非常大,所有活动的数据都在一个分区中。最多可以有 800 - 9 亿个条目

Cassandra 查询:始终使用分区键 + 主键到日期时间进行查询。订阅 id 包含在主键中以保持每条记录的唯一性,因为我们可以为主键中的其余键拥有多个具有相似值的记录。在这种情况下,数据必须是跨广告系列的查询,并且我们可能没有campaign_id 作为查询中的过滤器。

表 3:

(enterprise_id int, subscription_id text, domain_id text, event_category text, event_action text, datetime timestamp, event_label text, campaign_id int........) (many more columns not part of primary key)

PRIMARY KEY (enterprise_id, subscription_id, domain_id, event_category, event_action, datetime, ))

CLUSTERING ORDER BY ( subscription_id DESC, domain_id DESC, event_category DESC, event_action DESC, datetime DESC,)

表 3) 的键和数据大小:我将分区键作为企业 ID。每个企业可以有几个活动。可能是几百个活动。每个活动最多可以有 2-3 百万条记录。在这种情况下,分区非常大,所有活动的数据都在一个分区中。最多可以有 800 -9 亿个条目

Cassandra 查询:始终使用分区键 + 主键作为订阅 ID 进行查询。应该可以直接查询enterprise_id + subscription_id。

我的查询:

  1. 每个分区上的数据大小:使用表 2) 和表 3),我可能最终每个分区有超过 800 -9 亿行。根据我的阅读,每个分区有这么多条目是不行的。在这种情况下,我如何实现我的用例?即使我基于某些数据(例如 week_number(一年中 1-52))创建多个分区,查询也需要跨所有分区进行查询并最终使用包含所有周数的 IN 子句,这与扫描所有数据一样好.

  2. 是否可以让多个表具有相同的分区键和不同的主键并更改集群顺序?例如,在表 2 和表 3 中,散列将位于 enterprise_id 上,并将导致相同的节点。但是,只有集群键顺序发生了变化,并且允许我直接查询所需的键。在这种情况下,Table2 和 Table3 的数据会在不同的物理分区中吗?或者如果它映射到相同的分区号,cassandra 将如何在内部区分两个表?

  3. 如果我指定分区键,是否可以使用 ALLOW FILTERING。例如,如果我在表 2 上使用 ALLOW FILTERING,我可以避免创建表 3 并直接使用表 2 来查询 subscription_id。这又会产生什么影响。

【问题讨论】:

    标签: cassandra datamodel


    【解决方案1】:

    首先,每个问题只能作为一个问题。鉴于您的答案所需的长度和细节,这篇文章不太可能为未来的用户提供长期价值。

    根据我的阅读,每个分区有这么多条目是不合适的。在这种情况下如何实现我的用例?

    不幸的是,如果对时间组件进行分区不起作用,那么您将不得不找到其他一些列来对数据进行分区。我已经看到每个分区的行在 50k 到 20k 的范围内都可以正常工作。大多数高端用例都有小分区。看起来您的模型有很多列,所以我很好奇平均分区大小。从本质上讲,找到一个分区列,使您的分区大小保持在 10MB 到 1MB 的范围内。

    是否可以让多个表具有相同的分区键和不同的主键并更改集群顺序?

    是的,这很好。

    在这种情况下,表2和表3的数据会在不同的物理分区中吗?或者如果它映射到相同的分区号,cassandra 将如何在内部区分两个表?

    分区被散列成一个范围为 +/- 2^63 的数字。然后将该数字与映射到所有节点的分区范围进行比较,然后将查询发送到该节点。所以分区所做的就是确定哪个节点负责数据。

    表的数据文件根据表名写入不同的目录。因此 Cassandra 通过查询中提供的表名来区分表。无需担心。

    如果我指定分区键,是否可以使用 ALLOW FILTERING。

    如果您担心性能,我仍然建议您不要这样做。但是使用ALLOW FILTERING 指令同时指定完整分区键的好处确实会阻止Cassandra读取多个节点来构建结果集。所以应该没问题。这里唯一的缺点是,Cassandra 通过定义的CLUSTERING ORDER 从磁盘存储/读取数据,而使用ALLOW FILTERING 显然会使该过程复杂化(强制随机读取与顺序读取)。

    【讨论】:

    • 感谢@Aaron 的投入。如果分区键仅有助于识别应保存数据的节点,并且在节点内我们为不同的表提供不同的文件夹,那么给定节点中每个表的最大行数或每个表可以拥有的数据大小是多少。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-24
    • 2016-03-17
    • 2018-05-19
    • 2015-01-26
    • 1970-01-01
    • 2022-08-19
    相关资源
    最近更新 更多