Cassandra数据建模-我是否选择热点以简化查询?

Cassandra数据建模-我是否选择热点以简化查询?,cassandra,data-modeling,Cassandra,Data Modeling,即使可能会在集群中创建热点,构建一个数据模型使获取查询更容易,这样做是否可行? 在阅读时,请记住我现在没有使用Solr,鉴于访问这些数据的频率,我认为使用spark sql不合适。我想把这个当成纯粹的卡桑德拉 我们有事务,这些事务使用UUID作为分区键进行建模,以便数据均匀分布在集群中。我们的一种访问模式要求UI获取给定用户和日期范围的所有记录,查询方式如下: select * from transactions_by_user_and_day where user_id = ? and cre

即使可能会在集群中创建热点,构建一个数据模型使获取查询更容易,这样做是否可行?

在阅读时,请记住我现在没有使用Solr,鉴于访问这些数据的频率,我认为使用spark sql不合适。我想把这个当成纯粹的卡桑德拉

我们有事务,这些事务使用UUID作为分区键进行建模,以便数据均匀分布在集群中。我们的一种访问模式要求UI获取给定用户和日期范围的所有记录,查询方式如下:

select * from transactions_by_user_and_day where user_id = ? and created_date_time > ?;
我构建的第一个模型使用用户id和创建日期(事务创建的日期,始终设置为午夜)作为主键:

CREATE transactions_by_user_and_day (
    user_ id int,
    created_date timestamp,
    created_date_time timestamp,
    transaction_id uuid,
    PRIMARY KEY ((user_id, created_date), created_date_time)
) WITH CLUSTERING ORDER BY (created_date_time DESC);
这张桌子看起来很好。使用创建的_日期作为PK的一部分可以让用户更均匀地分布在集群中,以防止热点。然而,从访问的角度来看,它使数据访问层做了更多我们想要的工作。它最终必须创建一个IN语句,其中所有日期都在提供的范围内,而不是给出日期和大于运算符:

select * from transactions_by_user_and_day where user_id = ? and created_date in (?, ?, …) and created_date_time > ?;
为了简化数据访问层的工作,我考虑了如下数据建模:

CREATE transactions_by_user_and_day (
    user_id int,
    created_date_time timestamp,
    transaction_id uuid,
    PRIMARY KEY ((user_global_id), created_date_time)
) WITH CLUSTERING ORDER BY (created_date_time DESC);
使用上述模型,数据访问层可以为用户获取事务id,并在Cassandra中的特定日期范围内进行过滤。但是,这会导致集群内出现热点。长寿和/或高容量的用户将在行中创建更多的列。我们打算在数据上提供TTL,以便任何超过60天的数据都会丢失。此外,我还分析了数据的大小,我们最大的高容量用户60天的数据量不足2MB。通过计算,如果我们假设所有40000个用户(这个数字不会显著增长)平均分布在一个3节点集群上,每个用户有2MB的数据,那么每个节点的最大数据量将略高于26GB((13333.33*2)/1024)。事实上,你不会让1/3的用户完成那么多的容量,你会非常不幸地让Cassandra使用V节点将所有用户放在一个节点上。从资源的角度来看,我认为26GB也不会创造或破坏任何东西


感谢您的想法。

日期模型1:您可以做的其他事情是更改数据访问层,以单独查询每个ID,而不是使用IN子句。查看此页面以了解为什么这样做会更好

数据模型2:每个节点26GB的数据似乎不多,但2MB的数据获取似乎有点大。当然,如果这是一个异常值,那么我看不出有什么问题。您可以尝试设置一个cassandra压力作业来测试模型。只要大部分分区小于2MB,就可以了


另一个解决方案是使用带Bucketing的数据模型2。这会给您带来更多的写操作开销,因为您还必须维护一个bucket查找表。如果需要我详细说明此方法,请告诉我。

谢谢@gsteiner。我没有考虑过使用IN子句可能会出现的问题,感谢您为我指明了方向。让数据访问层执行如此多的查询仍然是我们想要回避的事情,这对我们来说似乎很奇怪(也许这就是我们长期以来一直生活在的关系世界)。我肯定会用这些数据做一些压力测试,看看结果如何。我很想多听听关于扣球的事。我读过一些关于它的文章,看起来我仍然会在数据访问层运行几个查询,获取我需要的bucket,然后查询它们。不想做很多查询是一件非常“相关”的事情。Cassandra实际上可以更好地处理大量查询,因为每个查询都将使用最适合该查询的协调器节点。是的,对于bucket,您仍然需要执行多个查询,但查询量要比模型1少。这取决于你的桶大小。