用于 IOT 的 cassandra 中的数据建模
Data Modelling in cassandra for IOT
我们正在尝试在基于物联网的应用程序中使用 Apache Cassandra。我们计划创建一个设备抽象。任何用户都应该能够定义具有一系列属性的设备。对于每个属性,用户应能够定义一系列属性,如 名称、数据类型、最小值、最大值等
下面给出了一些设备示例
车辆
车辆可以具有以下属性
- 速度[名称:- 速度,数据类型:- double,最小值:- 0,最大值:-300]
- 纬度 [名称:- 速度,数据:- 双精度,最小值:- -90,最大值:-90]
- 经度[名称:- 经度,数据:- double,最小值:- -180,最大值:- 180]
温度传感器
温度传感器可以有以下属性
- 当前温度[名称:- 当前温度,数据类型:- double,最小值:- 0,最大值:-300]
- 单位[名称:- 单位,数据类型:-字符串]
实时地,每个设备将以键值对的形式发送数据。
例如:- A Vehicle 可以发送以下数据
时间:- 6/4/2016 11:15:15.150,纬度:-1.256,经度:- -180.75,速度:- 50
时间:- 6/4/2016 11:15:16.150,纬度:-1.257,经度:- -181.75,速度:- 51
例如:- 温度传感器可以发送以下数据
时间:- 6/4/2016 11:15:15.150,当前温度:100,单位:华氏度
时间:- 6/4/2016 11:15:16.150,纬度:101,单位:华氏度
由于不同设备的属性可能不同,我们对 cassandra 中的 table 模型如何建模感到困惑...想到的一些选项是 创建一个table 用于设备,或者创建单个 table 并将值存储在 Map 数据类型中......我们对应该采用哪种方法感到困惑......
任何建议表示赞赏
您是否考虑过在 Cassandra 中使用不同的收集数据类型来存储设备之间不同的信息?
https://docs.datastax.com/en/cql/3.0/cql/cql_using/use_collections_c.html
绝对不要为每个设备创建 table。我想您最终会得到 100s/1000s 的 tables,而对它们的建模方式的控制却很少。 Cassandra 处理得不是很好,因为它需要每个 table 的内存,这将减少键缓存和行缓存(如果使用的话)可用的内存。
map 方法可能是可行的,但是在沿着该路径前进之前需要考虑一些事项:
设备条目会经常更新吗?您将如何更新它?
如果您计划更新地图中的每个元素,则必须单独更新每个元素。这样做的原因是 Cassandra 中的集合覆盖将为每个覆盖创建一个范围墓碑。如果频繁覆盖,那么您最终会得到数百万个墓碑,这些墓碑可能最终不会像您希望的那样有效地被压缩。这可以通过使用 JSON 类型来避免,并在您的应用程序中处理它。
您还需要考虑如何查询数据,如果您希望用户能够查询地图中的数据,可能会变得更复杂一些。我认为您最好使用一种查询方法,而不管设备类型如何,然后在您的应用程序中提取详细信息。然而,这取决于您,并且几乎是您构建数据的方式的驱动力。我能给出的最好建议是尽量避免创建过多的 table,并且要小心不要让用户对数据结构有过多的控制权,因为这样做很容易做得不好并导致性能问题在集群上。
如果您还没有阅读过此博客 - 它指出了在使用 Cassandra 时需要正确掌握的数据模型设计的基本元素。 http://www.datastax.com/dev/blog/basic-rules-of-cassandra-data-modeling
我认为最好的选择是只创建一个 table 具有用于收集时间序列数据的通用架构。
CQL 示例:
CREATE TABLE timeline (
device uuid,
time timeuuid,
key text,
value blob,
…
PRIMARY KEY ((device, key), time)
);
值可以存储为 blob(自定义序列化)、map 或 numeric scalars ,取决于您的应用程序用例和数据访问模式(如何 read/write/delete 以及您是否计划支持 更新 )。
仅供参考,有关时间序列建模的有用的相关 Datastax 帖子:
我们正在尝试在基于物联网的应用程序中使用 Apache Cassandra。我们计划创建一个设备抽象。任何用户都应该能够定义具有一系列属性的设备。对于每个属性,用户应能够定义一系列属性,如 名称、数据类型、最小值、最大值等
下面给出了一些设备示例
车辆
车辆可以具有以下属性
- 速度[名称:- 速度,数据类型:- double,最小值:- 0,最大值:-300]
- 纬度 [名称:- 速度,数据:- 双精度,最小值:- -90,最大值:-90]
- 经度[名称:- 经度,数据:- double,最小值:- -180,最大值:- 180]
温度传感器
温度传感器可以有以下属性
- 当前温度[名称:- 当前温度,数据类型:- double,最小值:- 0,最大值:-300]
- 单位[名称:- 单位,数据类型:-字符串]
实时地,每个设备将以键值对的形式发送数据。
例如:- A Vehicle 可以发送以下数据
时间:- 6/4/2016 11:15:15.150,纬度:-1.256,经度:- -180.75,速度:- 50
时间:- 6/4/2016 11:15:16.150,纬度:-1.257,经度:- -181.75,速度:- 51
例如:- 温度传感器可以发送以下数据
时间:- 6/4/2016 11:15:15.150,当前温度:100,单位:华氏度
时间:- 6/4/2016 11:15:16.150,纬度:101,单位:华氏度
由于不同设备的属性可能不同,我们对 cassandra 中的 table 模型如何建模感到困惑...想到的一些选项是 创建一个table 用于设备,或者创建单个 table 并将值存储在 Map 数据类型中......我们对应该采用哪种方法感到困惑...... 任何建议表示赞赏
您是否考虑过在 Cassandra 中使用不同的收集数据类型来存储设备之间不同的信息?
https://docs.datastax.com/en/cql/3.0/cql/cql_using/use_collections_c.html
绝对不要为每个设备创建 table。我想您最终会得到 100s/1000s 的 tables,而对它们的建模方式的控制却很少。 Cassandra 处理得不是很好,因为它需要每个 table 的内存,这将减少键缓存和行缓存(如果使用的话)可用的内存。
map 方法可能是可行的,但是在沿着该路径前进之前需要考虑一些事项:
设备条目会经常更新吗?您将如何更新它? 如果您计划更新地图中的每个元素,则必须单独更新每个元素。这样做的原因是 Cassandra 中的集合覆盖将为每个覆盖创建一个范围墓碑。如果频繁覆盖,那么您最终会得到数百万个墓碑,这些墓碑可能最终不会像您希望的那样有效地被压缩。这可以通过使用 JSON 类型来避免,并在您的应用程序中处理它。
您还需要考虑如何查询数据,如果您希望用户能够查询地图中的数据,可能会变得更复杂一些。我认为您最好使用一种查询方法,而不管设备类型如何,然后在您的应用程序中提取详细信息。然而,这取决于您,并且几乎是您构建数据的方式的驱动力。我能给出的最好建议是尽量避免创建过多的 table,并且要小心不要让用户对数据结构有过多的控制权,因为这样做很容易做得不好并导致性能问题在集群上。
如果您还没有阅读过此博客 - 它指出了在使用 Cassandra 时需要正确掌握的数据模型设计的基本元素。 http://www.datastax.com/dev/blog/basic-rules-of-cassandra-data-modeling
我认为最好的选择是只创建一个 table 具有用于收集时间序列数据的通用架构。
CQL 示例:
CREATE TABLE timeline (
device uuid,
time timeuuid,
key text,
value blob,
…
PRIMARY KEY ((device, key), time)
);
值可以存储为 blob(自定义序列化)、map 或 numeric scalars ,取决于您的应用程序用例和数据访问模式(如何 read/write/delete 以及您是否计划支持 更新 )。
仅供参考,有关时间序列建模的有用的相关 Datastax 帖子: