我是 Cassandra 的新手,对分区键和集群键有点困惑。
听起来您了解分区键,所以我将添加您的分区键帮助 Cassandra 确定集群中存储数据的位置(哪个令牌范围)。每个节点负责几个主要令牌范围(假设是 vnode)。当您的数据写入数据分区时,它会按您的集群键排序。这也是它在磁盘上的存储方式,因此请记住,您的集群键决定了数据在磁盘上的存储顺序。
每个分区最多可以有 20 亿行
这并不完全正确。每个分区最多可支持 20 亿个单元。单元格本质上是一个列名/值对。并且您的聚类键本身会加起来一个单元格。因此,通过计算您为每个 CQL 行存储的列值来计算您的单元格,如果您使用聚类列,则再添加一个。
根据您的宽行结构,您的行数可能会远远少于 20 亿行。此外,这只是存储限制。即使您设法在单个分区中存储 100 万条 CQL 行,查询该分区也会返回大量数据,以至于它会很笨拙并且可能会超时。
如果我在同一个节点内查询数据,检索会很快,对吗?
它至少比命中多个节点的多键查询要快。但它是否会“快速”取决于其他因素,例如行的宽度,以及执行删除和就地更新等操作的频率。
我的大部分查询如下:
select lastest timestamp of know deviceid and tagid
Select decvalue of known deviceid and tagid and timestamp
Select alphavalue of known deviceid and tagid and timestamp
select * of know deviceid and tagid with time range
select * of known deviceid with time range
您当前的数据模型可以支持所有这些查询,最后一个除外。为了对timestamp 执行范围查询,您需要将数据复制到一个新表中,并构建一个主键来支持该查询模式。这称为“基于查询的建模”。我会建立一个这样的查询表:
CREATE TABLE newdata_by_deviceid_and_time (
timestamp timestamp,
deviceid int,
tagid int,
decvalue decimal,
alphavalue text,
PRIMARY KEY (deviceid,timestamp));
该表可以支持对timestamp 的范围查询,同时对deviceid 进行分区。
但我发现这两种模型中最大的问题是“无限制的行增长”。基本上,随着您为设备收集越来越多的值,您将接近每个分区 20 亿个单元的限制(同样,在此之前事情可能会变得缓慢)。您需要做的是使用一种称为“时间分段”的建模技术。
例如,我会说我确定按月分桶将使我保持在 20 亿个单元格限制以下并且允许我需要的日期范围灵活性类型。如果是这样,我将添加一个额外的分区键monthbucket,我的(新)表将如下所示:
CREATE TABLE newdata_by_deviceid_and_time (
timestamp timestamp,
deviceid int,
tagid int,
decvalue decimal,
alphavalue text,
monthbucket text,
PRIMARY KEY ((deviceid,monthbucket),timestamp));
现在,当我想查询特定设备和日期范围内的数据时,我还会指定monthbucket:
SELECT * FROM newdata_by_deviceid_and_time
WHERE deviceid='AA23' AND monthbucket='201603'
AND timestamp >= '2016-03-01 00:00:00-0500'
AND timestamp < '2016-03-16 00:00:00-0500';
请记住,monthbucket 只是一个示例。对您而言,使用季度甚至年度可能更有意义(假设您一年内每个 deviceid 没有存储太多值)。