首页 文章

Cassandra查询超时

提问于
浏览
1

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

下面是表格结构

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);

数据正在这个表中收集,持续几个月,每隔5小时就会说差不多24小时,所以数据量非常大 .

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

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

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;

不确定表结构(主键)是否是错误的选择 . 应该是deviceid还是时间戳?

1 回答

  • 2

    二级索引几乎肯定会失败 . 它们应该具有“不低,不高”的基数(取决于环中的节点数) . 它很难做到正确,你应该真的只是避免使用它,除非有强烈的需要和数据适合(交叉表一致性不可能与非规范化表) .

    你永远不应该使用的另一件事是 allow filtering ,那就是调试/开发和大型火花作业,它们正在读取整个数据集 . 它非常昂贵,几乎总会导致长期超时 .

    相反,您应该创建新表并按时间拆分它们,以便分区不会变得太大 . 即

    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);
    

    插入数据时,请同时写入两者 . 实际上,您应该为每种请求创建一个表,因此数据采用您需要的格式 . 不要围绕数据的外观建模表格 . 如果您不需要uuid直接查询消息,请不要像上面那样使用 machine_data 表,因为这不是您查询它的方式 .

相关问题