本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。
InfluxDB
当您想要查询设备遥测以了解运营趋势或实时监控时间序列数据时,请选择此操作。您可以使用客户端或服务器端批处理将多个点合并到一个写入请求中。 AWS IoT Core 将每条消息转换为 InfluxDB 线路协议并将其写入指定的数据库和表。有关格式的更多信息,请参阅文档中的 InfluxDB 线路协议
先决条件
此规则操作具有以下先决条件:
-
InfluxDB 操作目标 — 创建一个 InfluxDB 操作目标,为你的 InfluxDB 实例指定终端节点、版本和凭据。 AWS IoT Core 在发送流量之前验证端点所有权。请参阅InfluxDB 操作目标。
-
一个 IAM 角色, AWS IoT 可以假设写入您的 InfluxDB 数据库,并对存储您的 InfluxDB 凭证的密钥执行
GetSecretValue操作。有关更多信息,请参阅 授予 AWS IoT 控制它需要的访问权限。 -
存储在 InfluxDB 凭证 AWS Secrets Manager — 对于 InfluxDB V3,InfluxDB 的 Amazon Timestream 在你创建 InfluxDB 集群时会自动配置 Secrets Manager 密钥。该密钥包含集群凭证。对于 InfluxDB V2,从你的 InfluxDB 实例生成 All Access 或自定义 API 令牌。将令牌值作为纯文本密钥存储在中。 AWS Secrets Manager有关创建令牌的更多信息,请参阅 InfluxData 文档中的创建令牌
。在运行时,规则操作会调用 secretsmanager:GetSecretValue以检索这些凭据,然后再对您的 InfluxDB 端点进行身份验证。 -
消息有效载荷@@ 中的时间戳 — 消息负载中的每个对象都必须包含一个名为
timestamp(区分大小写)的密钥,其值为整数 Unix 纪元。也可以在物联网规则定义中设置时间戳单位。 AWS IoT Core 不为 InfluxDB 操作生成时间戳,除非将 InfluxDB 用作错误操作。注意
time不能使用ts或之类的别名来代替timestamp。 -
HTTPS 连接 — 必须可以通过 HTTPS 访问您的 InfluxDB 实例。 AWS IoT Core 支持的出站端口有:443、8443、8086(InfluxDB V2 的默认端口)和 8181(InfluxDB V3 的默认端口)。
-
JSON-format 有效负载 — InfluxDB 操作仅处理 JSON 有效负载。如果您的设备发布二进制或 Protobuf 数据,请在操作运行之前使用规则 SQL 中的decode()函数转换为 JSON。
InfluxDB 操作目标
在使用 InfluxDB 规则操作之前,必须先创建一个 InfluxDB 操作目标。目标定义您的InfluxDB实例的连接参数。 AWS IoT Core 然后验证端点所有权。
创建目的地
使用 CreateTopicRuleDestination API 创建 InfluxDB 目的地:
{ "destinationConfiguration": { "influxDBConfiguration": { "endpoint": "https://my-instance.timestream-influxdb.us-west-2.amazonaws.com:8086", "influxDBVersion": "V2", "secretId": "arn:aws:secretsmanager:us-west-2:111122223333:secret:my-influxdb-credentials-AbCdEf" } } }
目的地参数
| 参数 | 类型 | 必需 | 描述 |
|---|---|---|---|
endpoint |
字符串 | 是 | InfluxDB 实例的 HTTPS 端点 URL。不支持 HTTP。支持的端口:443、8086、8181、8443。 |
influxDBVersion |
字符串 | 是 | InfluxDB 版本。有效值:V2、V3。 |
secretId |
字符串 | 是 | 包含您的 InfluxDB 令牌的 AWS Secrets Manager 密钥的名称或 ARN。 |
secretType |
字符串 | 否 | 密钥值的类型。有效值:SecretString、SecretBinary。 |
secretKey |
字符串 | 否 | 包含身份验证令牌的机密 JSON 中的密钥。仅当密钥是具有多个密钥的 JSON 对象时才需要。 |
端点所有权验证
创建InfluxDB操作目标时,使用您提供的凭据对InfluxDB API进行身份验证,从而 AWS IoT Core 验证端点所有权:
-
InfluxDB V2: AWS IoT Core 调用端点。
/api/v2/me -
InfluxDB V3: AWS IoT Core 调用列表数据库端点 ()
GET /api/v3/configure/database。
成功响应 (2xx) 会将目标状态设置为。ENABLED失败时, AWS IoT Core 将状态设置为ERROR。要重试验证,请UpdateTopicRuleDestination将状态设置为。IN_PROGRESS
InfluxDB 术语映射
以下术语在 InfluxDB V2 和 V3 之间有所不同。
| AWS IoT Core 参数 | InfluxDB V2 术语 | InfluxDB V3 术语 |
|---|---|---|
databaseName |
存储桶 | 数据库 |
tableName |
测量值 | 表 |
注意
如果您要从 Amazon Timestream 规则操作迁移,则dimensions参数会映射到 InfluxDB 操作中的标签,查询结果属性会映射到字段。
参数
使用 InfluxDB 操作创建 AWS IoT 规则时,必须指定以下信息:
destinationArn-
InfluxDB 操作目标的 ARN。请参阅InfluxDB 操作目标。支持替换模板:否
roleArn-
授予访问 Secrets Manager 密钥 AWS IoT 权限的 IAM 角色的 ARN。请参阅先决条件。支持替换模板:否
databaseName-
要写入记录的 InfluxDB 数据库(在 InfluxDB v2 中称为存储桶,在 InfluxDB v3 中称为数据库)的名称。支持替换模板:否。 要将数据路由到不同的数据库,请为每个数据库创建单独的规则操作。
tableName-
要写入记录的表(在 InfluxDB v2 中称为度量,在 InfluxDB v3 中称为表)的名称。支持替换模板:是。
organization-
InfluxDB 组织名称。对于 InfluxDB v2 来说是必需的。如果您在 InfluxDB v3 中包含此参数,则该参数将被忽略。支持替换模板:否。
tags-
每个点的元数据,指定为地图。每个映射键都是一个标签名称,每个地图值都是相应的标签值。为标签编制索引是为了提高查询性能。
-
在 InfluxDB V3 中,每个标签名称在表中必须是唯一的,并且不能重复字段名。
-
标签值支持消息范围和按元素替换模板。
-
timestampUnit-
有效载荷中时间戳值的精度。有效值:
s(秒)|ms(毫秒)|(微秒)|us(纳秒)。ns默认值:ms。支持替换模板:否。 batchConfig-
(可选) Server-side 批处理配置。有关更多信息,请参阅 批处理。
-
maxBatchSize— 每批中的最大分数。有效范围:1—500。 -
maxBatchOpenMs— 保持批次打开状态的最长时间(以毫秒为单位)。有效范围:5—1,000。 -
maxBatchSizeBytes— 刷新前的最大总大小(以字节为单位)。有效范围:100—131,072。 -
batchAcrossTopics:布尔值。何时true,批次会包含来自不同主题的消息中的要点。默认值:false。
-
批处理
InfluxDB 操作支持两种批处理模式。
Client-side 批处理
您的物联网设备将时间序列数据批处理为 JSON 数组,并将其作为单个 MQTT 消息发布。在客户端批处理中,每个数组元素在单个写入请求中成为一个行协议点。您不需要其他配置。
Server-side 批处理
在将单个消息写入InfluxDB之前,使用服务器端批处理对它们进行分组。使用参数配置服务器端批处理。batchConfig当首先达到任何配置的限制(maxBatchSize、或maxBatchSizeBytes)时maxBatchOpenMs,将刷新批次。
注意
可以同时配置服务器端批处理和客户端批处理(JSON 数组有效负载)。
InfluxDB 操作是根据出站有效载荷大小计量的,以 5 KiB 为增量。 Line-protocol 转换失败也会被计量。
Per-element 阵列有效载荷的模板
当您的物联网设备以 JSON 数组的形式发送批量时间序列数据时,您可以使用 “每元素替换模板” 来解析每个单独数组元素中的值。这会将每个数据点路由到不同的表或应用特定于元素的标签。有关更多信息,请参阅 Per-element 替换中的数组有效负载 AWS IoT 规则。
二的语法 替换模板
-
${expression}— 根据传入的设备消息在消息范围内进行解析。对每条消息计算一次;数组中的每个点都使用相同的值。 -
@{expression}— 在元素作用域针对规则的 SQL SELECT 语句生成的有效载荷的单个元素进行解析。 Re-evaluated 对于每个数组元素,因此每个点可以获得不同的值。有关更多信息,请参阅@{expression}参考。
使用 @{...} in tableName 和 tag 值分别解析每个数组元素的表达式。
示例
给定以下设备有效负载(JSON 数组):
[ {"measurement_type": "temperature", "room": "kitchen", "timestamp": 1700000000000, "value": 23.5}, {"measurement_type": "humidity", "room": "bedroom", "timestamp": 1700000001000, "value": 60.1} ]
以及以下动作配置:
{ "influxDB": { "destinationArn": "arn:aws:iot:us-west-2:111122223333:ruledestination/influxdb/abc123", "roleArn": "arn:aws:iam::111122223333:role/iot-influxdb-role", "databaseName": "sensor_data", "tableName": "@{measurement_type}", "tags": { "room": "@{room}" }, "timestampUnit": "ms" } }
生成的线路协议输出包含两个点:
temperature,room=kitchen value=23.5 1700000000000 humidity,room=bedroom value=60.1 1700000001000
注意
引用的字段@{...}已从线路协议字段集中移除,因此它不会同时显示为字段。在此示例中,measurement_type变为表名并room成为标签,因此两者都不会出现在字段集中,value这是唯一的字段。
限制
-
@{...}仅在 InfluxDB 操作配置(tableName和标签值)中受支持。 -
不能
@{...}在规则 SQL(SELECT/WHERE子句)、错误操作定义或任何其他规则操作中使用。 -
内部仅支持字段引用
@{...}。不支持函数。 -
每个值最多支持一个
@{...}标记。单个值中的多个标记会产生 API 异常。 -
不能将
${...}和混合到相同的值@{...}中。混合会产生 API 异常。 -
单个 JSON 对象被视为一个元素数组。
InfluxDB 记录内容
对于 post-SQL 查询结果中的每条记录,生成的 InfluxDB 行协议点包含以下组件:
| 组件 | 源 |
|---|---|
| 表 | tableName参数值 |
| 标签 | 参数中的键值对 tags |
| 字段 | 其余负载属性未用作标签、表名或时间戳 |
| Timestamp | 从有效载荷中提取的timestamp密钥 |
数据类型转换
AWS IoT Core 将 JSON 值转换为 InfluxDB 线路协议类型,如下所示:
| JSON 类型 | 线路协议类型 | 示例 |
|---|---|---|
| 整数 (−2³ 到 2³−1) | 有符号整数(i后缀) |
42 → 42i |
| 整数 (2³ 到 2−1) | 无符号整数(u后缀) |
9223372036854775808 →
9223372036854775808u |
| 外面的整数 (−2³ 到 2−1) | 已拒绝(已触发错误操作) | — |
| 浮点数/十进制 | IEEE-754 64 位浮点数 | 23.5 → 23.5 |
| 布尔值 | t 或者 f |
true → t |
| 字符串 | 引用字符串 | "active" →
"active" |
| Null | 省略(未写入) | — |
| 对象或数组 | 压缩的 JSON 字符串(去掉了空格) | {"a":1} →
"{\"a\":1}" |
命名限制
-
字段键和标签键不能为空或以下划线 (
_) 开头。 -
在 InfluxDB V3 中,表名和标签密钥必须以字母或数字开头。
-
字段键、标签键和标签值中的逗号、等号和空格会自动转义。
-
测量:逗号和空格会自动转义。
-
标签在序列化之前按键的字母顺序排序,以提高摄取性能。
-
输出中省略了空标签值。
保留的密钥
线路协议转换期间,以下有效载荷键会从字段设置中删除:
-
timestamp— 用作点时间戳。 -
tableName(通过${...}或@{...})引用的密钥-用作表名。 -
由标签值引用的密钥(通过
${...}或@{...})-用作标签值。
错误操作
如果 InfluxDB 操作失败,则会触发配置的错误操作。
使用 InfluxDB 作为错误操作
您可以将 InfluxDB 操作配置为任何规则的错误操作。整个有效载荷被写入单个tableName记录中。 Message-scope 错误操作的tableName和中支持替换模板 (${...}) tags。
错误操作输出
触发错误操作时,输出负载包含:ruleName、topic、cloudwatchTraceId、clientIdsourceIp、base64OriginalPayload(Base64-encoded 原始消息),以及每个条目都有failedAction、和failedResource、的failures数组errorMessage。
在服务器端批处理中,有效负载使用payloadsWithMetadata,每条不同的入站 MQTT 消息都有一个条目。每个失败的affectedIds值都是指这些消息条目的id值;它们不是点索引。客户端 JSON 数组是一条入站消息,尽管它会生成多个 InfluxDB 点。有关完整的有效载荷格式,请参阅批处理的错误操作。
| 失败场景 | 说明 |
|---|---|
| 目标已禁用或出错 | InfluxDB 操作目标未启用。验证端点所有权验证成功。 |
| 目标 ARN 无效 | 指定的目的地不存在。 |
| 角色无效 ARN | IAM 角色不存在或缺少权限。 |
| 秘密检索失败 | 密钥或配置的密钥secretKey不存在,或者规则操作角色无法检索或解密密密钥。 |
| 缺少时间戳 | 有效载荷不包含密timestamp钥。有效载荷中的每个对象都必须包含一个带整数 Unix 纪元值的timestamp字段。 |
| 时间戳值无效 | 时间戳值不是整数(例如,字符串、浮点数或 ISO-8601 日期)。该值必须是整数 Unix 时代,单位由指定。timestampUnit |
| 有效载荷无效(无字段) | 移除保留密钥后,有效负载不包含线路协议的有效字段。 |
| 字段密钥无效 | 字段键为空或开头为_。 |
| 客户端批次包含无效积分 | JSON 数组中的一个或多个元素未通过行协议验证。 |
| 标签 + 字段超过列限制 | 标签和字段键的组合超过了最大列数 (250)。 |
| 连接失败 | AWS IoT Core 无法连接到 InfluxDB 端点。 |
| 身份验证失败 | InfluxDB 令牌无效或已过期。更新中的密钥 AWS Secrets Manager。 |
| 未找到资源 | InfluxDB 中不存在指定的数据库、表或组织。 |
| 字段类型冲突 | 一个或多个字段与现有架构冲突。整个批量写入失败。 |
| InfluxDB 服务器错误 | InfluxDB 中发生了内部错误。 |
| InfluxDB 服务不可用 | InfluxDB 暂时不可用。规则引擎使用指数退避重试。 |
重要
批处理中任何一点的字段类型冲突都会导致整个批处理写入失败。InfluxDB 不会部分提交积分——要么所有点都成功,要么整个写入都被拒绝。
使用指数退避重试可重试错误 (503)。对于 HTTP 401 响应,从中 AWS IoT Core 重新加载令牌 AWS Secrets Manager 并重试请求一次。 Non-retryable 错误 (404、422) 会立即触发错误操作。有关重试限制,请参阅AWS IoT Core 服务配额。
示例
InfluxDB 规则操作
{ "topicRulePayload": { "sql": "SELECT * FROM 'devices/+/telemetry'", "ruleDisabled": false, "awsIotSqlVersion": "2016-03-23", "actions": [ { "influxDB": { "destinationArn": "arn:aws:iot:us-west-2:111122223333:ruledestination/influxdb/a1b2c3d4", "roleArn": "arn:aws:iam::111122223333:role/iot-influxdb-role", "organization": "my-org", "databaseName": "sensor_data", "tableName": "device_metrics", "tags": { "device_id": "${clientid()}", "location": "building-a" }, "timestampUnit": "ms" } } ] } }
有效载荷示例:
{ "timestamp": 1700000000000, "temperature": 23.5, "humidity": 60.1, "pressure": 1013.25, "battery_level": 87 }
生成的线路协议:
device_metrics,device_id=myDevice123,location=building-a temperature=23.5,humidity=60.1,pressure=1013.25,battery_level=87i 1700000000000
输出中的字段顺序可能有所不同,字段不按字母顺序排序。
Client-batched 带有每个元素模板的数组有效负载
{ "influxDB": { "destinationArn": "arn:aws:iot:us-west-2:111122223333:ruledestination/influxdb/a1b2c3d4", "roleArn": "arn:aws:iam::111122223333:role/iot-influxdb-role", "organization": "my-org", "databaseName": "sensor_data", "tableName": "@{measurement_type}", "tags": { "sensor_id": "@{sensor_id}", "location": "${topic(2)}" }, "timestampUnit": "ns" } }
示例有效负载(发布到devices/floor3/telemetry):
[ {"measurement_type": "temperature", "sensor_id": "sensor-42", "timestamp": 1700000000000000000, "value": 23.5}, {"measurement_type": "humidity", "sensor_id": "sensor-42", "timestamp": 1700000001000000000, "value": 60.1}, {"measurement_type": "pressure", "sensor_id": "sensor-43", "timestamp": 1700000002000000000, "value": 1013.25} ]
生成的线路协议:
temperature,location=floor3,sensor_id=sensor-42 value=23.5 1700000000000000000 humidity,location=floor3,sensor_id=sensor-42 value=60.1 1700000001000000000 pressure,location=floor3,sensor_id=sensor-43 value=1013.25 1700000002000000000
Server-side 使用 InfluxDB 进行批处理
要将服务器端批处理添加到任何 InfluxDB 操作中,请在操作配置batchConfig中包括:
"batchConfig": { "maxBatchSize": 50, "maxBatchOpenMs": 1000, "maxBatchSizeBytes": 65536, "batchAcrossTopics": false }
规则操作角色的 IAM 策略
信任政策:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": {"Service": "iot.amazonaws.com"}, "Action": "sts:AssumeRole" } ] }
权限策略:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "secretsmanager:GetSecretValue", "Resource": "arn:aws:secretsmanager:us-west-2:111122223333:secret:my-influxdb-secret-a1b2c3" } ] }
组合客户端和服务器端批处理(点重新排序)
同时启用客户端批处理(JSON 数组有效负载)和服务器端批处理(batchConfig)时,请注意,服务器端批处理可能会对客户端批处理负载中的积分进行重新排序。规则引擎将来自多个传入消息的积分累积到单个服务器端批处理中。由于消息是从不同的设备或主题异步到达的,因此在最终写入时,在原始客户端负载中排序的点可能会与其他消息中的点交错排列。
操作配置:
{ "influxDB": { "destinationArn": "arn:aws:iot:us-west-2:111122223333:ruledestination/influxdb/abc123", "roleArn": "arn:aws:iam::111122223333:role/iot-influxdb-role", "databaseName": "sensor_data", "tableName": "@{measurement_type}", "tags": { "device_id": "${topic(2)}", "floor": "@{floor}" }, "timestampUnit": "ms", "batchConfig": { "maxBatchSize": 100, "maxBatchOpenMs": 500, "maxBatchSizeBytes": 65536, "batchAcrossTopics": true } } }
设备 A 发布devices/deviceA/telemetry到时间 T:
[ {"measurement_type": "temperature", "floor": "1", "timestamp": 1700000000000, "value": 22.1}, {"measurement_type": "temperature", "floor": "2", "timestamp": 1700000000100, "value": 23.4}, {"measurement_type": "humidity", "floor": "1", "timestamp": 1700000000200, "value": 55.0} ]
设备 B 发布到时间 devices/deviceB/telemetry t+10ms:
[ {"measurement_type": "temperature", "floor": "3", "timestamp": 1700000000050, "value": 21.8}, {"measurement_type": "humidity", "floor": "3", "timestamp": 1700000000150, "value": 62.3} ]
两条消息都在 500 毫秒的批处理窗口 (maxBatchOpenMs) 内到达,因此规则引擎将所有五个点合并为一个服务器端批处理。
生成的线路协议(服务器端批量写入):
temperature,device_id=deviceB,floor=3 value=21.8 1700000000050 temperature,device_id=deviceA,floor=1 value=22.1 1700000000000 temperature,device_id=deviceA,floor=2 value=23.4 1700000000100 humidity,device_id=deviceB,floor=3 value=62.3 1700000000150 humidity,device_id=deviceA,floor=1 value=55.0 1700000000200
请注意,这些点不再按照它们在每个客户端有效载荷中出现的顺序排列。来自设备 A 的三个点(时间戳 170000000000000、1700000000100、1700000000200)与设备 B 中的两个点(时间戳 1700000000050、1700000000150)交错排列。服务器端批处理不能保证每条消息中的原始顺序。InfluxDB 使用时间戳字段将每个点放在时间轴上,因此重新排序不会影响查询的正确性。但是,如果您的应用程序依赖写入顺序语义(例如,在同一毫秒内处理字段类型冲突或最后一次写入获胜的重复数据删除),请注意有效的写入顺序可能与发布顺序不同。