排除写入数据的问题
学习如何避免意外结果以及在写入 InfluxDB 时从错误中恢复。
处理 write 和 delete 响应
在 InfluxDB Cloud 中,写入和删除是异步的,并且最终一致。 一旦 InfluxDB 验证了您的请求并 排队 写入或删除,它会发送一个 成功 响应(HTTP 204 状态码)作为确认。 为确保 InfluxDB 按您请求的顺序处理写入和删除,请在发送下一个请求之前等待确认。 由于写入是异步的,请记住以下几点:
- 当您收到 成功 (HTTP
204状态码) 时,数据可能尚不可查询。 - 在你收到成功(HTTP
204状态码)后,InfluxDB 可能仍然拒绝数据点。
查看HTTP状态码
InfluxDB 使用传统的 HTTP 状态码来指示请求的成功或失败。 写请求返回以下状态码:
| HTTP 响应代码 | 消息 | 描述 |
|---|---|---|
204 "Success" | 如果 InfluxDB 验证了请求的数据格式并将数据排队写入存储桶 | |
400 "错误的请求" | message 包含第一个格式错误的行 | 如果数据格式错误 |
401 "未授权" | 如果 Authorization: Token header 缺失或格式不正确,或者如果 API token 没有 权限 写入到存储桶 | |
404 "Not found" | 请求的 资源类型,例如“组织”,和 资源名称 | 如果请求的资源(例如组织或存储桶)未被找到 |
413 “请求过大” | 无法读取数据:批处理中的点太大 | 如果一个 写入 请求超过了最大 全局限制 |
429 “请求过多” | Retry-After 头部: xxx (在重试请求之前需要等待的秒数) | 如果 读取 或 写入 请求超出您计划的 可调整服务配额,或如果 删除 请求超出最大 全局限制 |
500 "内部服务器错误" | 错误的默认状态 | |
503 “服务不可用“ | 系列基数超过您的计划的服务配额 | 如果 系列基数 超过您的计划的 可调整服务配额 |
响应体的 message 属性可能包含有关错误的更多细节。 如果您的部分数据未写入桶中,请查看如何 排查被拒绝的点。
排查部分写入问题
由于写入是异步的,即使 InfluxDB 对有效请求返回了 HTTP 2xx 状态码,它们也可能部分或完全失败。
例如,当 InfluxDB 写入所有符合桶模式的点时,可能会发生部分写入,但拒绝那些字段中数据类型错误的点。
要检查异步失败的写入,请创建一个 任务 来 检查 _monitoring 桶中的被拒绝点。
要解决部分写入和被拒绝的点,请参阅 排除故障。
故障排除
- 在响应体中检查
message属性以获取有关错误的详细信息–例如,partial write error表示 rejected points。 - 检查您组织中的 rejected points 在
_monitoring桶中。 - 验证所有行包含有效的语法(行协议 或 CSV)。查看如何 查找解析错误。
- 验证数据类型是否与系列或桶模式匹配。查看如何解决显式模式拒绝。
- 验证时间戳与精度参数匹配。
- 通过 优化写入 来最小化负载大小和网络错误。
排查被拒绝的要点
即使HTTP请求返回“成功”,InfluxDB可能仍会拒绝数据点。 InfluxDB将拒绝的数据点及相关错误记录到您组织的_monitoring存储桶中。
审核被拒绝的点
要获取被拒绝点的日志,请查询您组织的 rejected_points 测量值 在您的 _monitoring 桶中。为了更快地定位 rejected_points,请牢记以下几点:
- 如果您的行协议批次包含多个 字段 的单行,InfluxDB 会为每个被拒绝的点(每个唯一字段)记录一条日志。
- 每个条目包含一个
reason标签,该标签描述了为什么该点被拒绝。 - 对于 数据类型冲突和模式拒绝,其
count字段值为1。 - 关于 解析错误 的条目包含一个
error字段(并且不包含count字段)。
被拒绝的点 schema
| 名称 | 值 |
|---|---|
_measurement | rejected_points |
_field | count 或 error |
_value | 1 或 错误详情 |
bucket | 拒绝该数据点的桶的ID |
measurement | 点的测量名称 |
field | 导致拒绝的字段名称 |
reason | 问题的简要描述。有关具体原因,请参见数据类型冲突和schema拒绝 |
gotType | 接收到的 字段 类型: Boolean, Float, Integer, String, 或 UnsignedInteger |
wantType | 期望的 字段 类型: Boolean, Float, Integer, String 或 UnsignedInteger |
| 记录拒绝点的时间 |
查找解析错误
如果 InfluxDB 无法解析一行(例如,由于语法问题),响应 message 可能不会提供详细信息。要找到解析错误的详细信息,请查询包含 error 字段的 rejected_points 条目。
from(bucket: "_monitoring")
|> range(start: -1h)
|> filter(fn: (r) => r._measurement == "rejected_points")
|> filter(fn: (r) => r._field == "error")
查找数据类型冲突和架构拒绝
要查找 rejected_points 由 数据类型冲突 或 模式拒绝 引起的,请查询 count 字段。
from(bucket: "_monitoring")
|> range(start: -1h)
|> filter(fn: (r) => r._measurement == "rejected_points")
|> filter(fn: (r) => r._field == "count")
解决数据类型冲突
当您写入具有implicit模式类型的桶时,InfluxDB会将新点与具有相同的series进行比较。
如果一个点的字段与该系列的数据类型不同,InfluxDB会拒绝该点并记录rejected_points条目。
rejected_points条目包含以下原因之一:
| 原因 | 意思 |
|---|---|
type conflict in batch write | 该批处理包含另一个具有相同系列的点,但是其中一个字段具有不同的值类型。 |
type conflict with existing data | 该桶包含另一个具有相同系列的点,但其中一个字段具有不同的值类型。 |
解决显式模式拒绝
如果您写入一个带有 显式模式的桶, 数据必须符合该模式。否则,InfluxDB 将拒绝该数据。
执行以下操作以解释显式架构拒绝:
检测测量不匹配
如果测量与名称不匹配桶模式,则InfluxDB会拒绝一个数据点。rejected_points条目包含以下reason标签值:
| 原因 | 意思 |
|---|---|
measurement not allowed by schema | 该 bucket 被配置为使用显式模式,而没有一个模式与该点的 measurement 匹配。 |
考虑以下 line protocol 数据。
airSensors,sensorId=TLM0201 temperature=73.97,humidity=35.23,co=0.48 1637014074
该行具有一个 airSensors 测量和三个字段 (temperature, humidity, 和 co)。 如果您尝试将此数据写入具有 explicit schema type 且没有 airSensors schema 的桶中,/api/v2/write InfluxDB API 将返回错误和以下数据:
{
"code": "invalid",
"message": "3 out of 3 points rejected (check rejected_points in your _monitoring bucket for further information)"
}
InfluxDB 记录了三个 rejected_points 条目,分别对应每个字段。
| 测量 | 字段 | 值 | 字段 | 测量 | 原因 |
|---|---|---|---|---|---|
| 拒绝的点 | 计数 | 1 | 湿度 | 空气传感器 | 不允许的测量,违反了架构 |
| 拒绝的点 | 计数 | 1 | co | 空气传感器 | 测量不被模式允许 |
| 被拒绝的点 | 计数 | 1 | 温度 | 空气传感器 | 模式不允许的测量 |
检测字段类型不匹配
如果测量与桶模式的名称匹配,并且字段数据类型不匹配,InfluxDB会拒绝一个点。
rejected_points条目包含以下原因:
| 原因 | 意思 |
|---|---|
field type mismatch with schema | 该点的度量与配置的模式相同,但它们有不同的字段值类型。 |
考虑一个具有以下 airSensors 显式桶模式 的桶:
{
"name": "airSensors",
"columns": [
{
"name": "time",
"type": "timestamp"
},
{
"name": "sensorId",
"type": "tag"
},
{
"name": "temperature",
"type": "field",
"dataType": "float"
},
{
"name": "humidity",
"type": "field",
"dataType": "float"
},
{
"name": "co",
"type": "field",
"dataType": "float"
}
]
}
以下的 行协议 数据包含一个 airSensors 测量,一个 sensorId 标签,以及三个字段 (temperature, humidity, 和 co)。
airSensors,sensorId=L1 temperature=90.5,humidity=70.0,co=0.2 1637014074
airSensors,sensorId=L1 temperature="90.5",humidity=70.0,co=0.2 1637014074
在上面的示例数据中,第二个点的 temperature 字段值具有 字符串 数据类型。因为 airSensors 架构要求 temperature 具有 浮点数 数据类型,InfluxDB 返回 400 错误和描述结果的消息:
{
"code": "invalid",
"message": "partial write error (5 accepted): 1 out of 6 points rejected (check rejected_points in your _monitoring bucket for further information)"
}
InfluxDB 记录以下 rejected_points 条目到 _monitoring 桶:
| _测量 | _字段 | _值 | 桶 | 字段 | 获得类型 | 测量 | 原因 | 想要类型 |
|---|---|---|---|---|---|---|---|---|
| rejected_points | 计数 | 1 | a7d5558b880a93da | 温度 | 字符串 | 空气传感器 | 字段类型与模式不匹配 | 浮点数 |