十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Ubuntu硬件信息查询:CPU、GPU、内存、硬盘与一键巡检脚本

Ubuntu硬件信息查询:CPU、GPU、内存、硬盘与一键巡检脚本 在 Ubuntu 上查 CPU、GPU、硬盘、内存这些硬件信息是运维、算法、装机、售后几拨人共同的日常动作。手上这台机器是几核几线程、内存是单条还是双条、显卡跑在什么链路宽度上、NVMe 的健康度还剩多少——这些答案直接决定你后面能不能顺利装上 PyTorch 的 GPU 版本、能不能把 Spark 的内存参数调对、能不能在硬盘彻底罢工之前把数据搬走。可惜现实里太多人是这么干的装完 Ubuntu敲一个lscpu看到 64就以为自己是 64 个物理核nvidia-smi没报错就以为 CUDA 环境万事俱备df -h还有空间就以为硬盘没事。等到真正跑任务才发现显存不够、CPU 缺 AVX 指令集、M.2 盘已经被写掉了九成寿命。这篇把 Ubuntu 下 CPU、GPU、硬盘、内存的查询链路从头捋一遍从最基础的lscpu、free到需要动点脑子的dmidecode、smartctl、nvidia-smi最后给一个能打包带走的一键巡检脚本。刚装完系统的可以当检查清单已经在跑业务的可以当排障手册。1. 先把需求拆开你到底想知道什么硬件信息查询这件事看起来是一个动作实际上背后至少藏着三类完全不同的需求。把这三类分清你才知道该用哪条命令、该看哪个字段而不是在网上抄一串命令挨个敲一遍敲完还是不知道机器什么水平。1.1 三种典型场景问的问题完全不一样第一类是装机验货。刚从供应商那里拿到一台服务器或者自己攒了一台工作站需要确认实物和采购单对不对得上。这时候你关心的是是不是双路内存插了几条、插在哪几个槽位显卡是不是真的那张卡而不是刷了 BIOS 的山寨货硬盘是不是标的那个型号和容量。这一类的关键词是核对对比对象是合同和配置单所以输出要尽量完整、可存档。第二类是性能排障。线上服务变慢、训练任务比预期慢一倍、JVM 堆内存老是溢出、Spark 任务频繁 spill 到磁盘。这时候你关心的是CPU 有没有被降频内存是单通道还是双通道是不是跑在 NUMA 远端节点上GPU 是不是掉到 PCIe x4 了磁盘 IO 是不是已经打满。关键词是瓶颈定位你需要的是实时数据和历史趋势的对照而不是静态清单。第三类是环境复现。同事说我这边跑得好好的你那边报错了或者你要在另一台机器上重建一模一样的环境。这时候你关心的是内核版本、驱动版本、CUDA 版本、glibc 版本、CPU 指令集这些能让程序行为产生差异的软硬件组合。关键词是差异比对你需要一份能贴进聊天窗口、能被 diff 的文本快照。三类需求对应的采集深度差别很大。装机验货要把每条内存的序列号都扒出来性能排障要连续采样看曲线环境复现反而只需要少数几个关键字段。我一般是先按第三类的标准采一遍全量再根据实际问题往深里挖。1.2 为什么不推荐一上来就装图形化工具Ubuntu 桌面版下确实有 HardInfo、GNOME 系统监视器这类工具Windows 那边也有 Victoria、CrystalDiskInfo 这类硬盘检测软件界面直观。但在服务器场景下它们基本用不上一是大部分生产机根本不装桌面环境二是 SSH 过去没有图形界面三是图形工具的输出没法进脚本、没法进工单系统。命令行工具还有一个隐藏优势——可组合。lscpu的输出能被grep、awk切着用nvidia-smi支持--query-gpu直接吐 CSVsmartctl有-j参数输出 JSON。这意味着你可以把巡检做成定时任务每天自动抓一份快照硬盘健康度掉到阈值以下就发告警。这种自动化能力是图形工具给不了的。提示Ubuntu 上所有硬件信息最终都来自/proc、/sys和几个内核接口DMI、SMART、NVMe 管理接口。理解这一点你就知道为什么有些命令要 root为什么有些虚拟机里查出来的数据是假的。2. CPU 信息别再把逻辑核当物理核CPU 这一块最容易被误读。nproc返回 64很多人就直接认为我这机器 64 核然后在容器配额、线程池大小、编译并行度这些地方全按 64 来配结果要么资源争抢要么利用率上不去。真实情况是nproc返回的是逻辑处理器数量和物理核心、插槽、NUMA 节点是两回事。2.1 lscpu 的每一行都在说什么lscpu是第一个该敲的命令它不需要 root输出干净字段含义明确。我挑几个真正有信息量的字段解释Architecture: x86_64 CPU(s): 64 On-line CPU(s) list: 0-63 Thread(s) per core: 2 Core(s) per socket: 16 Socket(s): 2 NUMA node(s): 2 Model name: Intel(R) Xeon(R) Gold 6248R CPU 3.00GHz CPU MHz: 2999.998 CPU max MHz: 4000.0000 CPU min MHz: 1200.0000 L3 cache: 48 MiB Virtualization: VT-x Flags: fpu vme de pse ... avx avx2 avx512f ...这组数字之间的关系非常好算物理核心数 Socket(s) × Core(s) per socket也就是 2 × 16 32 个物理核。逻辑 CPU 数 物理核心数 × Thread(s) per core也就是 32 × 2 64和CPU(s)对得上。NUMA 节点数反映内存访问的非一致性2 路机器通常就是 2 个节点。为什么这个区分很重要举两个实际例子。第一个是编译make -j64在 32 物理核 超线程的机器上通常比make -j32更慢因为编译是计算密集型任务超线程带来的额外吞吐抵不过缓存争抢。第二个是线程池Java 应用里常见的Runtime.getRuntime().availableProcessors()拿到的是逻辑核数如果你在容器里没做 CPU limit它可能返回宿主机全部的核心数然后 JVM 按这个数字去开 GC 线程和 ForkJoinPool 线程在只有 2 核配额的环境里直接把自己拖死。CPU MHz 和 CPU max MHz 的差值也值得看一眼。如果CPU MHz长期明显低于 max要么是 BIOS 里关掉了 Turbo要么是散热压不住在被动降频要么是powersave调频策略在省电。cpupower frequency-info能看到当前的 governor服务器上一般建议设成performance。2.2 /proc/cpuinfo 与指令集核对AVX 这个坑/proc/cpuinfo是lscpu的原始数据源字段更碎但更全。它按逻辑处理器逐个列出所以你想看某个特定核心的信息可以精确到processor : 37那一段。常用的提取方式# 只看物理 CPU 的 model name去重 grep -m1 model name /proc/cpuinfo # 统计逻辑处理器数量 grep -c ^processor /proc/cpuinfo # 查看物理 ID 和每颗物理 CPU 的核心数 grep -E physical id|cpu cores /proc/cpuinfo | sort -u # 直接看指令集 grep -m1 ^flags /proc/cpuinfo | tr \n | grep -E ^avx最后一个命令是我强烈建议每个人都跑一次的。指令集不匹配是个典型的编译期看不出来、运行期直接崩的问题。很多生信工具、深度学习框架预编译包、数学库比如某些 BLAS 实现在构建时启用了 AVX、AVX2 甚至 AVX-512。如果你把这类二进制拿到一台只有 SSE4 的老 CPU 上跑程序可能启动就直接退出报一句类似 this CPU does not support avx, which is required 的错误连日志都不给你留。这不是软件坏了是硬件真的不支持。所以装机验货时除了核对型号和核数把avx、avx2、avx512f、fma这几个 flag 记下来很有必要。后面要部署什么框架先拿这份清单对一遍能省掉大量无谓的排查时间。注意容器里读/proc/cpuinfo看到的是宿主机的 CPU 信息不是分配给容器的资源。想知道 cgroup 到底给了你多少 CPU得看/sys/fs/cgroup/cpu.maxcgroup v2或者/sys/fs/cgroup/cpu/cpu.cfs_quota_usv1。lscpu加了-e参数也一样会显示宿主机的拓扑。2.3 NUMA 与多路机器numactl 补位双路及以上的机器内存访问是有远近之分的。每个 CPU 插槽旁边挂着一组内存控制器和对应的内存条这就是一个 NUMA 节点。CPU 访问自己节点的内存local延迟低、带宽高访问另一个节点的内存remote要跨 QPI/UPI 总线延迟和带宽都要打折扣。lscpu只告诉你节点数量想看清每个节点的 CPU 和内存分布用numactl --hardwaresudo apt install numactl -y numactl --hardware输出里会列出node 0 cpus、node 0 size、node 0 free、node distances等。node distances那一张矩阵很关键对角线是 10自己到自己跨节点通常是 21 左右数字越大跨得越贵。这对什么场景有影响数据库MySQL、Redis、大内存 JVM 应用、Spark Executor、还有做大规模数值计算的进程。如果进程的内存被分配在了远端节点而 CPU 在本地性能可能直接掉 20% 到 40%。解决办法一般是在启动命令前加numactl --cpunodebind0 --membind0把进程绑死在某个节点或者更省事地开启自动 NUMA 均衡numactl --show能看到当前策略。我见过最典型的翻车是一台双路机器Spark Executor 的堆设得比单节点内存还大结果一半内存跨了节点GC 时间翻倍。后来把 Executor 内存压到单节点容量以内问题立刻消失。3. 内存容量之外的三个关键维度提到内存大部分人的第一反应是多大。但容量只是最表层的一个数字真正影响性能的是通道数、频率、插槽排布这三件事而这三件事恰好是free完全看不出来的。3.1 free 与 /proc/meminfoavailable 才是你要看的数free -h是最常用的命令但它的输出常被误读。看一段典型输出total used free shared buff/cache available Mem: 251Gi 38Gi 3.2Gi 1.1Gi 210Gi 208Gi Swap: 8.0Gi 0B 8.0Gi最容易踩的坑是看到free只剩 3.2Gi 就慌了觉得内存要爆了。实际上 Linux 会把空闲内存大量用作文件缓存buff/cache这部分内存随时可以回收给应用。真正该看的是available也就是在不触发 swap 的前提下还能给新进程用多少内存。上面这个例子里available有 208Gi机器其实很闲。buff/cache拆开看是两个不同的东西buffers是块设备元数据的缓存cached是文件内容的页缓存。绝大多数情况下cached占大头。如果你确实想手动释放比如做内存基准测试前需要干净环境可以sync echo 3 | sudo tee /proc/sys/vm/drop_caches但这只是把缓存丢掉重建纯粹为了测量准确日常千万别当优化手段用。shared那一列也要留意。它统计的是 tmpfs 和共享内存段占用的内存/dev/shm就在里面。数据库、Chromium 系浏览器、某些 JVM 应用都会用大量共享内存。如果你发现内存被吃掉但ps aux排序找不到大户去df -h /dev/shm看一眼。还有一个新手常问的问题我买了 32G 内存系统只认 31.2G 是不是被坑了。不一定。原因通常是集显显存共享核显会从物理内存里划走一块、内核保留区域、或者 DMI 中的保留段。想确认物理内存条的原始容量得靠dmidecode。3.2 dmidecode 看清内存条本身dmidecode读取的是主板 DMI/SMBIOS 表也就是主板固件里记录的硬件描述信息。它能告诉你物理内存条的单条容量、类型、频率、厂商、型号、序列号以及插在了哪个槽位。这是装机验货时最有用的一条命令# 先看整机内存阵列的总体信息最大支持容量、插槽总数 sudo dmidecode -t 16 # 再看每一根内存条的详细信息 sudo dmidecode -t 17一条健康的内存条信息大概长这样Memory Device Total Width: 72 bits Data Width: 64 bits Size: 32 GB Locator: DIMM_A1 Bank Locator: NODE 0 Type: DDR4 Speed: 3200 MT/s Manufacturer: Samsung Serial Number: 3xxxxxxx Part Number: M393A4K40DB3-CWE Rank: 2 Configured Memory Speed: 2933 MT/s Minimum Voltage: 1.2 V这里有三个点值得专门看槽位Locator。它告诉你这根条插在哪个物理插槽。如果你看到所有内存条都插在DIMM_A1、DIMM_A2这种同一通道的相邻槽位那很可能没组成双通道。正确的双通道插法是隔槽插比如 A1B1、A2B2具体要看主板手册。标称速度与配置速度的差异。上面例子里Speed是 3200 MT/s 但Configured Memory Speed只有 2933 MT/s。这说明内存条本身支持 3200但实际运行被降到了 2933。原因通常是 CPU 内存控制器上限、主板 BIOS 的内存频率设置、或者混插了不同频率的条子导致全部按最低的那条跑。这个差异对性能有实际影响值得追一下。Rank。单 Rank 和双 Rank或者四 Rank在同样的频率下带宽和延迟表现不同。大容量条子常常是双 Rank 或四 Rank单条带宽更高但时序可能略松。这个属于进阶话题装机时知道有这回事就够了。注意虚拟机里dmidecode返回的是虚拟化平台伪造的信息字段可能残缺或者根本不准比如显示最大支持容量 0。这种情况下不要拿它的输出做任何判断。另外dmidecode需要 root 权限因为它读的是原始固件表。3.3 通道、频率与带宽的粗略估算内存带宽的估算公式很简单带宽GB/s 传输速率MT/s × 位宽bit / 8 × 通道数单条 DDR4-3200 的位宽是 64 bit代入计算3200 × 64 / 8 25.6 GB/s。如果是双通道就是 51.2 GB/s四通道则是 102.4 GB/s。这个数字为什么重要因为它决定了你的内存敏感型任务的天花板。做 Spark 大数据处理、跑大内存 JVM 应用、用核显做推理、搞大规模矩阵运算这些场景经常是带宽受限而不是算力受限。同样是 32G 内存双通道和单通道能差出 30% 以上的实际性能。而free命令完全看不出通道数只能靠dmidecode -t 17里的槽位分布去推断。时序CL、tRCD、tRP、tRAS在dmidecode的标准输出里看不到需要主板支持并开启 XMP/EXPO 后在 BIOS 里查看或者用decode-dimms之类的工具需要加载eeprom内核模块。对绝大多数业务场景来说时序的收益远小于通道数装机时优先保证通道插满别在时序上纠结。4. GPU从卡在不在到能不能跑起来GPU 这块的查询需求层次非常分明可以分成三层硬件在不在、驱动通不通、版本配不配。三层依次推进不要跳步。很多人一上来就nvidia-smi报错然后开始瞎折腾驱动重装其实问题可能出在第一步——卡根本没被识别。4.1 第一层lspci 确认硬件在位lspci列出所有 PCI 设备不依赖任何显卡厂商驱动是最底层的检查手段# 列出所有显示相关设备 lspci | grep -Ei vga|3d|display # 更详细显示内核正在使用哪个驱动 sudo lspci -k | grep -A3 -Ei vga|3d|display # 用 lshw 看更结构化的信息 sudo lshw -C display输出类似01:00.0 VGA compatible controller: NVIDIA Corporation GA102 [GeForce RTX 3090] (rev a1) Subsystem: NVIDIA Corporation Device 1470 Kernel driver in use: nvidia Kernel modules: nvidiafb, nouveau, nvidia_drm, nvidia几个关键判断点卡的型号对不对。GA102 [GeForce RTX 3090]里的GA102是 NVIDIA 的核心代号比零售型号更难伪造。如果采购单写的是 A100 但这里显示 GA102那问题就大了。Kernel driver in use是什么。如果显示nouveau说明开源的 nouveau 驱动在占着卡专有驱动没有生效。这时候nvidia-smi大概率会报错或者找不到设备。如果显示nvidia说明专有驱动已经接管。如果这一行是空的说明卡还没被任何驱动绑定。设备有没有出现在多个 PCI 地址上。多卡机器上你会看到01:00.0、02:00.0、41:00.0这样的一串。如果数量比预期少可能是卡没插好、PCIe 供电不足、或者 BIOS 里某个插槽被禁用了。显示设备上还可能挂着音频控制器HDMI 音频比如01:00.1 Audio device: NVIDIA Corporation ...。这部分不用管但别把它当成第二张显卡数错了。4.2 第二层nvidia-smi 字段逐条读nvidia-smi是 NVIDIA 专有驱动自带的工具能正常工作本身就说明驱动装对了。默认输出长这样----------------------------------------------------------------------------- | NVIDIA-SMI 535.129.03 Driver Version: 535.129.03 CUDA Version: 12.2 | |--------------------------------------------------------------------------- | GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC | | Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. | || | 0 NVIDIA RTX 3090 Off | 00000000:01:00.0 Off | N/A | | 30% 38C P8 22W / 350W | 4MiB / 24576MiB | 0% Default | ---------------------------------------------------------------------------逐条看Driver Version是内核态驱动的版本CUDA Version是驱动支持的最高 CUDA 运行时版本不是你当前装的 CUDA Toolkit 版本。这两个概念经常被混。想知道实际装了什么版本得看nvcc --version或者python -c import torch; print(torch.version.cuda)。一个常见的误区是驱动显示 CUDA 12.2就以为一定要装 CUDA 12.2 的 PyTorch。实际上驱动向下兼容装 cu118 的 PyTorch 完全没问题。Temp 和 Fan。数据中心卡A100/H100的温度上限一般在 85 度左右超过会触发降频。消费卡可以到 90 度以上。如果满载时温度贴着上限说明风道有问题或者风扇策略太保守。Pwr:Usage/Cap。这一栏能看出实时功耗和功耗墙。如果 GPU 满载时功耗远低于 Cap可能是遇到了 CPU 瓶颈、显存瓶颈或者数据中心卡被设置了nvidia-smi -pl限功耗。Perf是一个性能状态标记P0 到 P12 加上 P8P0 是最高性能P8 是空闲。训练时如果一直停在 P5/P8说明任务根本没真正压上去。Memory-Usage显示已用显存和总显存。这里有件很重要的事显存被占用不代表进程还在跑。如果进程异常退出而没有正确释放显存可能处在僵死状态表现为nvidia-smi里看不到进程但显存被吃掉一大块。这种情况可以用nvidia-smi --gpu-reset -i 0重置会中断该卡上所有任务慎用。GPU-Util是采样周期内 GPU 有任务执行的时间占比。这个数字高不代表效率高——如果 kernel 很小、启动开销大利用率可以很高但吞吐很低。想批量抓结构化数据用 query 模式nvidia-smi --query-gpuindex,name,memory.total,memory.used,utilization.gpu,temperature.gpu,power.draw,compute_cap --formatcsv这个格式直接就是 CSV扔进 Excel 或者喂给监控系统都很方便。提示nvidia-smi -L只列出卡名适合写进巡检脚本的头部。nvidia-smi topo -m显示卡间互联拓扑多卡机器必看。nvidia-smi -q输出全量信息包括 ECC 错误计数、PCIe 链路宽度和速率排障时很有用。4.3 第三层算力与框架版本的匹配拿到显卡型号后最关键的一步是查它的Compute Capability计算能力也就是 SM 版本号。这个数字决定了 PyTorch、PaddlePaddle 等框架的预编译版本能不能直接跑。nvidia-smi --query-gpucompute_cap --formatcsv,noheader可以直接查到。常见的对应关系我整理成表显卡系列核心代号Compute Capability常见用途GTX 10 系GP104/GP1026.1入门实验RTX 20 系TU102/TU1047.5中等规模训练RTX 30 系GA102/GA1048.6主流训练推理RTX 40 系AD102/AD1038.9主流训练推理A100GA1008.0数据中心训练H100GH1009.0大模型训练这张表怎么用举个例子PyTorch 官方预编译包通常会为一个 CUDA 版本同时编译多个 SM 架构。如果你装的是老版本 PyTorch比如 1.12它可能只编到 sm_86那在 RTX 40 系sm_89上跑就会出现能跑但没优化或者直接报架构不支持的警告。同理装 PaddlePaddle 的 GPU 版本时也要注意它的预编译包覆盖了哪些架构。还有一个相关的概念叫CTACooperative Thread Array也就是 CUDA 里的线程块。这是编程模型层面的东西硬件查询阶段用不上但理解它有助于你解释为什么有些 kernel 在特定卡上跑不满——因为线程块的数量和大小受 SM 数量、每 SM 最大驻留块数的限制卡不同这些上限就不同。驱动版本与环境匹配的实操顺序我一般按这个流程走lspci确认卡在位记下型号和核心代号。nvidia-smi确认驱动正常记下驱动版本和支持的 CUDA 上限。nvidia-smi --query-gpucompute_cap拿到 SM 版本。去框架官网的版本对照表选一个 CUDA 版本不高于驱动支持上限、且覆盖了你的 SM 版本的预编译包。装完跑一句python -c import torch; print(torch.cuda.is_available(), torch.cuda.get_device_name(0))验证。这套流程走下来基本不会出现装完了才发现跑不起来的情况。4.4 多卡机器拓扑比数量更重要8 卡机器上卡和卡之间的通信路径差别巨大直接影响分布式训练的效率。nvidia-smi topo -m会输出一张矩阵GPU0 GPU1 GPU2 GPU3 CPU Affinity NUMA Affinity GPU0 X NV12 NV12 NV12 0-31 0 GPU1 NV12 X NV12 NV12 0-31 0 GPU2 NV12 NV12 X NV12 0-31 0 GPU3 NV12 NV12 NV12 X 0-31 0矩阵里的标记含义NV#表示通过 NVLink 连接#是链路数量数字越大带宽越高。PIX表示同一 PCIe 交换机下的两块卡。PHB表示经过 PCIe Host Bridge。SYS表示跨 NUMA 节点走的是 CPU 之间的互联总线最慢。X是自己和自己。为什么要看这个假设你要跑 4 卡数据并行训练如果卡之间全是SYS梯度同步会变成瓶颈加速比可能只有 2 倍出头。而同样是 4 卡如果都是NV4或以上加速比能接近线性。这时候解决方案是调整CUDA_VISIBLE_DEVICES的卡号组合把拓扑近的卡分到一组。另外注意CPU Affinity和NUMA Affinity两列。它们告诉你每张卡物理上挂在哪个 CPU 的 PCIe 通道下。做多卡训练时进程的数据加载线程最好绑到同一 NUMA 节点的 CPU 上否则会出现DMA 跨节点的额外开销。5. 硬盘与存储容量只是最不重要的一项硬盘这块的认知偏差可能是最大的。绝大多数人只关心df -h还剩多少空间而真正会导致事故的——健康度衰减、文件系统类型、inode 耗尽、被删除但仍被占用的文件——全都被忽略了。5.1 lsblk 一图看清设备拓扑lsblk是我最喜欢的磁盘命令它用树状结构展示块设备的层级关系一眼就能看出哪块盘分了哪些区、挂了什么文件系统、挂载在哪里lsblk -o NAME,SIZE,TYPE,FSTYPE,MOUNTPOINT,ROTA,MODEL输出NAME SIZE TYPE FSTYPE MOUNTPOINT ROTA MODEL nvme0n1 953.9G disk 0 SAMSUNG MZVL21T0HCLR-00B00 ├─nvme0n1p1 512M part vfat /boot/efi 0 ├─nvme0n1p2 928G part ext4 / 0 └─nvme0n1p3 25.4G part swap [SWAP] 0 sda 1.8T disk 1 WDC WD20EZBX-00AYRA0 └─sda1 1.8T part ext4 /data 1ROTA 字段是区分机械和固态的老办法ROTA1Rotational是机械盘0是固态。但这个方法不严谨因为 USB 移动硬盘、某些虚拟块设备也可能报 0。更准确的判断要看TRAN 字段lsblk -d -o NAME,ROTA,TRAN,SIZE,MODELTRAN会显示nvme、sata、usb、scsi之类的实际传输类型。这样你就能确认一块 M.2 盘到底走的是 NVMe 协议还是 SATA 协议——外观一样速度差三倍以上采购时被坑过的人应该深有体会。/dev/nvme0n1和/dev/sda的命名差异也值得记一下。NVMe 设备走的是独立的驱动栈命名规则是nvme控制器号n命名空间号分区再加p分区号。而 SATA/SAS 设备走 SCSI 子系统用sd字母加数字分区。所以你会看到nvme0n1p1和sda1这两种画风完全不同的写法。想更详细地看 NVMe 设备信息装个nvme-clisudo apt install nvme-cli -y sudo nvme list sudo nvme id-ctrl /dev/nvme0 -H | head -50nvme list会给出一张很清爽的表包含设备节点、SN、型号、固件版本、容量、已用百分比。其中**已用百分比Used**是 NVMe 自己报的健康度指标很直观。5.2 SMART健康度才是重点SMART 是硬盘自带的健康监测系统能提前预警故障。Ubuntu 上用它需要装smartmontoolssudo apt install smartmontools -y sudo smartctl -i /dev/sda # 设备基本信息 sudo smartctl -H /dev/sda # 健康状态总览 sudo smartctl -a /dev/sda # 全部属性机械盘和固态盘关注的属性完全不同我分开说。机械盘SATA关注这几项属性 ID名称关注点5Reallocated_Sector_Ct重映射扇区数任何非零增长都是危险信号187Reported_Uncorrect无法纠正的错误数应为 0197Current_Pending_Sector待重映射扇区非零说明有读不出来的扇区198Offline_Uncorrectable离线扫描发现的不可纠正错误199UDMA_CRC_Error_Count传输链路 CRC 错误通常是线材或接口问题对机械盘来说最危险的组合是5 和 197 同时非零且在增长。这意味着盘片上有物理坏道并且已经在扩散。从原理上讲硬盘写入数据时要先按磁道和扇区定位读回时校验一旦某个扇区的校验反复失败固件就会把它标记出来并尝试重映射到备用区。备用区是有限的用完了盘就彻底废了。所以看到这两项涨别犹豫立刻做全盘备份然后换盘。固态盘NVMe关注这几项Percentage Used: 12% Available Spare: 100% Available Spare Threshold: 10% Media and Data Integrity Errors: 0 Error Information Log Entries: 0 Temperature: 38 Celsius Power On Hours: 8,760 Data Units Written: 152,345,678 [78.0 TB]Percentage Used是厂商根据写入量估算的寿命消耗百分比注意这是估算值不是精确的剩余寿命。Available Spare是剩余备用块比例掉到 Threshold 以下就进入只读或者告警状态。Media and Data Integrity Errors理论上应该永远是 0一旦非零说明闪存颗粒层面出现了不可纠正错误这是最严重的信号。Data Units Written特别值得关注。固态盘的闪存颗粒有擦写次数上限TLC 通常 1000-3000 次 P/E换算成 TBW总写入字节数就是厂商标的寿命指标。1TB 的消费级 NVMe 一般标 600 TBW 左右企业级能到 1-3 PBW。如果你的盘一年就写了 78 TB按这个速度跑下去三四年就到寿命了。这就是为什么数据库、日志服务器、缓存节点上的盘要专门选高耐写型号。注意USB 硬盘盒和部分扩展卡不透传 SMART 命令smartctl -a会报 Unable to detect device type。这时候换台机器直连主板 SATA 口再测或者换支持 UASP 且透传 SMART 的硬盘盒。另外 RAID 控制器后面的盘需要-d megaraid,N之类的设备类型参数才能读到。5.3 容量、inode 与被删除文件df -h看容量df -i看 inode。这两个必须一起看因为**磁盘明明还有空间但就是写不进去**这个经典故障八成是 inode 用尽了。inode 是小文件系统里为每个文件分配的元数据结构数量在格式化时就定死了。如果你的应用会产生海量小文件比如邮件队列、缓存目录、会话文件inode 会先于空间耗尽。df -h # 看块空间 df -i # 看 inode 使用率 du -sh /* 2/dev/null | sort -h # 从根开始找占用大户 du -sh /var/* | sort -h # 逐层下钻还有一个更隐蔽的情况df显示已用和du算出来的总和对不上。典型场景是某个进程正在写一个大日志文件你rm掉了它但进程还持有文件句柄内核就不会真正回收这块空间。表现就是磁盘满了但怎么找都找不到那个文件。排查命令# 找出所有被删除但仍被进程占用的文件 sudo lsof L1 # 或者用 lsof 过滤 deleted 标记 sudo lsof | grep deleted | head -20找到对应的 PID 后重启那个进程或者用 /proc/pid/fd/fd把文件清空注意是清空不是删除。这个坑我在日志服务上踩过一次深夜磁盘告警找了一个多小时才发现是一个没配好日志轮转的服务。顺带说一下分区规划。1T 的盘怎么分我的习惯是EFI 分区 512M或 1G、根分区 100-200G、剩余全部给数据分区单独挂载。根分区太大的坏处是系统盘和业务盘混在一起做快照、做备份、做迁移都不方便太小的坏处是/var里的日志、Docker 镜像、包缓存容易把它撑爆。现在主流的做法其实是不给/home单独分区而是给业务数据一个独立挂载点系统盘的容量问题交给日志轮转和容器存储清理来解决。6. 打包成脚本一次采集到处交差零散敲命令适合现场排查但如果你经常要给不同机器做体检或者需要把机器的硬件信息存档、发给采购、贴给同事做对比手动敲就太低效了。写一个巡检脚本跑一次生成一份完整报告后面省下的是几十次重复劳动。6.1 脚本设计上的几个取舍写这类脚本我有几个固定原则先说清楚理由输出到文件而不是只打印到屏幕。SSH 会话断掉、终端滚动条冲掉、需要发给别人——这三种情况都会让你后悔没存文件。默认按主机名_时间戳命名天然带版本。每一条命令都容错。不要在脚本开头写set -e一条命令失败就整体退出那你拿到的是半份报告。正确的做法是让每条命令独立执行失败就打印一行提示继续往下走。所以我用的组合是set -uo pipefail而不加-e。区分需要 root 和不需要 root 的部分。dmidecode、smartctl、nvme都要 root但lscpu、free、lsblk、nvidia-smi不要。如果脚本一上来就要求 root很多人的日常使用场景就被劝退了。我的做法是自动检测如果是 root 就采全量不是 root 就跳过需要权限的部分并显式标注未采集。统一 locale。不同机器的语言环境不一样df输出的表头和错误信息可能是中文脚本解析就会出问题。在脚本开头设置export LC_ALLC能规避这一整类问题。GPU 部分要能优雅降级。没装 NVIDIA 驱动的机器上nvidia-smi会报 command not found脚本不应该因此出错直接写一句未检测到 nvidia-smi就行。6.2 完整脚本下面这个脚本我用了几年改过好几版可以直接抄#!/usr/bin/env bash # hwreport.sh - Ubuntu 硬件信息一键采集 # 用法: bash hwreport.sh [输出文件路径] set -uo pipefail export LC_ALLC HOST$(hostname) OUT${1:-hwreport_${HOST}_$(date %Y%m%d_%H%M%S).txt} IS_ROOT0 [ $(id -u) -eq 0 ] IS_ROOT1 sec() { printf \n\n %s \n $1 $OUT; } run() { $ $OUT 21 || echo [命令失败: $*] $OUT; } need_root() { [ $IS_ROOT -eq 1 ] || echo [需要 root已跳过] $OUT; } : $OUT echo 硬件巡检报告 主机: ${HOST} 时间: $(date %F %T) 用户: $(id -un) $OUT sec 0. 系统概况 run uname -a run cat /etc/os-release run uptime sec 1. CPU run lscpu { echo --- 指令集关键项 --- grep -m1 ^flags /proc/cpuinfo | tr \n \ | grep -E ^(avx|avx2|avx512f|fma|sse4_2)$ | sort -u } $OUT 21 sec 2. 内存 run free -h if [ $IS_ROOT -eq 1 ]; then run dmidecode -t 16 run dmidecode -t 17 else need_root fi run numactl --hardware sec 3. GPU if command -v nvidia-smi /dev/null 21; then run nvidia-smi run nvidia-smi --query-gpuindex,name,memory.total,memory.used,utilization.gpu,temperature.gpu,power.draw,compute_cap --formatcsv run nvidia-smi topo -m else echo 未检测到 nvidia-smi跳过 NVIDIA GPU 信息 $OUT fi run bash -c lspci | grep -Ei vga|3d|display sec 4. 存储设备 run lsblk -o NAME,SIZE,TYPE,FSTYPE,MOUNTPOINT,ROTA,TRAN,MODEL run bash -c df -hT | grep -v tmpfs run bash -c df -i | grep -v tmpfs if [ $IS_ROOT -eq 1 ]; then command -v smartctl /dev/null 21 \ for d in $(lsblk -dpno NAME | grep -E /dev/(sd|nvme)); do echo --- SMART: $d --- $OUT smartctl -H -A $d $OUT 21 done command -v nvme /dev/null 21 run nvme list else need_root fi sec 5. 网络 run bash -c ip -br addr run bash -c ip -br link sec 6. 内核模块与驱动 run bash -c lsmod | grep -E nvidia|nvme|megaraid|mpt3sas echo 报告已生成: $OUT6.3 输出解读与归档脚本跑完后会得到一个文本文件。我的习惯是把它连同机器编号一起存进一份内部文档按时间倒序排列。这样做的价值在于趋势对比硬盘的Percentage Used三个月涨了多少、内存有没有被人偷偷拔走一条、GPU 温度在夏天是不是明显更高——这些问题只有和历史快照对比才看得出来。如果是给采购或者供应商核对配置我会用diff把到货机器的报告和配置单逐项过一遍重点看dmidecode -t 17里的型号、容量、数量和槽位。别看这一步枯燥我见过内存条型号被换、固态被换成低耐写型号的情况都是在这一步发现的。7. 常见问题与排查技巧实录前面讲了正常路径这一节讲不正常路径。下面这些是我在实际操作中反复遇到的坑。7.1 速查表现象可能原因排查方向nvidia-smi: command not found专有驱动未安装lspci -k看驱动是否为 nouveau装ubuntu-driversnvidia-smi报 No devices were found驱动与内核模块不匹配 / Secure Boot 阻止加载dmesgfree显示内存比标称少几个 G核显共享显存、内核保留段dmidecode -t 17核对物理条容量dmidecode报 No SMBIOS 或数据异常虚拟机环境 / 权限不足物理机加 sudo 重试虚拟机直接放弃smartctl报 Unable to detect device typeUSB 硬盘盒不透传 SMART换直连 SATA/NVMe 接口测试磁盘有空间但写入失败inode 耗尽df -i检查du找小文件目录df与du结果对不上被删除但仍被占用的文件lsof L1重启持有句柄的进程容器里lscpu显示几十核读的是宿主机信息查/sys/fs/cgroup/cpu.max确认配额内存占用高但找不到进程buff/cache 或共享内存看free -h的 available检查/dev/shmGPU 利用率高但吞吐低kernel 太小或数据加载瓶颈看功耗是否贴近 Cap检查 CPU 与 IO7.2 几条用血换来的经验第一条所有硬件信息的判断都要有基准没有基准就没有结论。内存 2933 MT/s这个数字本身说明不了任何问题只有和内存条标称值、CPU 支持上限、同批机器对比之后才有意义。所以我在接手新机器时第一件事就是采一份完整快照存在仓库里后面所有异常都拿它做参照。第二条不要相信单次采样。GPU 利用率、CPU 频率、温度这些指标都是瞬时值你nvidia-smi看到 0% 不代表卡闲可能只是刚好在两次采样之间。排查性能问题至少要连续观察几分钟。我一般用nvidia-smi --query-gpu... --formatcsv -l 2每两秒刷一次或者直接watch -n 2配合。第三条SSH 到别人的机器前先问清楚能不能提权。很多只读信息lscpu、free、lsblk不需要 root但dmidecode、smartctl、nvme都需要。如果对方只给你普通账号你拿到的报告会缺一半。提前问清楚别到现场才发现权限不够。第四条把巡检脚本加入开机自启或者定时任务。硬盘故障、内存条掉线这类问题往往是渐进式的。与其等到服务崩了再去查不如每天凌晨自动采一份用脚本对关键字段做阈值判断——Percentage Used超过 80%、Reallocated_Sector_Ct大于 0、Available Spare低于阈值任何一个触发就告警。这个成本很低收益极高。第五条报告要能一眼看出重点。前几版脚本我是把所有命令的原始输出一股脑塞进文件结果一页一页全是lspci的几百行内容。后来我把命令重新排了序把最关键的信息核数、内存总容量、GPU 型号与算力、磁盘健康状态放在脚本最后单独做一个小结区块。这样别人拿到报告只看最后一段就知道机器什么水平。最后再分享一个我自己常用的小技巧把hwreport.sh放到 U 盘里加上chmod x装机现场不需要任何依赖就能跑。脚本里所有工具lscpu、free、lsblk、lspci都是 Ubuntu 基础系统自带的只有smartmontools、nvme-cli、numactl需要额外装而且脚本对这些缺失工具都做了容错处理不会因为少一个包就跑不下去。实测在一台刚装好的最小化 Ubuntu 上这份报告能有 90% 的采集完整度剩下 10% 装完包补采一次就够了。
返回列表