Cassandra 查询超时

Cassandra query timeout

我们正在从大约 20-25 个工业电机传感器中提取数据,数据存储在 cassandra 中 database.Cassandra 目前 运行 在单个节点中。

下面是table结构

CREATE TABLE cisonpremdemo.machine_data (
    id uuid PRIMARY KEY,
    data_temperature bigint,
    data_current bigint,
    data_timestamp timestamp,
    deviceid text,
    
) WITH bloom_filter_fp_chance = 0.01
    AND caching = {'keys': 'ALL', 'rows_per_partition': 'NONE'}
    AND default_time_to_live = 7884000
    AND gc_grace_seconds = 100;
 
CREATE INDEX deviceid_idx ON db.machine_data (deviceid);
CREATE INDEX data_timestamp_idx ON db.machine_data (data_timestamp);

在这 table 中收集了几个月的数据,比如每 5 秒收集一次,持续将近 24 小时,因此数据量相当大。

我正在尝试使用 java 和 dotnet 执行基于日期范围的查询,在这两种情况下我都收到超时错误(Cassandra 在读取查询期间失败,一致性为 LocalOne(0 个副本响应超过需要 1 个))

如果我给出 100 的限制,查询工作正常,否则它会失败超过 that.Some 我尝试过的事情...

1) 增加了查询超时时间。 2) 将 gc_grace_seconds 减少到 100(暂时)以消除任何墓碑。

已使用查询

SELECT data_temperature AS "DATA_TEMP",data_current AS "DATA_CURRENT" FROM machine_data 
WHERE DATA_TIMESTAMP>=1517402474699 
AND DATA_TIMESTAMP<=1517402774699 
AND DEVICEID='BP_100' ALLOW FILTERING;

不确定 table 结构(主键)是否选择错误。是否应该同时是 deviceid 和 timestamp ??

二级索引几乎肯定会失败。它们应该具有 "not to low, not to high" 基数(这取决于环中的节点数)。很难做到正确,你真的应该避免使用它,除非有强烈的需求并且数据适合(非规范化 table 不可能实现交叉 table 一致性)。

另一个你永远不应该使用的东西是 allow filtering,它几乎只用于 debugging/development 和大型 spark 作业有点像读取整个数据集的东西。它非常昂贵,而且几乎总是会导致长期超时。

相反,您应该创建新的 tables 并按时间分解它们,这样分区就不会变得太大。即

CREATE TABLE cisonpremdemo.machine_data_by_time (
    id uuid PRIMARY KEY,
    data_temperature bigint,
    data_current bigint,
    data_timestamp timestamp,
    yymm text,
    deviceid text,
    PRIMARY KEY ((deviceid, yymm), data_timestamp)
) WITH CLUSTERING ORDER BY (data_timestamp DESC);

插入数据时,写入两者。您基本上应该为您拥有的每种请求创建一个 table,以便数据采用您需要的格式。不要围绕数据的外观对 table 进行建模。如果您不需要通过 uuid 进行直接消息查找,请完全不要像上面那样制作 machine_data table,因为那不是您查询它的方式。