Cassandra获取IN子句中包含的每个元素的最新条目

Cassandra获取IN子句中包含的每个元素的最新条目,cassandra,cql,Cassandra,Cql,所以,我有一个Cassandra CQL语句,看起来像这样: SELECT * FROM DATA WHERE APPLICATION_ID = ? AND PARTNER_ID = ? AND LOCATION_ID = ? AND DEVICE_ID = ? AND DATA_SCHEMA = ? PRIMARY KEY ((application_id, partner_id, location_id, device_id, data_schema), activity_timestam

所以,我有一个Cassandra CQL语句,看起来像这样:

SELECT * FROM DATA WHERE APPLICATION_ID = ? AND PARTNER_ID = ? AND LOCATION_ID = ? AND DEVICE_ID = ? AND DATA_SCHEMA = ?
PRIMARY KEY ((application_id, partner_id, location_id, device_id, data_schema), activity_timestamp)
) WITH CLUSTERING ORDER BY (activity_timestamp DESC);
此表按时间戳列排序

该功能前面是一个RESTAPI,以及一个他们可以指定的过滤器参数,以获取最新的行,然后在CQL语句末尾出现“LIMIT 1”,因为它是按时间戳列降序排列的。我想做的是允许他们指定多个设备id以获取最新的条目。所以,我的问题是,在卡桑德拉有没有办法做到这一点:

SELECT * FROM DATA WHERE APPLICATION_ID = ? AND PARTNER_ID = ? AND LOCATION_ID = ? AND DEVICE_ID IN ? AND DATA_SCHEMA = ?
并且仍然使用类似“限制1”的东西来只获取每个设备id的最新行?或者,我是否只需要为每个设备执行一个单独的CQL语句,以获取每个设备的最新行

FWIW,表的复合键如下所示:

SELECT * FROM DATA WHERE APPLICATION_ID = ? AND PARTNER_ID = ? AND LOCATION_ID = ? AND DEVICE_ID = ? AND DATA_SCHEMA = ?
PRIMARY KEY ((application_id, partner_id, location_id, device_id, data_schema), activity_timestamp)
) WITH CLUSTERING ORDER BY (activity_timestamp DESC);
当有很多参数时,不建议使用IN,并且在引擎盖下,它对多个分区进行REQ,并且它对协调器节点施加压力

并不是说你做不到。这是完全合法的,但大多数情况下,这是不履行的,也不是建议的。如果您指定了limit,它将用于整个语句,基本上您不能从分区中只选择第一项。最简单的选择是向集群发出多个查询(在中的
中的每个元素将成为一个查询),并将
限制为1

老实说,这是我在很多项目中的解决方案,效果非常好。基本上,协调器无论如何都会去多个节点,但也需要为您做更多的工作才能得到所有请求,可能会出现超时等情况

简言之,如果客户机多次请求(使用多个具有较小请求的协调器),这对集群和性能都要好得多,而不是让单个协调器完成所有工作

这一切都是为了防止您无法为集群提供更多的磁盘空间

常用卡桑德拉解决方案

建议准备好cassandra中的数据进行查询(先查询)。因此,基本上您必须有一个额外的表,该表将具有与现在相同的分区键,并且您必须删除集群列
activity\u timestamp
。i、 e

PRIMARY KEY ((application_id, partner_id, location_id, device_id, data_schema))
double(())
是故意的

每次写入表时,您也会将数据写入
最新的\u条目
(表中没有
活动\u时间戳
),然后您可以在中指定需要的查询,该表包含最新的条目,因此您不必使用限制1,因为每个分区键只有一个条目。。。这将是卡桑德拉通常的解决方案

如果您害怕额外的写操作,不要担心,它们很便宜并且cpu有限。对于卡桑德拉来说,我想总是“写出来吧:)

基本上取决于你:

  • 多个查询—一点重构,没有额外的空间开销
  • 新架构-写入时附加插入,额外空间成本

  • 您的表定义不适合这样使用IN子句。实际上,它在主键的最后一个字段或集群键的最后一个字段上受支持。因此,您可以:

    • 交换主键的最后两个字段
    • 对每个设备id使用一个查询

    谢谢!这正是我所想的,但我对卡桑德拉还很陌生,所以我只是想确保我没有遗漏什么。我已经在对另一个记录其他内容的表进行额外的每次插入写入操作,因此,如果再有一个记录最新条目的表,可能不会有什么大不了的。我认为这将有助于提高性能,而性能在这里肯定比它所消耗的一点点空间更重要:)好吧,那么你们都很好;)这个项目看起来很有意思:)哦,设备写的频率是多少。考虑使用ButkPress,如果它是一个写得更频繁的东西,比如说每隔几秒或者更多,我可以给出一些建议;就说频率吧,我得调查一下——我还没听说过bucketing。目前,每个“容器”的写入频率为每5秒一次,并且容器的数量有望继续快速增长,因此每5秒将有x次写入,这可能是一个整体。这是每个“桶”每天大约17k个条目。我们有类似的负载,每个月都在减少。基本上,一个月来自一个传感器的所有数据都在一个月分区中。这完全取决于负载。这里有一个答案也可以试试谷歌。这将为您今后节省很多麻烦;)我还发现您的问题的更新有点晚,是在查找其他方面,看起来cassandra的版本永远不会支持每个分区限制:因此基本上您可以使用
    每个分区限制1