ARTICLE DETAIL

资讯详情

深耕商务建站与企业官网运营的一线实战洞察。

GPFS排故日志收集全攻略:从故障场景到自动化脚本

GPFS排故日志收集全攻略:从故障场景到自动化脚本 1. 为什么GPFS排故日志收集值得单独拎出来讲做过HPC存储运维的人都有一个共识GPFS现称IBM Storage Scale但圈内人还是习惯叫GPFS出问题的时候最怕的不是故障本身而是故障现场被破坏、日志收集不全、事后复盘时发现关键信息缺失。我见过太多次这样的情况——集群突然出现IO hang管理员第一反应是重启节点结果重启完一切恢复正常但根因永远找不到了。下一次故障再来还是抓瞎。GPFS作为一套分布式并行文件系统它的日志来源非常分散有内核态的、有用户态的、有管理节点的、有计算节点的、有IB/RoCE网络层的、有存储后端RAID控制器的。不同层面的日志格式、存放路径、收集方式都不一样。如果没有一套标准化的收集流程排故时就会陷入知道要看什么但找不到在哪的窘境。这篇内容要解决的核心问题就一个当GPFS集群出现各类异常时如何系统化、标准化、无遗漏地收集排故所需的全部日志。适合谁来参考一线存储运维工程师、HPC集群管理员、以及需要对接厂商支持但不想被反复要求再抓一次日志的同行。我会把常见的故障场景分类针对每类场景给出具体的日志收集清单、命令、路径和注意事项让你在故障现场能像执行checklist一样操作不慌不乱。2. GPFS日志体系的全景拆解2.1 日志的三大来源层次GPFS的日志不是集中在一个目录里的它横跨了三个层次每个层次的日志解决不同维度的问题。第一层是GPFS自身的日志。这包括/var/adm/ras/目录下的mmfs.log系列、/var/mmfs/下的各种状态文件、以及通过mmfsadm dump系列命令动态抓取的运行时信息。这一层直接反映GPFS文件系统本身的行为——inode分配、锁管理、token管理、磁盘租约、配额等。第二层是操作系统层面的日志。GPFS深度依赖内核模块mmfs、mmfslinux、tracedev等所以dmesg、/var/log/messages或/var/log/syslog、journalctl的输出至关重要。很多GPFS的panic、hung task、OOM都和内核态有关。第三层是硬件与网络层的日志。包括IB交换机的性能计数器、网卡的统计信息、RAID控制器的事件日志、SAN交换机的zone配置和错误计数。这一层往往被忽略但实际排故中有相当比例的GPFS故障最终定位到网络丢包或存储链路抖动。注意三层日志的收集顺序有讲究。建议先抓第一层和第二层的瞬时状态因为可能被覆盖或丢失再从容收集第三层的硬件日志。2.2 关键日志文件与目录速查下面这张表是我自己整理并反复使用的速查表建议收藏日志/目录路径内容说明适用场景/var/adm/ras/mmfs.log.latest当前GPFS主日志所有GPFS异常/var/adm/ras/mmfs.log.previous上一次轮转的日志故障后节点被重启/var/adm/ras/mmsysmonitor.log系统监控日志节点状态异常/var/adm/ras/mmfsadm.log管理命令执行记录追溯谁做了什么操作/var/mmfs/gen/mmsdrfs集群配置描述文件配置比对/var/mmfs/gen/mmfsdb集群数据库快照集群元数据恢复/tmp/mmfs/临时dump文件动态抓取的诊断数据/var/log/messages系统综合日志内核态异常dmesg输出内核环形缓冲区OOM、hung task、驱动报错2.3 日志轮转机制与收集时机GPFS的mmfs.log.latest默认在达到一定大小后会轮转为mmfs.log.previous旧的previous会被覆盖。这意味着如果你不及时收集关键证据可能在几小时内就消失了。我踩过最惨的一次坑是一个客户集群在凌晨3点出现IO超时管理员早上9点才通知我等我连上去的时候mmfs.log.latest已经被后续的正常日志冲刷得面目全非previous里也只有部分残留。所以我的原则是故障确认后的第一件事不是分析而是保全现场。具体做法是立即把所有相关节点的/var/adm/ras/目录整体打包复制到一个安全位置再慢慢分析。3. 按故障场景分类的日志收集实操3.1 场景一集群无法挂载或文件系统mount失败这是最常见的入门级故障但排查起来涉及的面并不少。当mmmount或mount命令失败时你需要按以下顺序收集第一步确认集群状态。在所有节点上执行mmgetstate -a把输出完整保存。如果节点状态是down或arbitrating说明集群层面就有问题。第二步抓取核心日志。在管理节点和问题节点上分别执行# 打包GPFS核心日志 tar czf /tmp/gpfs_logs_$(hostname)_$(date %Y%m%d%H%M).tar.gz \ /var/adm/ras/mmfs.log.latest \ /var/adm/ras/mmfs.log.previous \ /var/adm/ras/mmsysmonitor.log \ /var/adm/ras/mmfsadm.log # 抓取集群配置 mmfsadm dump config /tmp/mmfs_dump_config_$(hostname).txt mmlscluster /tmp/mmlscluster_$(hostname).txt mmlsconfig /tmp/mmlsconfig_$(hostname).txt第三步检查内核日志。执行dmesg | grep -i mmfs重点看有没有mmfs:开头的错误信息。常见的如mmfs: Failed to load module、mmfs: cannot allocate memory等。第四步检查文件系统描述文件。/var/mmfs/gen/mmsdrfs是集群的宪法如果这个文件损坏或版本不一致mount必然失败。收集时务必保留。实操心得mount失败时很多人会反复尝试mount命令这是大忌。每次失败的mount尝试都会在日志中产生新的记录可能覆盖掉第一次失败时的关键信息。正确做法是失败一次后立即停止收集完日志再分析。3.2 场景二IO性能骤降或hang住这类问题最棘手因为集群可能看起来正常——节点状态up文件系统mount着但应用就是读写不动。这时候日志收集要覆盖性能和阻塞两个维度。GPFS层面的收集# 抓取当前所有GPFS线程栈 mmfsadm dump threads /tmp/mmfs_threads_$(hostname)_$(date %s).txt # 抓取等待队列信息 mmfsadm dump waiters /tmp/mmfs_waiters_$(hostname)_$(date %s).txt # 抓取锁和token状态 mmfsadm dump locks /tmp/mmfs_locks_$(hostname)_$(date %s).txt mmfsadm dump tokens /tmp/mmfs_tokens_$(hostname)_$(date %s).txt这几个dump命令抓取的是瞬时快照建议间隔30秒连续抓3次这样可以看出等待队列是在增长还是在消化。操作系统层面的收集# 进程状态 ps -eLf /tmp/ps_elf_$(hostname).txt # IO统计 iostat -x 1 5 /tmp/iostat_$(hostname).txt cat /proc/diskstats /tmp/diskstats_$(hostname).txt # 网络统计 netstat -s /tmp/netstat_s_$(hostname).txt ip -s link /tmp/ip_link_$(hostname).txt网络层的收集如果用了IB或RoCE# IB性能计数器 perfquery /tmp/perfquery_$(hostname).txt ibstat /tmp/ibstat_$(hostname).txt # RoCE统计 ethtool -S roce_interface /tmp/ethtool_roce_$(hostname).txt注意mmfsadm dump threads的输出可能非常大几千行但这是定位IO hang最关键的证据。它能告诉你GPFS的内核线程卡在哪个函数上——是在等锁、等磁盘、还是等网络。3.3 场景三节点意外宕机或panic节点宕机后如果配置了kdump第一优先级是拿到vmcore。如果没有kdump那就只能靠日志回溯。宕机前的日志保全# 从其他正常节点收集宕机节点的最后状态 mmgetstate -a /tmp/mmgetstate_all.txt mmdiag --node 宕机节点名 /tmp/mmdiag_node.txt # 检查是否有core dump ls -la /var/crash/ 2/dev/null ls -la /var/adm/ras/ | grep -i coreGPFS的crash日志GPFS自身也有crash log机制通常在/var/adm/ras/下会有mmfs.core.*或mmfs.crash.*文件。这些文件需要用mmfsadm工具解析mmfsadm dump core /var/adm/ras/mmfs.core.xxxxx /tmp/mmfs_core_analysis.txt系统层面的回溯# 最后一次启动的日志 journalctl -b -1 /tmp/journalctl_prev_boot.txt # 如果有kdump ls -la /var/crash/*/vmcore实操心得节点panic后如果集群配置了自动重启节点可能在几分钟内就重新加入了集群。这时候mmfs.log.latest会被新的启动日志覆盖。所以必须在节点重启完成前从其他节点远程抓取该节点的日志或者确保日志是集中收集的。3.4 场景四磁盘或存储子系统报错GPFS底层依赖NSDNetwork Shared DiskNSD又依赖本地磁盘或SAN LUN。当磁盘出现坏道、RAID降级、或SAN链路抖动时GPFS层面会报disk error或NSD server unavailable。GPFS层面的收集# NSD状态 mmlsnsd -X /tmp/mmlsnsd_X.txt mmfsadm dump nsd /tmp/mmfs_nsd_dump.txt # 磁盘错误统计 mmdiag --disk /tmp/mmdiag_disk.txt存储层面的收集# 本地磁盘SMART信息 smartctl -a /dev/sdX /tmp/smartctl_sdX.txt # RAID控制器日志以常见的MegaRAID为例 storcli /c0 show events /tmp/storcli_events.txt storcli /c0 /eall /sall show /tmp/storcli_drives.txt # SAN HBA统计 systool -c fc_host -v /tmp/fc_host_stats.txt多路径状态multipath -ll /tmp/multipath_ll.txt注意存储层的日志收集往往需要额外的工具storcli、sas3ircu、smartctl等建议在集群部署阶段就把这些工具装好别等故障了才发现没有。4. 日志收集的自动化与标准化4.1 为什么需要自动化手动收集的问题很明显故障时人手忙脚乱、容易遗漏、不同人收集的内容不一致、厂商支持要反复催。我经历过最夸张的一次一个IO性能问题来回折腾了两周就是因为每次收集的日志都不完整厂商支持每次看完都说还缺XXX。后来我写了一个脚本把常见故障场景的日志收集全部自动化。效果立竿见影——第一次提交就给全了厂商支持的响应速度直接快了一倍。4.2 脚本设计的核心思路脚本的设计原则是分层收集、场景可选、输出规范。具体来说分层GPFS层、OS层、网络层、存储层分开收集每层一个子目录场景可选通过参数指定故障类型mount/io/panic/disk脚本自动决定收集哪些内容输出规范统一打包成gpfs_diag_hostname_timestamp.tar.gz方便传输和归档下面是一个简化版的核心框架#!/bin/bash # gpfs_log_collector.sh # 用法: ./gpfs_log_collector.sh 场景 输出目录 # 场景: mount | io | panic | disk | all SCENARIO${1:-all} OUTDIR${2:-/tmp/gpfs_diag_$(hostname)_$(date %Y%m%d%H%M%S)} HOSTNAME$(hostname) mkdir -p ${OUTDIR}/{gpfs,os,network,storage} collect_gpfs() { echo [*] Collecting GPFS logs... cp /var/adm/ras/mmfs.log.latest ${OUTDIR}/gpfs/ 2/dev/null cp /var/adm/ras/mmfs.log.previous ${OUTDIR}/gpfs/ 2/dev/null cp /var/adm/ras/mmsysmonitor.log ${OUTDIR}/gpfs/ 2/dev/null cp /var/adm/ras/mmfsadm.log ${OUTDIR}/gpfs/ 2/dev/null mmfsadm dump config ${OUTDIR}/gpfs/dump_config.txt 21 mmgetstate -a ${OUTDIR}/gpfs/mmgetstate.txt 21 mmlscluster ${OUTDIR}/gpfs/mmlscluster.txt 21 mmlsconfig ${OUTDIR}/gpfs/mmlsconfig.txt 21 mmlsnsd -X ${OUTDIR}/gpfs/mmlsnsd.txt 21 } collect_os() { echo [*] Collecting OS logs... dmesg ${OUTDIR}/os/dmesg.txt 21 cp /var/log/messages ${OUTDIR}/os/ 2/dev/null journalctl -b ${OUTDIR}/os/journalctl_current.txt 21 ps -eLf ${OUTDIR}/os/ps_elf.txt 21 cat /proc/meminfo ${OUTDIR}/os/meminfo.txt 21 cat /proc/loadavg ${OUTDIR}/os/loadavg.txt 21 } collect_network() { echo [*] Collecting network logs... ip -s link ${OUTDIR}/network/ip_link.txt 21 netstat -s ${OUTDIR}/network/netstat_s.txt 21 if command -v ibstat /dev/null; then ibstat ${OUTDIR}/network/ibstat.txt 21 perfquery ${OUTDIR}/network/perfquery.txt 21 fi } collect_storage() { echo [*] Collecting storage logs... cat /proc/diskstats ${OUTDIR}/storage/diskstats.txt 21 multipath -ll ${OUTDIR}/storage/multipath.txt 21 if command -v smartctl /dev/null; then for disk in /dev/sd[a-z]; do smartctl -a ${disk} ${OUTDIR}/storage/smartctl_$(basename ${disk}).txt 21 done fi } # 按场景执行 case ${SCENARIO} in mount) collect_gpfs; collect_os ;; io) collect_gpfs; collect_os; collect_network ;; panic) collect_gpfs; collect_os ;; disk) collect_gpfs; collect_storage ;; all) collect_gpfs; collect_os; collect_network; collect_storage ;; *) echo Unknown scenario: ${SCENARIO}; exit 1 ;; esac # 打包 cd /tmp tar czf ${OUTDIR}.tar.gz $(basename ${OUTDIR}) echo [] Done. Output: ${OUTDIR}.tar.gz4.3 脚本使用的注意事项这个脚本看起来简单但有几个坑我踩过第一权限问题。很多GPFS的dump命令需要root权限脚本必须以root运行。但有些集群禁止root直接登录这时候需要用sudo并且确保sudoers配置允许执行这些命令。第二命令不存在的情况。不是所有节点都装了smartctl、storcli、perfquery这些工具。脚本里用command -v做了检查但实际使用中建议在集群部署阶段就统一安装。第三输出目录的空间。dmesg和journalctl的输出可能很大如果/tmp空间不足会失败。建议输出到有足够空间的分区或者加一个空间检查。第四时间戳的精度。多个节点同时收集时时间戳精度到秒就够了。但如果要做跨节点的时间线关联分析建议用date %s.%N精确到纳秒。实操心得脚本写好后别等到故障了才第一次运行。建议在测试环境模拟各种故障场景验证脚本能正常收集。我见过太多故障时脚本跑不起来的情况原因五花八门——路径不对、权限不够、命令缺失。5. 常见问题与排查技巧实录5.1 日志收集过程中的典型问题问题一mmfsadm dump命令hang住不返回这种情况通常说明GPFS内核模块本身已经处于异常状态。解决办法是加超时timeout 30 mmfsadm dump threads /tmp/threads.txt 21如果30秒还没返回说明dump机制本身被阻塞了这时候只能靠dmesg和/proc下的信息。问题二日志文件太大传输困难mmfs.log.latest在繁忙集群上可能达到几百MB甚至GB级别。传输前建议先压缩并且只保留故障时间窗口附近的内容# 提取最近2小时的日志 awk -v start$(date -d 2 hours ago %Y-%m-%d %H:%M) $0 start mmfs.log.latest mmfs_recent.log问题三多节点日志时间不同步这是分布式系统排故的经典问题。如果各节点NTP没同步日志时间戳对不上根本无法做因果分析。收集日志的同时务必收集各节点的时间状态timedatectl /tmp/timedatectl_$(hostname).txt ntpq -p /tmp/ntpq_$(hostname).txt问题四厂商支持要求再抓一次这通常是因为第一次收集的日志不完整或格式不对。为了避免反复建议在提交前自己先检查一遍GPFS日志有没有、dmesg有没有、时间窗口对不对、有没有压缩包密码保护。我一般会附一个README说明收集了什么、故障现象是什么、时间点是什么。5.2 日志分析的核心思路收集只是第一步分析才是重头戏。我的分析顺序通常是先看时间线从mmfs.log.latest中找到第一个ERROR或FATAL出现的时间点再看关联在那个时间点前后dmesg里有没有对应的内核报错然后看状态mmfsadm dump的输出里线程栈、等待队列、锁状态是否异常最后看硬件如果前面都正常再查网络和存储层的计数器这个顺序的逻辑是从软件到硬件、从高层到低层。因为大部分问题在GPFS层面就能定位不需要一上来就查硬件。5.3 常见错误信息速查表错误信息可能原因进一步排查方向mmfs: Disk error on NSD xxx磁盘故障或链路抖动查smartctl、multipath、SAN日志mmfs: Token conflict detected集群分裂或网络分区查网络连通性、mmfs.log中的token记录mmfs: Inode allocation failedinode耗尽或元数据损坏查mmlsinode、文件系统使用率mmfs: Quota exceeded配额超限查mmlsquota、用户配额设置mmfs: Failed to mount配置不一致或日志损坏查mmsdrfs、mmfs.log.latesthung taskin dmesg内核线程阻塞查mmfsadm dump threadsOOM killerin dmesg内存不足查GPFS pagepool配置、系统内存注意这张表只是快速索引实际排故中错误信息往往更复杂需要结合上下文。比如Token conflict可能是网络问题也可能是节点时钟不同步导致的。6. 日志收集的长期策略与经验沉淀6.1 建立集中式日志归档单次故障的日志收集是战术建立长期的日志归档机制才是战略。我的建议是在集群里部署一个集中式的日志收集服务所有节点的GPFS日志、系统日志实时或定时推送到一个中心存储。这样即使节点宕机、日志被覆盖中心存储里还有备份。实现方式可以很简单用rsyslog或syslog-ng把/var/log/messages转发到中心用cron定时打包/var/adm/ras/目录。复杂一点可以用ELK或类似方案做结构化存储和检索。6.2 定期做日志健康检查就像定期体检一样日志系统也需要定期检查。我一般每个月做一次检查各节点的/var/adm/ras/目录空间是否充足检查日志轮转是否正常检查集中收集服务是否在运行抽查几个节点的日志时间戳是否同步这些检查花不了多少时间但能在关键时刻救命。6.3 把排故经验固化成文档每次排故结束后我都会花半小时写一个简短的复盘记录故障现象、收集了哪些日志、最终根因是什么、下次遇到类似问题应该先看什么。这些记录积累起来就是团队最宝贵的知识库。我个人的体会是GPFS排故这件事工具和脚本只占30%经验和思路占70%。同样一份日志新手可能看不出问题老手一眼就能定位。而这个眼力就是靠一次次实战和复盘练出来的。所以别嫌麻烦每次故障都认真收集、认真分析、认真记录半年下来你就会发现自己排故的速度和准确率有质的飞跃。最后分享一个小技巧在集群的每个节点上放一份排故日志收集checklist的打印版贴在机柜上。故障时不用想照着清单一项项做就行。这个习惯帮我避免了很多次事后才发现漏了关键日志的尴尬。
返回列表
PREV
查看更多资讯
NEXT
返回资讯列表