部署检测 Linux 性能
MeteorCat针对 Linux 大部分性能指标采集, 需要用到对应相关的工具集, 这里提供目前比较主流的 Linux 检测手段:
- perf: CPU 性能检测采集
- iperf3: 网络性能检测采集
- iostat: 磁盘IO监控
- sar: 全能监控数据采集
CPU 性能检测
perf 是 Linux 系统下的性能分析工具(Performance Counters for Linux), 用于针对
CPU|内存|磁盘I/O|网络|进程/线程等系统资源的使用情况进行全方位的采样和分析.
这里采用 Debian 发行版来说明, 其他发行版只需要找 perf|performance 相关包安装即可:
1 2 3 4 5 6
| # 安装依赖, 这里有的教程说是 linux-perf 或者 perf, 可能有的版本变迁之后更改包名 sudo apt install performance-tools
# 查看目前监控工具版本 # 需要注意: 系统性能采集本身是很高级的功能, 所以大部分情况都是需要用到 root 高级权限 sudo perf --version # 这里目前版本为 perf version 6.14.11
|
这里之后就是准备采集到具体指标信息, 建议可以参照文档来进行调试:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
| # 参考文档: https://www.man7.org/linux/man-pages/man1/perf.1.html
# 实时 CPU 性能火焰监控, 核心使用方法 # 用于分析占用 CPU 最高的函数 / 进程 / 模块 sudo perf top -g # 有的时候会提示让你选择, 比如 cpu_atom 和 cpu_core, 这是因为 CPU 采用大小核结构 # cpu_core: P-Core, Performance Core | 性能核, 算力强、主频高、缓存大,单核心性能拉满, 支持超线程 # cpu_atom: E-Core, Efficient Core | 能效核, 功耗低、能效比高、核心数多, 单核心性能弱于 P 核, 但胜在数量多、占用资源少 # 服务器很多时候都是只有 P-Core, 因为本身是服务器不讲究功耗节能, 要求的是最大限度释放核心性能, 所以既有 cpu_core # 部分内核版本中, cpu_atom 也可能显示为 cpu_efficiency, cpu_core 也可能显示为 cpu_performance, 含义完全一致只是命名不同
# 选择主要核心之后就可以看到对应的列表, 主要的三个指标 # Children/Self/Shared Object/Symbol #
# 若 Children 很高, Self 很低 → 该函数本身不耗 CPU, 它调用的子函数才是真正瓶颈 # 如果出现 Children 很高, Self 很低的情况, 需要检查下是不是程序内部业务代码逻辑是不是编写正确 # 但是这个指标不是唯一的, 因为确实有些业务必须要占用大量资源来处理, 所以这方面只能参考 #
# 若 Self 占比越高 → 该函数自身是纯 CPU 密集型(如循环、计算、序列化),是直接性能瓶颈, 优先优化这个函数本身 #
# 明确 CPU 高耗是业务进程、还是内核、还是第三方库, 常见取值如下 # [kernel] - 内核调用, 系统级瓶颈(如上下文切换频繁、内核锁竞争) # nginx/clickhouse-server - 业务进程, 进程任务占用瓶颈 # libc.so/libpthread.so - 系统库, 业务代码调用系统库的逻辑低效(如频繁内存分配、线程锁) #
# 确定瓶颈是 用户态函数/内核态函数/匿名符号 哪个方面导致的问题 # 用户态函数 - 如 kafka_consumer_poll()、data_process() → 业务代码写的函数, 可直接优化 # 内核态函数 - 函数名前带 [kernel], 如 schedule()、sys_read() → 内核逻辑, 需调系统参数/内核配置解决 # 匿名符号 - 显示为 0xffffffffxxxxxx → 程序无调试符号, 需给程序加 -g 编译/安装调试包 #
# Self → 函数「自己」耗CPU → 优化函数本身 # Children → 函数「全家」耗CPU → 优化它调用的子函数
# 进去火焰图之后的操作如下 # ↑ ↓ 方向键 → 上下滚动列表,查看更多热点函数 # Enter → 选中某行函数,展开/收起 -g 的调用栈 # q → 退出 perf top 监控界面 # s → 切换排序方式(按 Self/Children 排序,优先按 Self 排) # /xxx → 搜索关键字(如 /java 只看Java进程的热点、/kafka 只看kafka相关函数) # d → 按进程PID过滤(输入目标PID,只显示该进程的CPU热点,精准无噪音) # P → 按CPU核心过滤(只看指定核心的负载,适合大小核服务器)
# 开始记录 CPU 的性能分析报告 # perf record -e task-clock,cache-misses,cycles {程序二进制}
# 记录目前服务器 60 秒内的所有性能报告, 其中以每秒99次频率进行采样检测 sudo perf record -F 99 -a -g -- sleep 60 # 执行之后要等 60s 等待报告生成
# 耗费 60 秒收集之后就可以导出对应报告 # 模板默认版本不支持 JSON 输出, 只能生成默认 text 报告, 为了兼容性最好导出 txt 之后做每行数据分析 sudo perf report -i perf.data -g --stdio > perf_report.txt
# 纯文本结构化报告, 会打印父子节点分叉 sudo perf report -i perf.data -g --stdio --sort overhead > perf_struct.txt
# 导出perf原始结构化数据 sudo perf script -i perf.data > perf_raw.data
|
另外我很不喜欢大小核 CPU 的问题就是因为可能出现莫名其妙的调度问题, 比如最希望释放能效的程序会被分配到节能的能效核.
其中以英特尔的 CPU 调度问题最严重, 不过仅仅也只有家用服务器会影响到, 最多是 NAS 用户会出现这种问题, 可以通过内核参数禁用能效核心.
网络性能检测
iperf3 目前是比较常用的网络速度检测工具, 用于负责多种网络状态测试:
1 2 3 4 5
| # 安装依赖 sudo apt install -y iperf3
# 查看目前版本 sudo iperf3 --version # iperf 3.16 (cJSON 1.7.15)
|
一般 iperf3 多用于内网测速效率判断, 确认内网的网络是否能够跑满网络带宽, 外网检测比较复杂所以不能单纯用 iperf3 分析:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
| # 注意: 如果要测速必须要保证内网有最少两台实体服务器/NAS, 才能正确获取到性能指标
# 1. 首先必须要在准备测试的设备创建服务端 sudo iperf3 -s # 默认监听端口为 5201, 可以通过 -p <端口> 指定监听服务端口 # 不要在同一个服务上启动服务端同时启动客户端进行测试, 这种测速方式是没用的
# 2. 其他服务器发起正向测试, 用于检测 客户端 → 服务器 的网络速率, 可以看作是上传速率 # iperf3 -c <服务器IP> sudo iperf3 -c 192.168.1.9 # 最后可能输出速度如下 # [ ID] Interval Transfer Bitrate Retr # [ 5] 0.00-10.00 sec 99.9 GBytes 85.8 Gbits/sec 0 sender # [ 5] 0.00-10.00 sec 99.9 GBytes 85.8 Gbits/sec receiver
# 3. 其他服务器发起反向测试, 用于检测 服务器 → 客户端 的网络速率, 可以看作是下载速率 sudo iperf3 -c 192.168.1.9 -R
# 4. 其他服务器发起双向测试, 同时测试上传和下载速率 sudo iperf3 -c 192.168.1.9 --bidir # 最后的速率结果可能如下: # [ ID][Role] Interval Transfer Bitrate Retr # [ 5][TX-C] 0.00-10.00 sec 86.8 GBytes 74.5 Gbits/sec 0 sender # [ 5][TX-C] 0.00-10.00 sec 86.8 GBytes 74.5 Gbits/sec receiver # [ 7][RX-C] 0.00-10.00 sec 87.7 GBytes 75.3 Gbits/sec 36 sender # [ 7][RX-C] 0.00-10.00 sec 87.7 GBytes 75.3 Gbits/sec receiver
# 如果需要输出成 JSON 报告, 可以追加参数 --json --logfile <文件名> # 可以提供给监控文件采集对应的数据, 用于做服务器的状态监控 sudo iperf3 -c 192.168.1.9 --bidir --json --logfile iperf3.json
# 5. 另外还有 UDP 的吞吐测速判断, 适合测试视频流、实时数据传输等 UDP 业务场景 # -u 指定 UDP 协议, -t 指定测试时长(秒), -b 指定带宽上限 sudo iperf3 -c 192.168.1.9 -u -b 1G -t 10
# 6. 实际内网环境都是多线程并发很激烈, 所以需要模拟下这部分并发 # -P <线程数> 代表模拟业务并发线程 # 这里模拟内网 10G 带宽, 开 4 线程区来测速 sudo iperf3 -c 192.168.1.9 -b 10G -P 4 -R # [ ID] Interval Transfer Bitrate Retr # [ 5] 0.00-10.00 sec 11.6 GBytes 10.0 Gbits/sec 0 sender # [ 5] 0.00-10.00 sec 11.6 GBytes 10.0 Gbits/sec receiver # [ 7] 0.00-10.00 sec 11.6 GBytes 10.0 Gbits/sec 0 sender # [ 7] 0.00-10.00 sec 11.6 GBytes 10.0 Gbits/sec receiver # [ 9] 0.00-10.00 sec 11.6 GBytes 10.0 Gbits/sec 0 sender # [ 9] 0.00-10.00 sec 11.6 GBytes 10.0 Gbits/sec receiver # [ 11] 0.00-10.00 sec 11.6 GBytes 10.0 Gbits/sec 0 sender # [ 11] 0.00-10.00 sec 11.6 GBytes 10.0 Gbits/sec receiver # [SUM] 0.00-10.00 sec 46.6 GBytes 40.0 Gbits/sec 0 sender # [SUM] 0.00-10.00 sec 46.6 GBytes 40.0 Gbits/sec receiver
|
这里的网络速率有比较简单指标判断, 需要学习看这部分的指标:
-
Interval → 测速时间区间, 时间越长, 测速结果越精准, 可通过 -t 参数调整
-
Transfer → 测速周期内总传输数据量, 仅作为参考, 结合Bitrate看更有意义
-
Bitrate → 实际网络传输速率(核心指标), 若该值 ≈ 内网物理带宽 则代表网络正常且带宽跑满
百兆网卡 ≈ 94.1 Mbits/sec ≈ 94.1 Mbits/sec÷8 ≈ 11.8 MB/s
千兆网卡 ≈ 940 Mbits/sec ≈ 940 Mbits/sec÷8 ≈ 117.5 MB/s
万兆网卡 ≈ 9.4 Gbits/sec ≈ 9.4 Gbits/sec÷8 ≈ 1.175 GB/s
25G 网卡 ≈ 23.8 Gbits/sec ≈ 23.8 Gbits/sec÷8 ≈ 2.975 GB/s
-
Retr → 数据包重传次数(核心指标), 测速周期内因网络丢包导致的数据包重传数量, 也就是数据包重传次数, 数值越大链路质量越差
单位区分: Mbits/sec 是网卡链路带宽单位, MB/s 是文件传输的实际速度单位, 两者换算必须除以 8
注意: 这部分速率换算公式为 1 GB/s = 8 Gbits/sec, 也就是 测速显示 8 Gbits/sec, 实际文件传输速度约 1 GB/s.
内网应该尽可能保证达到 千兆网卡(117.5 MB/s) 的速度, 方便做内部的数据传输场景
有的小型服务器如果宣称支持千兆网络, 但是速率没有到达最低 100MB/s|940Mbits/sec 就需要判断网络环境哪里被干扰.
内网实际传输受网线、交换机、CPU 负载影响, 速率会略有下降, 但是降低的值不会偏差太大, 10% 以内偏差都是正常
如果需要构建家庭内网, 这些指标都是十分重要的判断方式, 用来判断是否最大程度跑满家庭的网络带宽.
一般来说网络速率跑满可以按照以下流程处理:
-
网线问题: 更换超五类 / 六类网线, 避免使用劣质线材(千兆网络对网线要求高)
-
交换机限制: 检查交换机端口是否被手动限速为 100 Mbps, 确保交换机端口为千兆口
-
CPU 负载过高: 测速时用 top 查看 CPU 使用率, 若 ≥ 80% → CPU 瓶颈导致无法跑满带宽, 需关闭其他高耗进程
-
网卡驱动问题: 更新网卡驱动(需要及时更新网卡驱动)
至于 WIFI 速率跑满千兆网络, 应该说目前还不是这么乐观, 虽然 WiFi 6(802.11ax) 和 WiFi 5(802.11ac Wave 2) 理论上能够达到,
但也是基于无干扰的实验室环境下, 一旦距离过长或者阻隔物体过多, 那么很大概率是只能回退成百兆带宽的情况.
硬盘性能检测
最后就是硬盘性能检测, Linux 这部分套件就比较多, 分析起来也相对容易:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| # 这部分原生工具 dd 和 df 就可以测试 # 生成 /tmp/disk_write_test 测试写入 1G 的本地测试数据 # 检测写入速度, oflag 规避缓存处理 dd if=/dev/zero of=/tmp/disk_write_test bs=1G count=1 oflag=direct # 这里输出如下信息: # 输入了 1+0 块记录 # 输出了 1+0 块记录 # 1073741824 字节 (1.1 GB, 1.0 GiB) 已复制,0.599968 s,1.8 GB/s
# 测试硬盘读取速度 dd if=/tmp/disk_write_test of=/dev/null bs=1G count=1 iflag=direct # 这里输出如下信息: # 输入了 1+0 块记录 # 输出了 1+0 块记录 # 1073741824 字节 (1.1 GB, 1.0 GiB) 已复制,0.363162 s,3.0 GB/s
# 最后删除生成文件 rm -f /tmp/disk_write_test
# df 查看硬盘容量使用率+挂载信息, 排查磁盘满导致的性能问题 # -h 人性化单位显示, -T 显示硬盘文件系统格式(ext4/xfs等) df -hT
# 这里我是外部扩展出来的机械硬盘, 用于查看机械和固态硬盘的差距 # /data 是外部扩展硬盘, 这里测试写入速度 dd if=/dev/zero of=/data/disk_write_test bs=1G count=1 oflag=direct # 输入了 1+0 块记录 # 输出了 1+0 块记录 # 1073741824 字节 (1.1 GB, 1.0 GiB) 已复制,5.69057 s,189 MB/s
# 测试读取速率 dd if=/data/disk_write_test of=/dev/null bs=1G count=1 iflag=direct # 输入了 1+0 块记录 # 输出了 1+0 块记录 # 1073741824 字节 (1.1 GB, 1.0 GiB) 已复制,6.34121 s,169 MB/s
# 最后删除生成文件 rm -f /data/disk_write_test
|
注意: 对于外部扩展的硬盘, 不要在系统盘根目录测速; 优先在业务数据盘测试, 一般是在扩展的硬盘生成测试文件.
而如果想要让本地文件速率贴合千兆带宽, 必须确保硬盘的速度大等于千兆网络速度, 否则硬盘速度将会成为瓶颈
对于硬盘来说, 以下指标都是相对比较正常的:
-
机械硬盘(HDD): 顺序读写 ≈ 80-150 MB/s 即为正常
-
固态硬盘(SSD): 顺序读写 ≈ 300-500 MB/s(SATA)即为达标
-
NVMe 固态(NVMe): 顺序读写 ≈ 1000-3500 MB/s, 是目前最快的硬盘类型, 速率轻松破千兆
另外还有多线程因素, 这部分读写也是会影响到最终的传输速率
一般来说如果要构建内网千兆网络的话, 那么硬盘读写速度最低也不能低于 117.5 MB/s, 否则会触发网络传输的瓶颈.