指标和算子的计算逻辑
本文将介绍不同类型指标,不同算子的计算逻辑。
#1. 指标
指标分为应用性能指标
和网络性能指标
两个大类。
#1.1 应用性能指标
应用指标是用来衡量服务在实际运行中的性能表现的指标,主要关注服务的吞吐量、响应时延和异常情况。通过统计这些指标量,可以帮助运维人员和开发者更好地了解应用程序在实际使用中的表现,并且发现潜在的性能问题,从而采取相应的措施进行优化和改进。
以下描述的指标会在每个统计周期内都记录一个指标量,统计周期用户可以自定义,目前系统默认支持的为 1m(一分钟)和 1s(一秒)(这些数据 DeepFlow 平台统称为原始数据源),如果在一个统计周期内,计算得到多个指标量时,最终会聚合记录为一个指标量,聚合的逻辑见后续类型
的描述。
#1.1.1 吞吐量(Throughput)
Field | DisplayName | Unit | Type | Description |
---|---|---|---|---|
request | 请求 | 个 | counter | 请求总数 |
response | 响应 | 个 | counter | 响应总数 |
generate from csv file: application.ch?Category=Throughput
#1.1.2 时延(Delay)
Field | DisplayName | Unit | Type | Description |
---|---|---|---|---|
rrt | 平均时延 | 微秒 | delay | 采集周期内所有应用时延的平均值,单次应用时延等于响应与请求的时间差 |
rrt_max | 最大时延 | 微秒 | delay | 采集周期内所有应用时延的最大值,单次应用时延等于响应与请求的时间差 |
generate from csv file: application.ch?Category=Delay
#1.1.3 异常(Error)
Field | DisplayName | Unit | Type | Description |
---|---|---|---|---|
error | 异常 | 个 | counter | 客户端异常 + 服务端异常 |
client_error | 客户端异常 | 个 | counter | 根据具体应用协议的响应码判断异常,不同协议的定义见 l7_flow_log 中 response_status 字段的说明 |
server_error | 服务端异常 | 个 | counter | 根据具体应用协议的响应码判断异常,不同协议的定义见 l7_flow_log 中 response_status 字段的说明 |
timeout | 超时 | 个 | counter | 应用超时的统计次数(默认配置下:TCP 类应用在 1800s 内未采集到响应,UDP 类应用在 150s 内未采集到响应) |
error_ratio | 异常比例 | % | percentage | 异常 / 响应 |
client_error_ratio | 客户端异常比例 | % | percentage | 客户端异常 / 响应 |
server_error_ratio | 服务端异常比例 | % | percentage | 服务端异常 / 响应 |
generate from csv file: application.ch?Category=Error
#1.2 网络性能指标
网络指标是用来评估网络性能的一些量化指标,涵盖网络层、传输层和应用层,这些指标包括吞吐量、延迟、性能和异常类型等
#1.2.1 网络层吞吐量 (L3 Throughput)
Field | DisplayName | Unit | Type | Description |
---|---|---|---|---|
byte | 字节 | 字节 | counter | 发送字节 + 接收字节 |
byte_tx | 发送字节 | 字节 | counter | 资源发送的字节数总和(含 Ethernet 头) |
byte_rx | 接收字节 | 字节 | counter | 资源接收的字节数总和(含 Ethernet 头) |
packet | 包数 | 包 | counter | 发送包数 + 接收包数 |
packet_tx | 发送包数 | 包 | counter | 资源发送的包数总和 |
packet_rx | 接收包数 | 包 | counter | 资源接收的包数总和 |
l3_byte | 网络层载荷 | 字节 | counter | 发送网络层载荷 + 接收网络层载荷 |
l3_byte_tx | 发送网络层载荷 | 字节 | counter | 资源发送的网络层载荷字节数总和(不含 IP 头) |
l3_byte_rx | 接收网络层载荷 | 字节 | counter | 资源接收的网络层载荷字节数总和(不含 IP 头) |
bpp | 平均包长 | 字节 | quotient | 字节 / 包数 |
bpp_tx | 平均发送包长 | 字节 | quotient | 发送字节 / 发送包数 |
bpp_rx | 平均接收包长 | 字节 | quotient | 接收字节 / 接收包数 |
generate from csv file: network.ch?Category=L3 Throughput
#1.2.2 传输层吞吐量(L4 Throughput)
Field | DisplayName | Unit | Type | Description |
---|---|---|---|---|
new_flow | 新建连接 | 连接 | counter | 采集周期内新建的 TCP 连接数,连接 的定义详见文档 |
closed_flow | 关闭连接 | 连接 | counter | 采集周期内关闭的 TCP 连接数,连接 的定义详见文档 |
flow_load | 活跃连接 | 连接 | gauge | 采集周期内活跃的连接数,包括有数据交互的长连接、无数据交互的长连接、周期内关闭的短连接,连接 的定义详见文档 |
syn_count | SYN 包数 | 包 | counter | SYN 包的总数 |
synack_count | SYN-ACK 包数 | 包 | counter | SYN-ACK 包的总数 |
l4_byte | 传输层载荷 | 字节 | counter | 发送传输层载荷 + 接收传输层载荷 |
l4_byte_tx | 发送传输层载荷 | 字节 | counter | 资源发送的包传输层载荷字节数总和(不含 TCP/UDP 头) |
l4_byte_rx | 接收传输层载荷 | 字节 | counter | 资源接收的包传输层载荷字节数总和(不含 TCP/UDP 头) |
generate from csv file: network.ch?Category=L4 Throughput
活跃连接计算逻辑:
- 采集器以四元组(客户端 IP、服务端 IP、协议、服务端口)为单位统计原始活跃连接数,并进而计算出资源、路径对应的活跃连接数
- 数据源对应的时间间隔内能采集到流量,则统计活跃连接,但存在一些特殊情况:
- 1s 数据源:描述每秒统计到的活跃连接数
- 每分钟第 1 秒:包括该秒内无流量但未结束的连接,一般可用于评估并发连接(无交叠且持续时间小于一秒的多个连接会带来一些误差)
- 每分钟后 59 秒:如果相同四元组的多条流在该秒内均无流量,这一秒会忽略该四元组对应的连接数,一般可用于评估并发连接的下界
- 1m 数据源:描述每分钟统计到的活跃连接数
- 包括没有流量但仍未结束的连接,一般可用于评估并发连接的上界
- 自定义数据源:根据 1s/1m 数据源通过 Avg/Max/Min 计算得到,含义与直接使用 1s/1m 数据源并选择 Avg/Max/Min 算子得到的值相同
- 1s 数据源:描述每秒统计到的活跃连接数
#1.2.3 传输层 TCP 性能 (TCP Slow)
Field | DisplayName | Unit | Type | Description |
---|---|---|---|---|
retrans_syn | SYN 重传 | 包 | counter | SYN 包的重传次数 |
retrans_synack | SYN-ACK 重传 | 包 | counter | SYN-ACK 包的重传次数 |
retrans | TCP 重传 | 包 | counter | TCP 客户端重传 + TCP 服务端重传 |
retrans_tx | TCP 客户端重传 | 包 | counter | 资源发送的 TCP 重传包次数 |
retrans_rx | TCP 服务端重传 | 包 | counter | 资源接收的 TCP 重传包次数 |
zero_win | TCP 零窗 | 包 | counter | TCP 客户端零窗 + TCP 服务端零窗 |
zero_win_tx | TCP 客户端零窗 | 包 | counter | 资源发送的 TCP 零窗包次数 |
zero_win_rx | TCP 服务端零窗 | 包 | counter | 资源接收的 TCP 零窗包次数 |
retrans_syn_ratio | SYN 重传比例 | % | percentage | TCP SYN 重传 / TCP SYN 包数 |
retrans_synack_ratio | SYN-ACK 重传比例 | % | percentage | TCP SYN-ACK 重传 / TCP SYN-ACK 包数 |
retrans_ratio | TCP 重传比例 | % | percentage | TCP 重传 / 包数 |
retrans_tx_ratio | TCP 客户端重传比例 | % | percentage | TCP 客户端重传 / 发送包数 |
retrans_rx_ratio | TCP 服务端重传比例 | % | percentage | TCP 服务端重传 / 接收包数 |
zero_win_ratio | TCP 零窗比例 | % | percentage | TCP 零窗 / 包数 |
zero_win_tx_ratio | TCP 客户端零窗比例 | % | percentage | TCP 客户端零窗 / 发送包数 |
zero_win_rx_ratio | TCP 服务端零窗比例 | % | percentage | TCP 服务端零窗 / 接收包数 |
generate from csv file: network.ch?Category=TCP Slow
#1.2.4 传输层 TCP 异常 (TCP Error)
Field | DisplayName | Unit | Type | Description |
---|---|---|---|---|
tcp_establish_fail | 建连-失败次数 | 次 | counter | 建连-客户端失败次数 + 建连-服务端失败次数 |
client_establish_fail | 建连-客户端失败次数 | 次 | counter | 建连-客户端端口复用 + 建连-客户端其他重置 + 建连-客户端 ACK 缺失 |
server_establish_fail | 建连-服务端失败次数 | 次 | counter | 建连-服务端 SYN 缺失 + 建连-服务端直接重置 + 建连-服务端其他重置 |
tcp_establish_fail_ratio | 建连-失败比例 | % | percentage | 建连-失败次数 / 关闭连接 |
client_establish_fail_ratio | 建连-客户端失败比例 | % | percentage | 建连-客户端失败次数 / 关闭连接 |
server_establish_fail_ratio | 建连-服务端失败比例 | % | percentage | 建连-服务端失败次数 / 关闭连接 |
tcp_transfer_fail | 传输-失败次数 | 次 | counter | 传输-客户端重置 + 传输-服务端重置 + 传输-服务端队列溢出 + 传输-TCP 连接超时 |
tcp_transfer_fail_ratio | 传输-失败比例 | % | percentage | 传输-失败次数 / 关闭连接 |
tcp_rst_fail | 重置次数 | 连接 | counter | 建连-客户端其他重置 + 建连-服务端直接重置 + 建连-服务端其他重置 + 传输-客户端重置 + 传输-服务端重置 |
tcp_rst_fail_ratio | 重置比例 | % | percentage | 重置次数 / 关闭连接 |
client_source_port_reuse | 建连-客户端端口复用 | 连接 | counter | TCP 建连失败的场景之一,见文档描述 |
server_syn_miss | 建连-服务端 SYN 缺失 | 连接 | counter | TCP 建连失败的场景之一,见文档描述 |
client_establish_other_rst | 建连-客户端其他重置 | 连接 | counter | TCP 建连失败的场景之一,见文档描述 |
client_ack_miss | 建连-客户端 ACK 缺失 | 连接 | counter | TCP 建连失败的场景之一,见文档描述 |
server_reset | 建连-服务端直接重置 | 连接 | counter | TCP 建连失败的场景之一,见文档描述 |
server_establish_other_rst | 建连-服务端其他重置 | 连接 | counter | TCP 建连失败的场景之一,见文档描述 |
client_rst_flow | 传输-客户端重置 | 连接 | counter | TCP 传输失败的场景之一,见文档描述 |
server_rst_flow | 传输-服务端重置 | 连接 | counter | TCP 传输失败的场景之一,见文档描述 |
server_queue_lack | 传输-服务端队列溢出 | 连接 | counter | TCP 传输失败的场景之一,见文档描述 |
tcp_timeout | 传输-TCP 连接超时 | 连接 | counter | TCP 传输失败的场景之一,见文档描述 |
client_half_close_flow | 断连-客户端半关 | 连接 | counter | TCP 断连异常的场景之一,见文档描述 |
server_half_close_flow | 断连-服务端半关 | 连接 | counter | TCP 断连异常的场景之一,见文档描述 |
generate from csv file: network.ch?Category=TCP Error
#1.2.4.1 TCP 建连异常
TCP 建连异常
#1.2.4.2 TCP 传输异常
TCP 传输异常
#1.2.5 传输层时延 (Delay)
Field | DisplayName | Unit | Type | Description |
---|---|---|---|---|
rtt | 平均 TCP 建连时延 | 微秒 | delay | 采集周期内,所有 TCP 建连时延的平均值,单次时延的计算见文档描述 |
rtt_client | 平均 TCP 建连客户端时延 | 微秒 | delay | 采集周期内,所有 TCP 建连客户端时延的平均值,单次时延的计算见文档描述 |
rtt_server | 平均 TCP 建连服务端时延 | 微秒 | delay | 采集周期内,所有 TCP 建连服务端时延的平均值,单次时延的计算见文档描述 |
srt | 平均 TCP/ICMP 系统时延 | 微秒 | delay | 采集周期内,所有 TCP/ICMP 系统时延的平均值,单次时延的计算见文档描述 |
art | 平均数据时延 | 微秒 | delay | 采集周期内,所有数据时延的平均值,数据时延包含 TCP/UDP,单次时延的计算见文档描述 |
cit | 平均客户端等待时延 | 微秒 | delay | 采集周期内,所有客户端等待时延的平均值,数据时延仅包含 TCP,单次时延的计算见文档描述 |
rtt_max | 最大 TCP 建连时延 | 微秒 | delay | 采集周期内,所有 TCP 建连时延的最大值,单次时延的计算见文档描述 |
rtt_client_max | 最大 TCP 建连客户端时延 | 微秒 | delay | 采集周期内,所有 TCP 建连客户端时延的最大值,单次时延的计算见文档描述 |
rtt_server_max | 最大 TCP 建连服务端时延 | 微秒 | delay | 采集周期内,所有 TCP 建连服务端时延的最大值,单次时延的计算见文档描述 |
srt_max | 最大 TCP/ICMP 系统时延 | 微秒 | delay | 采集周期内,所有 TCP/ICMP 系统时延的最大值,单次时延的计算见文档描述 |
art_max | 最大数据时延 | 微秒 | delay | 采集周期内,所有数据时延的最大值,数据时延包含 TCP/UDP,单次时延的计算见文档描述 |
cit_max | 最大客户端等待时延 | 微秒 | delay | 采集周期内,所有客户端等待时延的最大值,数据时延仅包含 TCP,单次时延的计算见文档描述 |
generate from csv file: network.ch?Category=Delay
TCP 网络时延解剖
- 建连时产生的时延
- [1] 完整的
建连时延
包含客户端发出 SYN 包到收到服务端回复的 SYN+ACK 包,并再次回复 ACK 包的整个时间。建连时延拆解开又可分为客户端建连时延
与服务端建连时延
- [2]
客户端建连时延
为客户端收到 SYN+ACK 包后,回复 ACK 包的时间 - [3]
服务端建连时延
为服务端收到 SYN 包后,回复 SYN+ACK 包的时间
- [1] 完整的
- 数据通信时产生的时延,可拆解为
客户端等待时延
+数据传输时延
- [4]
客户端等待时延
为建连成功后,客户端首次发送请求的时间;为收到服务端的数据包后,客户端再发起数据包的时间 - [5]
数据传输时延
为客户端发送数据包到收到服务端回复数据包的时间 - [6] 在数据传输时延中还会产生系统协议栈的处理时延,称为
系统时延
,为数据包收到 ACK 包的时间
- [4]
#1.2.6 应用层指标(Application)
Field | DisplayName | Unit | Type | Description |
---|---|---|---|---|
l7_request | 应用请求 | 个 | counter | 应用层协议请求次数 |
l7_response | 应用响应 | 个 | counter | 应用层协议响应次数 |
rrt | 平均应用时延 | 微秒 | delay | 采集周期内,所有应用时延的平均值,单次应用时延等于响应与请求的时间差 |
rrt_max | 最大应用时延 | 微秒 | delay | 采集周期内,所有应用时延的最大值,单次应用时延等于响应与请求的时间差 |
l7_error | 应用异常 | 个 | counter | 应用客户端异常 + 应用服务端异常 |
l7_client_error | 应用客户端异常 | 个 | counter | 根据具体应用协议的响应码判断异常,不同协议的定义见 l7_flow_log 中 response_status 字段的说明 |
l7_server_error | 应用服务端异常 | 个 | counter | 根据具体应用协议的响应码判断异常,不同协议的定义见 l7_flow_log 中 response_status 字段的说明 |
l7_timeout | 应用超时 | 个 | counter | 应用超时的统计次数(默认配置下:TCP 类应用在 1800s 内未采集到响应,UDP 类应用在 150s 内未采集到响应) |
l7_error_ratio | 应用异常比例 | % | percentage | 应用异常 / 应用响应 |
l7_client_error_ratio | 应用客户端异常比例 | % | percentage | 应用客户端异常 / 应用响应 |
l7_server_error_ratio | 应用服务端异常比例 | % | percentage | 应用服务端异常 / 应用响应 |
generate from csv file: network.ch?Category=Application
#1.2.7 基数统计 (Cardinality)
统计周期内,计数采集到的数据不重复的 tag 个数。例如查询所有访问 pod_1 的客户端 IP 地址 (ip_0)
这个指标量,表达的含义则是访问 pod_1 所有流量里面不重复的客户端 IP 地址有多少个。
Field | DisplayName | Unit | Type | Description |
---|
generate from csv file: network.ch?Category=Cardinality
#2. 算子
算子根据选定的时间范围及时间间隔,对原始数据源中的数据进行计算。例如使用折线图查看 1s 的原始数据源,最近 5 分钟,按 20s 的时间间隔的 Avg 数据,以折线图上一个点为例(14:43:00)则是读取原始数据源里面的 14:42:40 - 14:43:00 这个时间范围内的所有数据,然后求平均值。
算子支持嵌套叠加,其中聚合算子
不支持叠加,例如 PerSecond(Avg(byte)) 表达的含义为先求 Avg(byte),然后得到的值再根据 PerSecond 二次计算。
#2.1 聚合算子
算子 | 英文名 | 适用的指标类型 | 描述 |
---|---|---|---|
Avg | Average | 所有类型 | 平均值(用于 Counter/Gauge 指标时不会忽略零值) |
AAvg | Arithmetic Average | 所有类型 | 算数平均值(先求每个时间点的均值,再求均值的平均) |
Sum | Sum | Counter 类型 | 加和值 |
Max | Maximum | 所有类型 | 最大值 |
Min | Minimum | 所有类型 | 最小值 |
Percentile | Estimated Percentile | 所有类型 | 估算百分位数 |
PercentileExact | Exact Percentile | 所有类型 | 精准百分位数 |
Spread | Spread | 所有类型 | 绝对跨度,统计周期内,Max 减去 Min |
Rspread | Relative Spread | 所有类型 | 相对跨度,统计周期内,Max 除以 Min |
Stddev | Standard Deviation | 所有类型 | 标准差 |
Apdex | Application Performance Index | Delay 类型 | 时延满意度 |
Last | Last | 所有类型 | 最新值 |
Uniq | Estimated Uniq | Cardinality 类型 | 估算基数统计 |
UniqExact | Exact Uniq | Cardinality 类型 | 精准基数统计 |
#2.2 二级算子
算子 | 描述 |
---|---|
PerSecond | 计算速率,将内层算子结果除以时间间隔 [1] |
Math | 四则运算,支持 +、-、*、/ |
Percentage | 单位转化 % |
- [1] 例如:
PerSeond(Sum)
表示先求和,再除以 API 传入的时间间隔interval
;PerSeond(Avg)
表示先求平均,然后除以数据源的时间间隔data_precision
。
#3. 不同指标的算子计算逻辑
#3.1 Counter/Gauge 类指标
- flow_metrics 的数据表
Sum
算子- 计算查询时间范围内所有数据的
Sum
- 计算查询时间范围内所有数据的
Avg
算子- 计算查询时间范围内所有数据的
Sum
,并除以interval/data_precision
- 计算查询时间范围内所有数据的
- 其他算子
- 先使用
Sum
根据data_precision
进行聚合 - 再根据选择的具体算子调用
ClickHouse
的函数进行计算
- 先使用
- 当被迫(由于同语句中其他指标量的需要)使用两层
SQL
计算时Sum/Avg
算子- 先使用
Sum
根据data_precision
进行聚合 - 再根据选择的具体算子调用
ClickHouse
的函数进行计算
- 先使用
- flow_log 的数据表
- 根据选择的具体算子调用
ClickHouse
的函数进行计算
- 根据选择的具体算子调用
- prometheus/ext_metrics/deepflow_system 的数据表
- 与 flow_metrics 数据表一致
- 额外说明
Min
算子对无数据或数据为null
的时间点进行fill 0
#3.2 Quotient/Percentage 类指标
- flow_metric 的数据表
Avg
算子- 计算查询时间范围内所有数据的
Sum(x)/Sum(y)
- 计算查询时间范围内所有数据的
- 其他算子
- 先使用
Sum(x)/Sum(y)
根据data_precision
进行聚合 - 再根据选择的具体算子调用
ClickHouse
的函数进行计算
- 先使用
- 当被迫(由于同语句中其他指标量的需要)使用两层
SQL
计算时Avg
算子- 先使用
Sum(x)/Sum(y)
根据data_precision
进行聚合 - 再根据选择的具体算子调用
ClickHouse
的函数进行计算
- 先使用
- flow_log 的数据表
- 根据选择的具体算子调用
ClickHouse
的函数func(x/y)
进行计算
- 根据选择的具体算子调用
- 额外说明
Percentage
类指标量的Min
算子对无数据的时间点进行fill 0
- 计算
Sum(x)/Sum(y)
时,忽略分母为0/null
或分子为null
的点
#3.3 Delay/BoundedGauge 类指标
- flow_metric 的数据表
- 根据选择的具体算子调用
ClickHouse
的函数进行计算 - 当被迫(由于同语句中其他指标量的需要)使用两层
SQL
计算时Avg/Min/Max
算子- 两层均根据选择的具体算子调用
ClickHouse
的函数进行计算
- 两层均根据选择的具体算子调用
Spread/Rspread
算子- 先使用
Max
和Min
根据data_precision
进行聚合 - 再根据选择的具体算子调用
ClickHouse
的函数进行计算
- 先使用
- 其他算子
- 先使用
groupArray
进行聚合 - 再根据选择的具体算子调用
ClickHouse
的函数进行计算
- 先使用
- 根据选择的具体算子调用
- flow_log 的数据表
- 根据选择的具体算子调用
ClickHouse
的函数进行计算
- 根据选择的具体算子调用
- 额外说明
BoundedGauge
类指标的Min
算子对无数据或数据为null
的时间点进行fill 0
Delay
类指标忽略 0 的点,认为 0 是无意义的时延值
#3.4 不同数据库/表的 data_precision
数据库 | data_precision | 备注 |
---|---|---|
flow_metrics | 1s/1m | 默认支持 1s、1m,可聚合为 1h、1d |
flow_log | 1s | 实际上没有data_precision 的概念,其取值仅为方便计算 |
application_log | 1s | 实际上没有data_precision 的概念,其取值仅为方便计算 |
prometheus | 10s | 可通过server.yaml 的data_source_prometheus_interval 字段修改 |
ext_metrics | 10s | 可通过server.yaml 的data_source_ext_metrics_interval 字段修改 |
deepflow_admin | 10s | |
deepflow_tenant | 10s | |
event | 1s | 实际上没有data_precision 的概念,其取值仅为方便计算 |
profile | 1s | 实际上没有data_precision 的概念,其取值仅为方便计算 |