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