在 DynamoDB 中监控设备状态更新 - Amazon DynamoDB
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

在 DynamoDB 中监控设备状态更新

此使用案例讨论使用 DynamoDB 来监控 DynamoDB 中的设备状态更新(或设备状态更改)。

应用场景

在 IoT 使用案例(例如智能工厂)中,许多设备需要由操作员监控,它们会定期将其状态或日志发送到监控系统。当设备出现问题时,该设备的状态会从正常更改为警告。根据设备中异常行为的严重程度和类型,日志级别或状态会有所不同。然后,系统会指派一名操作员检查设备,如果需要,操作员可以将问题上报给主管。

此系统的一些典型访问模式包括:

  • 为设备创建日志条目

  • 获取特定设备状态的所有日志,首先显示最新的日志

  • 获取给定操作员在两个日期之间的所有日志

  • 获取向给定主管上报的所有日志

  • 获取向给定主管上报的带有特定设备状态的所有日志

  • 获取特定日期向给定主管上报的带有特定设备状态的所有日志

实体关系图

这是我们将用于监控设备状态更新的实体关系图(ERD)。

访问模式

这些是我们将考虑用于监控设备状态更新的访问模式。

  1. createLogEntryForSpecificDevice

  2. getLogsForSpecificDevice

  3. getWarningLogsForSpecificDevice

  4. getLogsForOperatorBetweenTwoDates

  5. getEscalatedLogsForSupervisor

  6. getEscalatedLogsWithSpecificStatusForSupervisor

  7. getEscalatedLogsWithSpecificStatusForSupervisorForDate

架构设计的演变

步骤 1:解决访问模式 1(createLogEntryForSpecificDevice)和 2(getLogsForSpecificDevice

设备跟踪系统的扩展单位将是各个设备。在该系统中,deviceID 唯一地标识设备。这使得 deviceID 成为分区键的出色候选者。每个设备都会定期(比如每五分钟左右)向跟踪系统发送信息。这种排序使日期成为逻辑排序标准,因此成为排序键。本案例中的示例数据如下所示:

要获取特定设备的日志条目,我们可以使用分区键 DeviceID="d#12345" 执行查询操作。

步骤 2:解决访问模式 3(getWarningLogsForSpecificDevice

由于 State 是一个非键属性,因此,使用当前架构解决访问模式 3 将需要一个筛选表达式。在 DynamoDB 中,筛选表达式是在使用键条件表达式读取数据之后应用的。例如,如果我们要获取 d#12345 的警告日志,那么分区键为 DeviceID="d#12345" 的查询操作将从上表中读取四个项目,然后筛选出一个具有警告状态的项目。这种方法在规模较大时效率不高。如果所排除的项目的比率较低或查询不频繁执行,则筛选表达式可能是一种排除所查询的项目的好方法。但是,对于从表中检索到许多项目并且大多数项目被筛选掉的情况,我们可以继续改进我们的表设计,使其运行效率更高。

让我们通过使用复合排序键来更改处理这种访问模式的方式。您可以从 DeviceStateLog_3.json 导入示例数据,其中排序键更改为 State#Date。此排序键是属性 State#Date 的组合。在本例中,# 用作分隔符。数据现在如下所示:

要仅获取设备的警告日志,则使用此架构可以使查询更具针对性。查询的键条件使用分区键 DeviceID="d#12345" 和排序键 State#Date begins_with “WARNING”。此查询将只读取具有警告状态的相关三个项目。

步骤 3:解决访问模式 4(getLogsForOperatorBetweenTwoDates

您可以导入 DeviceStateLog_4.json,其中 Operator 属性已添加到带有示例数据的 DeviceStateLog 表中。

由于 Operator 当前不是分区键,因此无法基于 OperatorID 对该表执行直接键/值查找。我们需要在 OperatorID 上创建一个具有全局二级索引的新项目集合。访问模式需要基于日期的查找,因此 Date全局二级索引(GSI)的排序键属性。这就是 GSI 现在的样子:

对于访问模式 4(getLogsForOperatorBetweenTwoDates),您可以在 2020-04-11T05:58:002020-04-24T14:50:00 之间使用分区键 OperatorID=Liz 和排序键 Date 来查询此 GSI。

步骤 4:解决访问模式 5(getEscalatedLogsForSupervisor)、6(getEscalatedLogsWithSpecificStatusForSupervisor)和 7(getEscalatedLogsWithSpecificStatusForSupervisorForDate

我们将使用稀疏索引来解决这些访问模式。

原定设置情况下,全局二级索引是稀疏索引,因此,只有基表中包含索引的主键属性的项目才会实际出现在索引中。这是排除与正在建模的访问模式无关的项目的另一种方法。

您可以导入 DeviceStateLog_6.json,其中 EscalatedTo 属性已添加到带有示例数据的 DeviceStateLog 表中。如前所述,并非所有日志都会上报给主管。

现在可以创建一个新的 GSI,其中 EscalatedTo 是分区键,State#Date 是排序键。请注意,只有同时具有 EscalatedToState#Date 属性的项目才会出现在索引中。

其余的访问模式汇总如下:

下表总结了所有访问模式以及架构设计如何解决访问模式:

访问模式 基表/GSI/LSI 操作 分区键值 排序键值 其他条件/筛选条件
createLogEntryForSpecificDevice 基表 PutItem DeviceID=deviceId State#Date=state#date
getLogsForSpecificDevice 基表 Query DeviceID=deviceId State#Date begins_with "state1#" ScanIndexForward = False
getWarningLogsForSpecificDevice 基表 Query DeviceID=deviceId State#Date begins_with "WARNING"
getLogsForOperatorBetweenTwoDates GSI-1 查询 Operator=operatorName date1 和 date2 之间的日期
getEscalatedLogsForSupervisor GSI-2 查询 EscalatedTo=supervisorName
getEscalatedLogsWithSpecificStatusForSupervisor GSI-2 查询 EscalatedTo=supervisorName State#Date begins_with "state1#"
getEscalatedLogsWithSpecificStatusForSupervisorForDate GSI-2 查询 EscalatedTo=supervisorName State#Date begins_with "state1#date1"

最终架构

这是最终的架构设计。要以 JSON 文件格式下载此架构设计,请参阅 GitHub 上的 DynamoDB 示例

基表

GSI-1

GSI-2

在此架构设计中使用 NoSQL Workbench

若要进一步探索和编辑新项目,您可以将此最终架构导入到 NoSQL Workbench,这是一款为 DynamoDB 提供数据建模、数据可视化和查询开发功能的可视化工具。请按照以下步骤开始使用:

  1. 下载 NoSQL Workbench。有关更多信息,请参阅 下载 NoSQL Workbench for DynamoDB

  2. 下载上面列出的 JSON 架构文件,该文件已经采用 NoSQL Workbench 模型格式。

  3. 将 JSON 架构文件导入到 NoSQL Workbench。有关更多信息,请参阅 导入现有数据模型

  4. 导入到 NOSQL Workbench 后,您便可编辑数据模型。有关更多信息,请参阅 编辑现有数据模型

  5. 要将数据模型可视化、添加样本数据或从 CSV 文件导入样本数据,请使用 NoSQL Workbench 的数据可视化工具功能。