您当前的位置:首页 > 互联网百科 > 物联网

5 种物联网数据模型

时间:2022-08-13 13:39:45  来源:  作者:qaseven

Apache Cassandra是大规模管理 IoT 和时间序列数据的可靠选择。在 Cassandra 中存储、查询和分析 IoT 设备生成的时间序列的最流行用例已得到很好的理解和记录。通常,时间序列是根据其源 IoT 设备存储和查询的。但是,还有另一类 IoT​ 应用程序需要快速访问由一组 IoT 设备基于已知状态生成的最新数据。此类应用程序需要回答的问题是:哪些物联网设备或传感器当前正在报告特定状态?在这篇博文中,我们将重点关注这个问题,并提供五种可能的数据建模解决方案,以便在 Cassandra 中有效地回答这个问题。

介绍

物联网 (IoT) 正在生成大量需要存储、查询和分析的时间序列数据。Apache Cassandra 是这项任务的绝佳选择:不仅因为它的速度、可靠性和可扩展性,还因为它的内部数据模型内置了对时间排序数据的支持。

在 Cassandra 中,时间序列通常由源(例如,IoT 设备或传感器)或主题(例如,参数或度量)存储和检索。有很多很好的资源非常详细地涵盖了这个主题,包括这个会议演示视频,以及用于传感器数据和时间序列的即用型 Cassandra 数据模型。

在这篇文章中,我们研究了一类相关的物联网用例,它们需要管理来自许多物联网设备的最新数据的快照。此外,需要根据物联网设备报告的特定状态来查询或过滤这样的快照。换句话说,我们应该能够在 Cassandra 中快速回答这个问题:哪些物联网设备当前正在报告特定状态?对于许多现实生活中的用例,这个问题听起来更像是:

  • 智能家居中当前打开(关闭)哪些灯?
  • 停车结构中当前有哪些停车位被占用(空置)?
  • 当前在特定位置附近有哪些车辆可用(不可用)?
  • 当前在某个区域触发(激活、禁用)哪些安全警报?
  • 建筑物中当前打开(关闭、锁定、解锁)哪些门?
  • 哪些火灾探测传感器当前报告传感器网络中的异常(正常待机、错误)状态?

在下文中,我们更正式地定义了这个问题,并通过示例 CQL 实现提出了五个实用的解决方案。

问题定义

给定一组 IoT 设备或传感器,这些设备或传感器生成包含时间戳、数据点和状态的按时间排序的事件序列,找到所有 IoT 设备报告的具有已知状态的最新事件。这个问题的三个关键组成部分如下图所示,描述如下:

  1. 输入由物联网设备生成的时间序列组成。时间序列通常存储在一个或多个 Cassandra 表中。
  2. 中间视图是 IoT 设备报告的仅最新事件的快照。可以单独显式存储最新事件,也可以根据输入动态计算它们。
  3. 最终结果是所有具有已知状态的最新事件。具有相同状态的最新事件应该存储在一起或易于计算。

基于状态管理最新的 IoT 事件

我们确定了基于状态管理最新物联网事件的几个挑战:

  • 最新事件的快照不断发展。可能需要额外的努力来增量捕获任何更改。
  • 事件发生的频率通常是不可预测的。仅基于事件的时间戳组件可能难以对事件进行分区和组织。
  • 一个状态通常只能采用几个唯一值。基于低基数列对数据进行分区和索引可能会导致大分区。

我们使用以下运行示例作为起点。表 events_by_device 是输入。这张具有多行分区的表旨在存储时间序列,这样每个分区对应一个设备,分区中的行表示具有时间戳、状态和值的事件。每个分区中的事件始终按其时间戳降序排序。该表实质上每个分区存储一个时间序列。我们将五个事件插入表中并检索一个设备的时间序列。此外,在第二个查询中,我们证明可以动态计算所有设备的所有最新事件。不幸的是,我们不应该依赖这个查询来解决问题:它可能会变得非常昂贵,因为它访问表中的每个分区。

架构

CQL

-- All events by deviceCREATE TABLE events_by_device (    device_id  UUID,    timestamp  TIMESTAMP,    state      TEXT,    value      TEXT,    PRIMARY KEY((device_id), timestamp)) WITH CLUSTERING ORDER BY (timestamp DESC);

 

数据:

CQL

-- Event 1-1INSERT INTO events_by_device        (device_id, timestamp, state, value)VALUES (11111111-aaaa-bbbb-cccc-12345678abcd,         '2021-01-01 01:11:11', 'on', 'event 1-1');-- Event 1-2INSERT INTO events_by_device        (device_id, timestamp, state, value)VALUES (11111111-aaaa-bbbb-cccc-12345678abcd,         '2021-01-01 02:22:22', 'off', 'event 1-2');-- Event 1-3INSERT INTO events_by_device        (device_id, timestamp, state, value)VALUES (11111111-aaaa-bbbb-cccc-12345678abcd,         '2021-01-01 03:33:33', 'on', 'event 1-3');-- Event 2-1INSERT INTO events_by_device        (device_id, timestamp, state, value)VALUES (22222222-aaaa-bbbb-cccc-12345678abcd,         '2021-02-02 01:11:11', 'off', 'event 2-1');-- Event 3-1INSERT INTO events_by_device        (device_id, timestamp, state, value)VALUES (33333333-aaaa-bbbb-cccc-12345678abcd,         '2021-03-03 01:11:11', 'off', 'event 3-1');

 

查询:

CQL

-- Find all events for a deviceSELECT device_id, timestamp, state, valueFROM   events_by_deviceWHERE  device_id = 11111111-aaaa-bbbb-cccc-12345678abcd; device_id                            | timestamp                       | state | value--------------------------------------+---------------------------------+-------+----------- 11111111-aaaa-bbbb-cccc-12345678abcd | 2021-01-01 03:33:33.000000+0000 |    on | event 1-3 11111111-aaaa-bbbb-cccc-12345678abcd | 2021-01-01 02:22:22.000000+0000 |   off | event 1-2 11111111-aaaa-bbbb-cccc-12345678abcd | 2021-01-01 01:11:11.000000+0000 |    on | event 1-1-- Find the latest events for all devicesSELECT device_id, timestamp, state, valueFROM   events_by_devicePER PARTITION LIMIT 1; device_id                            | timestamp                       | state | value--------------------------------------+---------------------------------+-------+----------- 33333333-aaaa-bbbb-cccc-12345678abcd | 2021-03-03 01:11:11.000000+0000 |   off | event 3-1 22222222-aaaa-bbbb-cccc-12345678abcd | 2021-02-02 01:11:11.000000+0000 |   off | event 2-1 11111111-aaaa-bbbb-cccc-12345678abcd | 2021-01-01 03:33:33.000000+0000 |    on | event 1-3

 

请注意,我们可以假设每个设备的事件数不超过 100,000。否则,我们可能不得不通过在其分区键定义中引入另一列来进一步拆分表 events_by_device 中的分区。由于这对于我们在这篇文章中解决的问题并不重要,所以让我们保持简单。

鉴于问题定义和IoT 事件的运行 CQL 示例,我们准备描述具有不同特征的五种解决方案。

解决方案一:物化视图

第一个解决方案需要一个新表和一个物化视图。表 latest_events_by_device 是一个单行分区表,其中每个分区对应一个设备,每一行对应最新的已知事件。此表的目的是仅获取 IoT 设备报告的最新事件的快照。该表也是物化视图 latest_events_by_state 的基表,可以使用状态查询最新事件。

请注意,完全相同的数据被插入到表 events_by_device 和 latest_events_by_device 中。但是,对于后者,插入变为更新插入,将行更新为最新事件。

架构:

CQL

-- Latest known events by deviceCREATE TABLE latest_events_by_device (    device_id  UUID,    timestamp  TIMESTAMP,    state      TEXT,    value      TEXT,    PRIMARY KEY((device_id)));-- Latest events by stateCREATE MATERIALIZED VIEW latest_events_by_state AS   SELECT * FROM latest_events_by_device  WHERE state IS NOT NULL AND device_id IS NOT NULLPRIMARY KEY ((state), device_id);

 

数据:

CQL

-- Event 1-1INSERT INTO latest_events_by_device        (device_id, timestamp, state, value)VALUES (11111111-aaaa-bbbb-cccc-12345678abcd,         '2021-01-01 01:11:11', 'on', 'event 1-1');-- Event 1-2INSERT INTO latest_events_by_device        (device_id, timestamp, state, value)VALUES (11111111-aaaa-bbbb-cccc-12345678abcd,         '2021-01-01 02:22:22', 'off', 'event 1-2');-- Event 1-3INSERT INTO latest_events_by_device        (device_id, timestamp, state, value)VALUES (11111111-aaaa-bbbb-cccc-12345678abcd,         '2021-01-01 03:33:33', 'on', 'event 1-3');-- Event 2-1INSERT INTO latest_events_by_device        (device_id, timestamp, state, value)VALUES (22222222-aaaa-bbbb-cccc-12345678abcd,         '2021-02-02 01:11:11', 'off', 'event 2-1');-- Event 3-1INSERT INTO latest_events_by_device        (device_id, timestamp, state, value)VALUES (33333333-aaaa-bbbb-cccc-12345678abcd,         '2021-03-03 01:11:11', 'off', 'event 3-1');

 

查询:

CQL

-- Find all the latest events with state 'on'SELECT state, device_id, timestamp, valueFROM   latest_events_by_stateWHERE  state = 'on'; state | device_id                            | timestamp                       | value-------+--------------------------------------+---------------------------------+-----------    on | 11111111-aaaa-bbbb-cccc-12345678abcd | 2021-01-01 03:33:33.000000+0000 | event 1-3-- Find all the latest events with state 'off'SELECT state, device_id, timestamp, valueFROM   latest_events_by_stateWHERE  state = 'off'; state | device_id                            | timestamp                       | value-------+--------------------------------------+---------------------------------+-----------   off | 22222222-aaaa-bbbb-cccc-12345678abcd | 2021-02-02 01:11:11.000000+0000 | event 2-1   off | 33333333-aaaa-bbbb-cccc-12345678abcd | 2021-03-03 01:11:11.000000+0000 | event 3-1

 

物化视图解决方案具有以下特点:

  • 适用性:基于状态的查询返回 100K 行/100MB 或更少的数据。
  • 优点:视图是自动维护的;完美的表现。
  • 缺点:物化视图有一些限制;数据分布可能会出现偏差。

为了支持多租户,我们可以把表的主键改成PRIMARY KEY((tenant, device_id))或者PRIMARY KEY((tenant), device_id),物化视图的主键改成PRIMARY KEY((tenant, state), device_id )。多租户也可能有助于改善数据分布。

只要您了解并愿意抵消物化视图的限制,此数据模型就可以成为许多应用程序的简单、有效和高效的选择。这种数据模型的另一个不太明显的优势是从 Apache Pulsar 或 Apache Kafka 等事件流平台提供数据是多么容易。所有事件都可以转到基表,而物化视图负责其余的事情。

方案二:二级索引

第二种解决方案需要一个新表和一个二级索引。该表与物化视图解决方案中的表相同。表 latest_events_by_device 是一个单行分区表,其中每个分区对应一个设备,每一行对应最新的已知事件。此表的目的是仅获取 IoT 设备报告的最新事件的快照。为该表创建二级索引latest_events_by_state_2i,用于根据状态查询最新事件。

再一次,完全相同的数据被插入到表 events_by_device 和 latest_events_by_device 中。但是,对于后者,插入变为更新插入,将行更新为最新事件。

架构:

CQL

-- Latest known events by deviceCREATE TABLE latest_events_by_device (    device_id  UUID,    timestamp  TIMESTAMP,    state      TEXT,    value      TEXT,    PRIMARY KEY((device_id)));-- Latest events by stateCREATE INDEX latest_events_by_state_2i ON latest_events_by_device (state);

 

数据:

CQL

-- Event 1-1INSERT INTO latest_events_by_device        (device_id, timestamp, state, value)VALUES (11111111-aaaa-bbbb-cccc-12345678abcd,         '2021-01-01 01:11:11', 'on', 'event 1-1');-- Event 1-2INSERT INTO latest_events_by_device        (device_id, timestamp, state, value)VALUES (11111111-aaaa-bbbb-cccc-12345678abcd,         '2021-01-01 02:22:22', 'off', 'event 1-2');-- Event 1-3INSERT INTO latest_events_by_device        (device_id, timestamp, state, value)VALUES (11111111-aaaa-bbbb-cccc-12345678abcd,         '2021-01-01 03:33:33', 'on', 'event 1-3');-- Event 2-1INSERT INTO latest_events_by_device        (device_id, timestamp, state, value)VALUES (22222222-aaaa-bbbb-cccc-12345678abcd,         '2021-02-02 01:11:11', 'off', 'event 2-1');-- Event 3-1INSERT INTO latest_events_by_device        (device_id, timestamp, state, value)VALUES (33333333-aaaa-bbbb-cccc-12345678abcd,         '2021-03-03 01:11:11', 'off', 'event 3-1');

 

查询:

CQL

-- Find all the latest events with state 'on'SELECT state, device_id, timestamp, valueFROM   latest_events_by_deviceWHERE  state = 'on'; state | device_id                            | timestamp                       | value-------+--------------------------------------+---------------------------------+-----------    on | 11111111-aaaa-bbbb-cccc-12345678abcd | 2021-01-01 03:33:33.000000+0000 | event 1-3-- Find all the latest events with state 'off'SELECT state, device_id, timestamp, valueFROM   latest_events_by_deviceWHERE  state = 'off'; state | device_id                            | timestamp                       | value-------+--------------------------------------+---------------------------------+-----------   off | 33333333-aaaa-bbbb-cccc-12345678abcd | 2021-03-03 01:11:11.000000+0000 | event 3-1   off | 22222222-aaaa-bbbb-cccc-12345678abcd | 2021-02-02 01:11:11.000000+0000 | event 2-1

 

二级索引方案具有以下特点:

  • 适用性:基于状态的查询返回 100K 行/100MBs 或更多的数据;基于状态的查询很少执行。
  • 优点:在检索大型结果集时,可以更好地在集群中的节点之间分配查询工作负载。
  • 缺点:二级索引有一些限制;对于实时应用程序,性能可能会变得不令人满意。

在某些情况下,这种数据模型可能是一个合理的选择。特别是,当通过将表主键更改为 PRIMARY KEY((tenant), device_id) 来引入多租户时,我们可以达到使用二级索引进行实时事务查询的最佳时机。那是在基于分区键和查询谓词中指定的索引列从大型多行分区中检索行时。

解决方案 3:状态分区表

第三种解决方案依赖表 latest_events_by_state 使用状态来组织和查询最新事件。每次向该表中插入具有某种状态的事件时,都必须删除同一物联网设备的具有其他状态的任何过时事件。在我们的示例中,每个事件都有一个插入和一个删除,因为我们只有两个唯一状态。如果我们有三种可能的状态,每个新事件将导致一次插入和两次删除。

架构:

CQL

-- Latest events by stateCREATE TABLE latest_events_by_state (    state      TEXT,    device_id  UUID,    timestamp  TIMESTAMP,    value      TEXT,    PRIMARY KEY((state), device_id));

 

数据:

CQL

-- Event 1-1INSERT INTO latest_events_by_state        (state, device_id, timestamp, value)VALUES ('on', 11111111-aaaa-bbbb-cccc-12345678abcd,         '2021-01-01 01:11:11', 'event 1-1');DELETE FROM latest_events_by_state WHERE state = 'off' AND      device_id = 11111111-aaaa-bbbb-cccc-12345678abcd;-- Event 1-2INSERT INTO latest_events_by_state        (state, device_id, timestamp, value)VALUES ('off', 11111111-aaaa-bbbb-cccc-12345678abcd,         '2021-01-01 02:22:22', 'event 1-2');DELETE FROM latest_events_by_state WHERE state = 'on' AND      device_id = 11111111-aaaa-bbbb-cccc-12345678abcd;-- Event 1-3INSERT INTO latest_events_by_state        (state, device_id, timestamp, value)VALUES ('on', 11111111-aaaa-bbbb-cccc-12345678abcd,         '2021-01-01 03:33:33', 'event 1-3');DELETE FROM latest_events_by_state WHERE state = 'off' AND      device_id = 11111111-aaaa-bbbb-cccc-12345678abcd;-- Event 2-1INSERT INTO latest_events_by_state        (state, device_id, timestamp, value)VALUES ('off', 22222222-aaaa-bbbb-cccc-12345678abcd,         '2021-02-02 01:11:11', 'event 2-1');DELETE FROM latest_events_by_state WHERE state = 'on' AND      device_id = 22222222-aaaa-bbbb-cccc-12345678abcd;-- Event 3-1INSERT INTO latest_events_by_state        (state, device_id, timestamp, value)VALUES ('off', 33333333-aaaa-bbbb-cccc-12345678abcd,         '2021-03-03 01:11:11', 'event 3-1');DELETE FROM latest_events_by_state WHERE state = 'on' AND      device_id = 33333333-aaaa-bbbb-cccc-12345678abcd;

 

查询:

CQL

-- Find all the latest events with state 'on'SELECT state, device_id, timestamp, valueFROM   latest_events_by_stateWHERE  state = 'on'; state | device_id                            | timestamp                       | value-------+--------------------------------------+---------------------------------+-----------    on | 11111111-aaaa-bbbb-cccc-12345678abcd | 2021-01-01 03:33:33.000000+0000 | event 1-3-- Find all the latest events with state 'off'SELECT state, device_id, timestamp, valueFROM   latest_events_by_stateWHERE  state = 'off'; state | device_id                            | timestamp                       | value-------+--------------------------------------+---------------------------------+-----------   off | 22222222-aaaa-bbbb-cccc-12345678abcd | 2021-02-02 01:11:11.000000+0000 | event 2-1   off | 33333333-aaaa-bbbb-cccc-12345678abcd | 2021-03-03 01:11:11.000000+0000 | event 3-1

 

状态分区表解决方案具有以下特点:

  • 适用性:基于状态的查询返回 100K 行/100MB 或更少的数据。
  • 优点:出色的性能。
  • 缺点:需要额外的删除来维护表;可能需要采取措施防止与墓碑有关的问题;数据分布可能会出现偏差。

在大多数情况下,这三个缺点都不应被视为严重障碍。额外的删除相当于额外的写入,Cassandra 可以轻松扩展以处理更多写入。鉴于插入和删除一次又一次地应用于相同的行,墓碑很可能在 MemTable 而不是 SSTables 中得到解决,这可以大大减少墓碑的总数。例如,对于一个给定的物联网设备,即使是频繁的状态更新都命中同一个 MemTable 也只能导致一个墓碑。我们仍然建议监控表指标以排除任何潜在问题。最后但同样重要的是,数据分布取决于数据和应用程序特征。在本文的最后一个解决方案中,我们完全控制了数据分布。

我们可以通过将表主键更改为 PRIMARY KEY((tenant, state), device_id) 轻松支持多个租户。多租户也可能有助于改善数据分布。总体而言,在性能方面,该解决方案应该可以与物化视图解决方案相媲美。

解决方案 4:多个表

第四种解决方案的特点是每个州都有一个单独的表格。对表
latest_on_events_by_device 的每次插入都必须伴随着从表 latest_off_events_by_device 中删除,反之亦然。这是为了确保最新事件始终取消同一设备的任何具有不同状态的过时事件。对表的基于状态的查询可能会变得非常昂贵,因为它们必须扫描表中的所有分区。

架构:

CQL

-- Latest 'on' events by deviceCREATE TABLE latest_on_events_by_device (    device_id  UUID,    timestamp  TIMESTAMP,    value      TEXT,    PRIMARY KEY((device_id)));-- Latest 'off' events by deviceCREATE TABLE latest_off_events_by_device (    device_id  UUID,    timestamp  TIMESTAMP,    value      TEXT,    PRIMARY KEY((device_id)));

 

数据:

CQL

-- Event 1-1INSERT INTO latest_on_events_by_device        (device_id, timestamp, value)VALUES (11111111-aaaa-bbbb-cccc-12345678abcd,         '2021-01-01 01:11:11', 'event 1-1');DELETE FROM latest_off_events_by_device WHERE device_id = 11111111-aaaa-bbbb-cccc-12345678abcd;-- Event 1-2INSERT INTO latest_off_events_by_device        (device_id, timestamp, value)VALUES (11111111-aaaa-bbbb-cccc-12345678abcd,         '2021-01-01 02:22:22', 'event 1-2');DELETE FROM latest_on_events_by_device WHERE device_id = 11111111-aaaa-bbbb-cccc-12345678abcd;-- Event 1-3INSERT INTO latest_on_events_by_device        (device_id, timestamp, value)VALUES (11111111-aaaa-bbbb-cccc-12345678abcd,         '2021-01-01 03:33:33', 'event 1-3');DELETE FROM latest_off_events_by_device WHERE device_id = 11111111-aaaa-bbbb-cccc-12345678abcd;-- Event 2-1INSERT INTO latest_off_events_by_device        (device_id, timestamp, value)VALUES (22222222-aaaa-bbbb-cccc-12345678abcd,         '2021-02-02 01:11:11', 'event 2-1');DELETE FROM latest_on_events_by_device WHERE device_id = 22222222-aaaa-bbbb-cccc-12345678abcd;-- Event 3-1INSERT INTO latest_off_events_by_device        (device_id, timestamp, value)VALUES (33333333-aaaa-bbbb-cccc-12345678abcd,         '2021-03-03 01:11:11', 'event 3-1');DELETE FROM latest_on_events_by_device WHERE device_id = 33333333-aaaa-bbbb-cccc-12345678abcd;

 

查询:

CQL

-- Find all the latest events with state 'on'SELECT device_id, timestamp, valueFROM   latest_on_events_by_device; device_id                            | timestamp                       | value--------------------------------------+---------------------------------+----------- 11111111-aaaa-bbbb-cccc-12345678abcd | 2021-01-01 03:33:33.000000+0000 | event 1-3-- Find all the latest events with state 'off'SELECT device_id, timestamp, valueFROM   latest_off_events_by_device; device_id                            | timestamp                       | value--------------------------------------+---------------------------------+----------- 33333333-aaaa-bbbb-cccc-12345678abcd | 2021-03-03 01:11:11.000000+0000 | event 3-1 22222222-aaaa-bbbb-cccc-12345678abcd | 2021-02-02 01:11:11.000000+0000 | event 2-1

 

多表解决方案具有以下特点:

  • 适用性:基于状态的查询返回 100K 行/100MBs 或更多的数据;基于状态的查询很少执行。
  • 优点:在检索大型结果集时,可以更好地在集群中的节点之间分配查询工作负载。
  • 缺点:实时应用程序的性能可能无法令人满意;需要额外的删除来维护表;可能需要采取措施防止与墓碑有关的问题。

该方案在查询性能上与二级索引方案不相上下。可以通过将表主键更改为 PRIMARY KEY((tenant, device_id)) 或 PRIMARY KEY((tenant), device_id) 来支持多个租户。虽然我们在实践中不推荐这种解决方案,但这种数据模型真正有趣的是它如何为接下来讨论的可定制分区做好准备。

解决方案 5:可自定义的分区

我们的最终解决方案基于为每个状态使用单独的表的想法。但是,这一次,我们使用人工桶对表进行分区。桶值很容易使用来自设备 UUID 标识符的用户定义函数散列来计算。在此示例中,该函数从 UUID 文字中提取前三位,将生成的十六进制数转换为十进制数,并返回十进制数除以 3 的余数。因此,最多可以有三个桶或每个表的分区,值为 0、1 或 2。在此示例中,我们所有的设备标识符都映射到存储桶 0 只是巧合。由于版本 4 UUID是随机生成的,因此对于大量事件,数据应该或多或少均匀分布在三个存储桶中。

与之前的数据模型类似,每次对表
latest_on_events_by_bucket 的插入都必须伴随着从表 latest_off_events_by_bucket 中删除,反之亦然。基于状态的查询的性能取决于分区,并且分区是可定制的。

架构:

CQL

-- Custom hash functionCREATE FUNCTION hash(id UUID) RETURNS NULL ON NULL INPUT RETURNS INT LANGUAGE JAVA AS 'return Integer.parseInt(id.toString().substring(0,3),16) % 3;';-- Latest 'on' events by deviceCREATE TABLE latest_on_events_by_bucket (    bucket     INT,    device_id  UUID,    timestamp  TIMESTAMP,    value      TEXT,    PRIMARY KEY((bucket), device_id));-- Latest 'off' events by deviceCREATE TABLE latest_off_events_by_bucket (    bucket     INT,    device_id  UUID,    timestamp  TIMESTAMP,    value      TEXT,    PRIMARY KEY((bucket), device_id));

 

数据:

CQL

-- Event 1-1INSERT INTO latest_on_events_by_bucket        (bucket, device_id, timestamp, value)VALUES (hash(11111111-aaaa-bbbb-cccc-12345678abcd),         11111111-aaaa-bbbb-cccc-12345678abcd,        '2021-01-01 01:11:11', 'event 1-1');DELETE FROM latest_off_events_by_bucket WHERE bucket = hash(11111111-aaaa-bbbb-cccc-12345678abcd) AND       device_id = 11111111-aaaa-bbbb-cccc-12345678abcd;-- Event 1-2INSERT INTO latest_off_events_by_bucket        (bucket, device_id, timestamp, value)VALUES (hash(11111111-aaaa-bbbb-cccc-12345678abcd),        11111111-aaaa-bbbb-cccc-12345678abcd,         '2021-01-01 02:22:22', 'event 1-2');DELETE FROM latest_on_events_by_bucket WHERE bucket = hash(11111111-aaaa-bbbb-cccc-12345678abcd) AND       device_id = 11111111-aaaa-bbbb-cccc-12345678abcd;-- Event 1-3INSERT INTO latest_on_events_by_bucket        (bucket, device_id, timestamp, value)VALUES (hash(11111111-aaaa-bbbb-cccc-12345678abcd),        11111111-aaaa-bbbb-cccc-12345678abcd,         '2021-01-01 03:33:33', 'event 1-3');DELETE FROM latest_off_events_by_bucket WHERE bucket = hash(11111111-aaaa-bbbb-cccc-12345678abcd) AND       device_id = 11111111-aaaa-bbbb-cccc-12345678abcd;-- Event 2-1INSERT INTO latest_off_events_by_bucket        (bucket, device_id, timestamp, value)VALUES (hash(22222222-aaaa-bbbb-cccc-12345678abcd),        22222222-aaaa-bbbb-cccc-12345678abcd,         '2021-02-02 01:11:11', 'event 2-1');DELETE FROM latest_on_events_by_bucket WHERE bucket = hash(22222222-aaaa-bbbb-cccc-12345678abcd) AND       device_id = 22222222-aaaa-bbbb-cccc-12345678abcd;-- Event 3-1INSERT INTO latest_off_events_by_bucket        (bucket, device_id, timestamp, value)VALUES (hash(33333333-aaaa-bbbb-cccc-12345678abcd),        33333333-aaaa-bbbb-cccc-12345678abcd,         '2021-03-03 01:11:11', 'event 3-1');DELETE FROM latest_on_events_by_bucket WHERE bucket = hash(33333333-aaaa-bbbb-cccc-12345678abcd) AND       device_id = 33333333-aaaa-bbbb-cccc-12345678abcd;

 

查询:

CQL

-- Find all the latest events with state 'on'SELECT bucket, device_id, timestamp, valueFROM   latest_on_events_by_bucketWHERE  bucket IN (0,1,2); bucket | device_id                            | timestamp                       | value--------+--------------------------------------+---------------------------------+-----------      0 | 11111111-aaaa-bbbb-cccc-12345678abcd | 2021-01-01 03:33:33.000000+0000 | event 1-3-- Find all the latest events with state 'off'SELECT bucket, device_id, timestamp, valueFROM   latest_off_events_by_bucketWHERE  bucket IN (0,1,2); bucket | device_id                            | timestamp                       | value--------+--------------------------------------+---------------------------------+-----------      0 | 22222222-aaaa-bbbb-cccc-12345678abcd | 2021-02-02 01:11:11.000000+0000 | event 2-1      0 | 33333333-aaaa-bbbb-cccc-12345678abcd | 2021-03-03 01:11:11.000000+0000 | event 3-1

 

可定制的分区方案具有以下特点:

  • 适用性:定制时可满足不同要求。
  • 优点:灵活性;可以通过自定义分区来优化性能。
  • 缺点:必须提供良好的分区功能;需要额外的删除来维护表;可能需要采取措施防止与墓碑有关的问题。

选择一个好的分区函数是一个很好的问题。虽然这可能会增加一点复杂性,但该解决方案可以完全控制数据分区和查询性能。找到一个好的分区函数将取决于特定的数据和应用程序要求,并且可能需要一些经验和实验。例如,从 1 个分区检索 100 行通常比从 10 个分区检索 100 行快,但从 1 个分区检索 1,000,000 行通常比从 10 个分区检索 1,000,000 行慢。接下来,额外的删除相当于额外的写入,Cassandra 可以轻松扩展以处理更多写入。

鉴于插入和删除一次又一次地应用于相同的行,墓碑很可能在 MemTable 而不是 SSTables 中得到解决,这可以大大减少墓碑的总数。例如,对于一个给定的物联网设备,即使是频繁的状态更新都命中同一个 MemTable 也只能导致一个墓碑。我们仍然建议监控表指标以排除任何潜在问题。最后但同样重要的是,数据分布取决于数据和应用程序特征。在本文的最后一个解决方案中,我们完全控制了数据分布。

这种数据模型提供了极大的灵活性。通过将每个表的主键更改为 PRIMARY KEY((tenant, bucket), device_id) 可以实现多租户。更重要的是,可以更改分区函数以增加或减少分区的数量。检索较小结果集的查询应访问较少数量的分区以获得更好的性能。检索更大结果集的查询应访问更多分区以更好地分配工作负载。可以针对不同的状态和租户使用不同的功能以实现最佳性能。更好的分区应该会带来更好的性能。

结论

我们定义了基于状态管理最新物联网事件的问题,确定了它的挑战,并描述了如何在 Apache Cassandra 中使用五种不同的数据模型来解决它。我们陈述了每个数据模型的适用性、优缺点。我们的最终建议是关注物化视图、状态分区表和可自定义的分区数据模型。选择前两个是因为它们简单易用。当其他选项用尽时,考虑可定制的分区以获得最大的灵活性。最后,开放探索新的可能解决方案,这些解决方案可能会将一些计算推向应用程序或依赖专门的搜索索引和其他技术。

值得一提的是,这篇博文的动机是来自 Discord 上 Apache Cassandra 社区成员的问题。立即加入(Cassandra)戒指团契,与社区成员和专家建立联系!



Tags:物联网   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,不构成投资建议。投资者据此操作,风险自担。如有任何标注错误或版权侵犯请与我们联系,我们将及时更正、删除。
▌相关推荐
2024年五个重要的物联网趋势
今年,我们对物联网每种趋势进行了评级,即其可能的有效性程度。1 到 10 之间的数字是我们对 2024 年这一趋势可能对企业物联网项目产生多大影响的评估。真正重要的事情只有在回...【详细内容】
2024-03-20  Search: 物联网  点击:(11)  评论:(0)  加入收藏
简易百科科技之到底什么是物联网?
物联网,英文名为Internet of Things,简称IOT,是指通过信息传感设备,如射频识别、红外感应器、全球定位系统、激光扫描器等,按照约定的协议,对任何物品进行信息交换和通信,以实现智...【详细内容】
2024-01-30  Search: 物联网  点击:(45)  评论:(0)  加入收藏
一篇文章告诉你什么是物联网的感知层、网络层与应用层的意思?
物联网的概念在很早以前就已经被提出,20世纪末期在美国召开的移动计算和网络国际会议就已经提出了物联网(Internet of Things)这个概念。最先提出这个概念的是MIT Auto-ID中...【详细内容】
2023-12-28  Search: 物联网  点击:(64)  评论:(0)  加入收藏
物联网之能源预测性管理
通过实施能源预测性管理,企业可以更加高效地利用能源资源,降低成本,并减少对环境的影响。同时,这也有助于提高企业的竞争力和可持续发展能力。能源预测性管理是一种基于数据分析...【详细内容】
2023-12-22  Search: 物联网  点击:(43)  评论:(0)  加入收藏
万物互联成大势 物联网发展进入加速期
截至11月末,我国建成承载物联网的5G基站达到328.2万个,物联网连接数超过23亿,同比增幅达27.2%……自2022年8月我国率先迈入“物超人”时代以来,“物联”接棒连接“领...【详细内容】
2023-12-21  Search: 物联网  点击:(43)  评论:(0)  加入收藏
物联网技术将于2024年成熟
人工智能、机器学习(ML)、5G和其他连接服务在内的物联网技术预计将在2024年趋于成熟,不断满足企业持续的劳动力和供应链需求。2024年的宏观经济形势比过去几年更加稳定,为企业...【详细内容】
2023-12-14  Search: 物联网  点击:(49)  评论:(0)  加入收藏
物联网小知识:开关量、数字量、模拟量、离散量和脉冲量它们之间有什么区别?
开关量、数字量、模拟量、离散量和脉冲量是电子测量和控制系统中经常遇到的不同类型的数据。它们在定义、特性和应用方面存在差异。在电子测量和控制系统设计中,根据实际需求...【详细内容】
2023-12-13  Search: 物联网  点击:(71)  评论:(0)  加入收藏
物联网平台之IOT网关
IOT网关即物联网网关,是一种网络设备,在物联网系统中负责连接和控制各种设备,将它们连接到云端、本地服务器或其他设备上。它既可以实现广域互联,也可以实现局域互联,通过协议转...【详细内容】
2023-12-07  Search: 物联网  点击:(57)  评论:(0)  加入收藏
AIOT智能物联网平台架构
AIoT智能物联网平台是结合了人工智能(AI)和物联网(IoT)技术的平台。它旨在通过物联网技术产生和收集来自不同维度的海量数据,并存储在云端和边缘端,然后通过大数据分析和更高形式...【详细内容】
2023-12-06  Search: 物联网  点击:(140)  评论:(0)  加入收藏
物联网的应用与实践
物联网这个话题,说复杂也复杂,说不复杂也不复杂,小场景小应用,大场景大应用,很多人对这个概念既模糊又清晰,基于国内大厂的物联网场景广泛应用。其实以下几个点需要关注。1、网联...【详细内容】
2023-12-06  Search: 物联网  点击:(64)  评论:(0)  加入收藏
▌简易百科推荐
2024年五个重要的物联网趋势
今年,我们对物联网每种趋势进行了评级,即其可能的有效性程度。1 到 10 之间的数字是我们对 2024 年这一趋势可能对企业物联网项目产生多大影响的评估。真正重要的事情只有在回...【详细内容】
2024-03-20  计算机程序吧  微信公众号  Tags:物联网   点击:(11)  评论:(0)  加入收藏
简易百科科技之到底什么是物联网?
物联网,英文名为Internet of Things,简称IOT,是指通过信息传感设备,如射频识别、红外感应器、全球定位系统、激光扫描器等,按照约定的协议,对任何物品进行信息交换和通信,以实现智...【详细内容】
2024-01-30    简易百科  Tags:物联网   点击:(45)  评论:(0)  加入收藏
一篇文章告诉你什么是物联网的感知层、网络层与应用层的意思?
物联网的概念在很早以前就已经被提出,20世纪末期在美国召开的移动计算和网络国际会议就已经提出了物联网(Internet of Things)这个概念。最先提出这个概念的是MIT Auto-ID中...【详细内容】
2023-12-28  物联网IoT技术  微信公众号  Tags:物联网   点击:(64)  评论:(0)  加入收藏
物联网之能源预测性管理
通过实施能源预测性管理,企业可以更加高效地利用能源资源,降低成本,并减少对环境的影响。同时,这也有助于提高企业的竞争力和可持续发展能力。能源预测性管理是一种基于数据分析...【详细内容】
2023-12-22  独数易智  微信公众号  Tags:物联网   点击:(43)  评论:(0)  加入收藏
万物互联成大势 物联网发展进入加速期
截至11月末,我国建成承载物联网的5G基站达到328.2万个,物联网连接数超过23亿,同比增幅达27.2%……自2022年8月我国率先迈入“物超人”时代以来,“物联”接棒连接“领...【详细内容】
2023-12-21    人民邮电报  Tags:物联网   点击:(43)  评论:(0)  加入收藏
物联网技术将于2024年成熟
人工智能、机器学习(ML)、5G和其他连接服务在内的物联网技术预计将在2024年趋于成熟,不断满足企业持续的劳动力和供应链需求。2024年的宏观经济形势比过去几年更加稳定,为企业...【详细内容】
2023-12-14    千家网  Tags:物联网   点击:(49)  评论:(0)  加入收藏
物联网小知识:开关量、数字量、模拟量、离散量和脉冲量它们之间有什么区别?
开关量、数字量、模拟量、离散量和脉冲量是电子测量和控制系统中经常遇到的不同类型的数据。它们在定义、特性和应用方面存在差异。在电子测量和控制系统设计中,根据实际需求...【详细内容】
2023-12-13    物联网星球  Tags:物联网   点击:(71)  评论:(0)  加入收藏
LoRA模型的容量与覆盖范围研究与扩展
LoRA(LongRange)是一种低功耗、远距离通信的无线技术,被广泛应用于物联网(IoT)领域。LoRA技术的独特之处在于其长距离通信能力和低功耗特性,使得它成为连接设备和传感器的理想选择...【详细内容】
2023-12-13  办公小能手    Tags:LoRA   点击:(46)  评论:(0)  加入收藏
物联网平台之IOT网关
IOT网关即物联网网关,是一种网络设备,在物联网系统中负责连接和控制各种设备,将它们连接到云端、本地服务器或其他设备上。它既可以实现广域互联,也可以实现局域互联,通过协议转...【详细内容】
2023-12-07  独数易智  微信公众号  Tags:IOT网关   点击:(57)  评论:(0)  加入收藏
物联网的应用与实践
物联网这个话题,说复杂也复杂,说不复杂也不复杂,小场景小应用,大场景大应用,很多人对这个概念既模糊又清晰,基于国内大厂的物联网场景广泛应用。其实以下几个点需要关注。1、网联...【详细内容】
2023-12-06  独数易智  微信公众号  Tags:物联网   点击:(64)  评论:(0)  加入收藏
站内最新
站内热门
站内头条