我们从大约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 ??
答案 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
表,因为那不是您查询它的方式。