理解和排查 Flight 响应
了解如何处理响应以及当使用 Flight+gRPC 和 Arrow Flight 客户端查询 InfluxDB 集群时遇到的错误。
InfluxDB Flight 响应
InfluxDB 集群提供了 InfluxDB 特定的 Arrow Flight 远程过程调用 (RPC) 和 Flight SQL 服务,该服务使用 gRPC,一个高性能 RPC 框架,以 Arrow 格式传输数据。Flight 定义了一组 RPC 方法,服务器和客户端可以使用这些方法交换信息。Flight SQL 使用 Flight RPC 并定义了额外的查询数据库元数据、执行查询和操作预编译语句的方法。要了解更多关于 Flight SQL 的信息,请参阅 Apache Arrow Flight SQL:加速数据库访问。
要查询数据或检索存储在 InfluxDB 集群中的数据的信息,请使用 Flight 客户端向 InfluxDB Flight RPC 或 Flight SQL 服务方法发送调用。例如,如果您使用 influxdb3-python
Python 客户端库 并调用 InfluxDBClient3.query()
方法,客户端随后调用 pyarrow.flight.FlightClient.do_get()
方法,并将包含您的凭据和查询的 Flight 凭证传递给 InfluxDB 的 Flight DoGet(FlightCallOptions, Ticket)
方法。
InfluxDB 会响应以下之一
流
InfluxDB 提供了飞行 RPC 方法,并实现了服务器端流式传输,以便客户端检索和下载数据。在 gRPC 服务器端流式传输场景中,客户端向服务器发送 RPC 请求。因为服务器可以返回多个响应的 流 给客户端,客户端请求包含一个标识符,客户端和服务器使用该标识符来跟踪请求和相关响应。随着服务器发送响应,它们与客户端侧的相应流相关联。
如 InfluxDB 之类的箭头飞行服务以 箭头 IPC 流格式 发送流,该格式定义了流的结构和流中的每个响应或 消息。
如 pyarrow.flight
和 Go Arrow 飞行包之类的飞行客户端库实现了箭头接口,用于从流中检索数据、模式和元数据。
在 InfluxDB 集群成功处理查询后,它发送包含以下内容的流
模式
InfluxDB 飞行响应流包含一个 飞行模式,该模式描述了数据集中的列的数据类型和 InfluxDB 数据元素类型(时间戳、标签或字段)。同一流中的所有数据块或记录批次具有相同的模式。数据转换工具可以在将 Arrow 数据转换为其他格式并将其转换回 Arrow 时使用该模式。
示例
给定以下查询
SELECT co, delete, hum, room, temp, time
FROM home
WHERE time >= now() - INTERVAL '90 days'
ORDER BY time
Python 客户端库输出以下模式表示
Schema:
co: int64
-- field metadata --
iox::column::type: 'iox::column_type::field::integer'
delete: string
-- field metadata --
iox::column::type: 'iox::column_type::tag'
hum: double
-- field metadata --
iox::column::type: 'iox::column_type::field::float'
room: string
-- field metadata --
iox::column::type: 'iox::column_type::tag'
temp: double
-- field metadata --
iox::column::type: 'iox::column_type::field::float'
time: timestamp[ns] not null
-- field metadata --
iox::column::type: 'iox::column_type::timestamp'
使用 PyArrow,您可以通过 FlightStreamReader.schema
属性访问模式。请参阅 InfluxDBClient3.query()
示例,了解检索模式的方法。
RecordBatch
RecordBatch
消息 在 InfluxDB 集群响应流中包含以 Arrow 格式表示的查询结果数据。当飞行客户端接收到流时,它会从流中读取每个记录批次,直到没有更多消息可以读取。客户端在收到所有消息后认为请求已完成。
飞行客户端和 InfluxDB v3 客户端库提供从流中读取记录批次或“数据块”的方法。InfluxDB v3 Python 客户端库使用 pyarrow.flight.FlightStreamReader
类并提供以下读取方法
all
:将所有记录批次读取到pyarrow.Table
中。pandas
:将所有记录批次读取到pandas.DataFrame
中。chunk
:读取下一个批次及其元数据(如果可用)。reader
:将FlightStreamReader
实例转换为RecordBatchReader
。
飞行客户端实现飞行接口,但是客户端库类、方法和实现可能因每种语言和库而异。
InfluxDB 状态和错误代码
在 gRPC 中,每个调用都返回一个包含整数代码和字符串消息的状态对象。在请求过程中,gRPC 客户端和服务器可以各自返回一个状态——例如
- 服务器无法处理查询;响应状态为
internal error
和 gRPC 状态13
。 - 请求缺少数据库令牌;服务器响应状态为
unauthenticated
和 gRPC 状态16
。 - 服务器响应流,但客户端因网络故障而丢失连接,返回状态
unavailable
。
gRPC 定义了服务器和客户端的整数 状态代码 和定义,而 Arrow Flight 定义了 FlightStatusDetail
类和飞行 RPC 服务可能实现的 错误代码。
虽然Flight定义了服务器可用的状态码,但服务器可以选择在RPC调用中返回哪个状态。在错误响应中,状态details
字段包含一个错误码,客户端可以使用它来确定是否应向用户显示错误(例如,如果客户端应重试请求)。
排查错误
内部错误:收到RST_STREAM
示例:
Flight returned internal error, with message: Received RST_STREAM with error code 2. gRPC client debug context: UNKNOWN:Error received from peer ipv4:34.196.233.7:443 {grpc_message:"Received RST_STREAM with error code 2"}
潜在原因:
- 与服务器连接意外重置。
- 客户端和服务器之间的网络问题。
- 服务器可能由于内部错误关闭了连接。
- 客户端超过了服务器并发流的限制。
内部错误:通过RST_STREAM终止流,无错误
示例:
pyarrow._flight.FlightInternalError: Flight returned internal error, with message: stream terminated by RST_STREAM with error code: NO_ERROR. gRPC client debug context: UNKNOWN:Error received from peer ipv4:3.123.149.45:443 {created_time:"2023-07-26T14:12:44.992317+02:00", grpc_status:13, grpc_message:"stream terminated by RST_STREAM with error code: NO_ERROR"}. Client context: OK
潜在原因:
- 服务器终止了流,但没有与之相关的特定错误。
- 可能存在网络中断,即使它是临时的。
- 服务器可能已达到其最大容量或其他内部限制。
无效参数:无效票据
示例:
pyarrow.lib.ArrowInvalid: Flight returned invalid argument error, with message: Invalid ticket. Error: Invalid ticket. gRPC client debug context: UNKNOWN:Error received from peer ipv4:54.158.68.83:443 {created_time:"2023-08-31T17:56:42.909129-05:00", grpc_status:3, grpc_message:"Invalid ticket. Error: Invalid ticket"}. Client context: IOError: Server never sent a data message. Detail: Internal
潜在原因:
- 请求缺少数据库名称或其他必要元数据值。
- 请求包含错误的查询语法。
未认证:未认证
示例:
Flight returned unauthenticated error, with message: unauthenticated. gRPC client debug context: UNKNOWN:Error received from peer ipv4:34.196.233.7:443 {grpc_message:"unauthenticated", grpc_status:16, created_time:"2023-08-28T15:38:33.380633-05:00"}. Client context: IOError: Server never sent a data message. Detail: Internal
潜在原因:
- 请求中缺少令牌。
- 指定的组织不存在指定的令牌。
未授权:拒绝访问
示例:
pyarrow._flight.FlightUnauthorizedError: Flight returned unauthorized error, with message: Permission denied. gRPC client debug context: UNKNOWN:Error received from peer ipv4:54.158.68.83:443 {grpc_message:"Permission denied", grpc_status:7, created_time:"2023-08-31T17:51:08.271009-05:00"}. Client context: IOError: Server never sent a data message. Detail: Internal
潜在原因:
- 指定的令牌没有对指定数据库的读取权限。
Flight不可用错误:无法获取默认的pem根证书
示例:
如果无法找到gRPC+TLS的根证书,Flight客户端将返回类似以下错误
UNKNOWN:Failed to load file... filename:"/usr/share/grpc/roots.pem",
children:[UNKNOWN:No such file or directory
...
Could not get default pem root certs...
pyarrow._flight.FlightUnavailableError: Flight returned unavailable error,
with message: empty address list: . gRPC client debug context:
UNKNOWN:empty address list
...
潜在原因:
非POSIX兼容的系统(如Windows)需要为gRPC客户端指定SslCredentialsOptions中的根证书,因为默认配置仅适用于POSIX文件系统。指定Flight gRPC客户端的根证书路径。
有关gRPC SSL/TLS客户端-服务器认证的更多信息,请参阅使用客户端SSL/TLS,详情请见gRPC.io认证指南。
这个页面有帮助吗?
感谢您的反馈!