Cassandra查询超时

时间:2018-01-31 15:07:05

标签: cassandra cassandra-jdbc

我们从大约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和timestamp ??

1 个答案:

答案 0 :(得分: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表,因为那不是您查询它的方式。