我们从大约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 回答
二级索引几乎肯定会失败 . 它们应该具有“不低,不高”的基数(取决于环中的节点数) . 它很难做到正确,你应该真的只是避免使用它,除非有强烈的需要和数据适合(交叉表一致性不可能与非规范化表) .
你永远不应该使用的另一件事是
allow filtering
,那就是调试/开发和大型火花作业,它们正在读取整个数据集 . 它非常昂贵,几乎总会导致长期超时 .相反,您应该创建新表并按时间拆分它们,以便分区不会变得太大 . 即
插入数据时,请同时写入两者 . 实际上,您应该为每种请求创建一个表,因此数据采用您需要的格式 . 不要围绕数据的外观建模表格 . 如果您不需要uuid直接查询消息,请不要像上面那样使用
machine_data
表,因为这不是您查询它的方式 .