Cassandra时间切片数据模型的未知数据

时间:2013-11-06 17:25:41

标签: cassandra

我告诉我这个问题:我对NoSQL有点新,对Cassandra来说很新,但似乎它可能非常适合我正在尝试做的事情。

假设我有一个传感器列表,以合理的间隔提供输入。我建议的数据模型是按传感器的名称进行分区,它是(区域)和日期(写为yyyyMMdd),而群集是那天读数发生的实际读数。我们的想法是,“在日期B获取传感器A的所有读数”的查询应该非常快。到目前为止,我认为这么好。表/ CF在CQL中看起来像这样:

CREATE TABLE data (
    area_id int,
    sensor varchar,
    date ascii,
    event_time timeuuid,
    PRIMARY KEY ((area_id, sensor, date), event_time)
) WITH CLUSTERING ORDER BY (event_time DESC);

但实际上并不包含任何数据,我不知道如何将其添加到模型中。每次读取(来自同一传感器)都可以有一组不同的任意数据,我不会提前知道这是什么。例如。我可以得到温度数据,我可以得到湿度,我可以得到两者,或者我可以得到我以前没见过的东西。由实际记录数据的人决定他们想要提交的内容(不是从自动传感器读取)。

鉴于我想对这些数据(基本上是UGC)进行查询操作,我的选择是什么?查询通常包括对数据的计数(例如,在日期B计数来自传感器A的读数,其中some_ugc_valueX = C且some_ugc_valueY = D)。值得注意的是,将会有比通常一次查询更多的数据点。读数可能有20个数据值,但可能只会查询2个或3个 - 只是提前知道它是未知的。

目前我想到了:

  1. 将每个传感器读数的数据存储为Map类型。这肯定会使模型变得简单,但我的理解是查询会很困难吗?我想我需要为每个传感器读取拉回整个地图,然后检查值并将它计算在Storm / Hadoop / Cassandra之外。
  2. 将每个用户值存储为另一列(具有event_time uuid的复合列)。这意味着不使用CQL,因为它不支持在插入时添加任意新列。然而,Thrift API允许这样做。这意味着我可以让Cassandra自己进行计数。
  3. 也许我会以错误的方式解决这个问题?也许Cassandra甚至不是这类数据的最佳选择?

1 个答案:

答案 0 :(得分:0)

TL;博士。你不能同时选择速度和绝对灵活性; - )

基于来自用户生成内容的数据的查询将变得复杂 - 您将无法生成一个通用的表定义,以允许基于UGC内容的查询的快速响应。即使您选择使用地图,Cassandra也必须在每个查询中反序列化整个数据结构,因此它不是大地图的选项 - 正如您在问题中建议的那样可能就是这种情况。

替代方案可以是以序列化形式存储传感器数据,例如json。这将为存储的内容提供最大的灵活性 - 代价是无法进行复杂的查询。序列化/反序列化负担被推送到客户端,所有数据都通过线路发送。这是一个简单的例子:

创建表格(比你的例子稍微简单一点 - 我放弃了date):

create table data(
  area_id int, 
  sensor varchar, 
  event_time timeuuid, 
  data varchar, 
  primary key(area_id,sensor,event_time)
);

插入:

insert into data(area_id,sensor,event_time,data) VALUES (1,'sensor1',now(),'["datapoint1":"value1"]');
insert into data(area_id,sensor,event_time,data) VALUES (1,'sensor2',now(),'["datapoint1":"value1","count":"7"]');

按area_id和传感器查询:

>select area_id,sensor,dateof(event_time),data from data where area_id=1 and sensor='sensor1';

 area_id | sensor  | dateof(event_time)       | data
---------+---------+--------------------------+-------------------------
       1 | sensor1 | 2013-11-06 17:37:02+0000 | ["datapoint1":"value1"]

(1 rows)

按area_id查询:

> select area_id,sensor,dateof(event_time),data from data where area_id=1;

 area_id | sensor  | dateof(event_time)       | data
---------+---------+--------------------------+-------------------------------------
       1 | sensor1 | 2013-11-06 17:37:02+0000 |             ["datapoint1":"value1"]
       1 | sensor2 | 2013-11-06 17:40:49+0000 | ["datapoint1":"value1","count":"7"]

(2 rows)

(使用[cqlsh 4.0.1 | Cassandra 2.0.1 | CQL spec 3.1.1 | Thrift protocol 19.37.0]测试。)