free_top_df的使用

本文详细介绍了如何使用free、top、df等命令来查看Linux系统的内存使用情况、CPU状态、磁盘空间分配,以及如何理解meminfo文件的内容。通过实例展示了如何获取内存总量、可用内存、缓存内存等关键信息,并利用top命令实时监控进程占用资源,最后介绍了df命令用于检查磁盘分区使用情况。
1. free: 查看内存
这个系统用的是2块HY57561620 (32MB X 2 = 64)
[root@FriendlyARM /]# free  
              total         used         free       shared      buffers
  Mem:        61304         7352        53952            0            0
 Swap:            0            0            0
Total:        61304         7352        53952
可看出 mem 的使用情况
看内存额定值: cat /proc/meminfo
[root@FriendlyARM /]# cat /proc/meminfo
MemTotal:        61304 kB
MemFree:         53868 kB
Buffers:             0 kB
Cached:           3684 kB
SwapCached:          0 kB
Active:           1688 kB
Inactive:         2444 kB
HighTotal:           0 kB
HighFree:            0 kB
LowTotal:        61304 kB
LowFree:         53868 kB
SwapTotal:           0 kB
SwapFree:            0 kB
Dirty:               0 kB
Writeback:           0 kB
Mapped:           1644 kB
Slab:             2516 kB
CommitLimit:     30652 kB
Committed_AS:     3992 kB
PageTables:         80 kB
VmallocTotal:   450560 kB
VmallocUsed:      4244 kB
VmallocChunk:   444408 kB

2.  top: 查看运行中的CPU 和内存及进程情况
[root@FriendlyARM /]# top      
Mem: 7436K used, 53868K free, 0K shrd, 0K buff, 3684K cached
Load average: 0.07 0.02 0.00  (Status: S=sleeping R=running, W=waiting)
  PID USER     STATUS   RSS  PPID %CPU %MEM COMMAND
  318 root     R        680   309  1.9  1.1 top
  309 root     S        800     1  0.0  1.2 sh
  260 root     S        700     1  0.0  1.1 inetd
  272 root     S        648     1  0.0  1.0 boa
    1 root     S        292     0  0.0  0.4 init
  283 root     S        280     1  0.0  0.4 led-player
  231 root     SW<        0     5  0.0  0.0 kmmcd
    4 root     SW<        0     1  0.0  0.0 khelper
  200 root     SW         0     1  0.0  0.0 mtdblockd
    2 root     SWN        0     1  0.0  0.0 ksoftirqd/0
    3 root     SW<        0     1  0.0  0.0 events/0
    5 root     SW<        0     1  0.0  0.0 kthread
   23 root     SW<        0     5  0.0  0.0 kblockd/0
   25 root     SW<        0     5  0.0  0.0 khubd
   38 root     SW         0     1  0.0  0.0 kapmd
   72 root     SW         0     5  0.0  0.0 pdflush
   73 root     SW         0     5  0.0  0.0 pdflush
   75 root     SW<        0     5  0.0  0.0 aio/0
   74 root     SW         0     1  0.0  0.0 kswapd0
  149 root     SW<        0     5  0.0  0.0 kseriod

也可以 top -d 1  //一秒钟刷新一次
 
3. df :查看各磁盘使用情况
[root@FriendlyARM /]# df
Filesystem           1k-blocks      Used Available Use% Mounted on
/dev/root                63152     56372      6780  89% /
none                     30652         0     30652   0% /tmp
none                     30652         4     30648   0% /var
也可以:
[root@FriendlyARM /]# df -h
Filesystem                Size      Used Available Use% Mounted on
/dev/root                61.7M     55.1M      6.6M  89% /
none                     29.9M         0     29.9M   0% /tmp
none                     29.9M      4.0k     29.9M   0% /var
我用的是一块K9F1208UOC 的nandflash(512Mb = 64MB) ,怎么会出来这么多分区? 不明白。。。



import re import pandas as pd import matplotlib.pyplot as plt def parse_filtered_log(filtered_file_path): """解析过滤后的top日志文件""" data = { 'time_sec': [], 'mem_used_mb': [], 'mem_free_mb': [], 'cpu_usr': [], 'cpu_sys': [], 'load_avg_1min': [], 'load_avg_5min': [], 'load_avg_15min': [], 'nvrcore_cpu': [], 'nvrcore_mem': [], 'onvif_cpu': [], 'onvif_mem': [] } with open(filtered_file_path, 'r', encoding='utf-8') as f: lines = f.readlines() time_counter = 0 current_block = [] for line in lines: line = line.strip() if not line: continue if line.startswith('Mem:'): if current_block: nvrcore_cpu = 0.0 nvrcore_mem = 0.0 onvif_cpu = 0.0 onvif_mem = 0.0 for bline in current_block: parts = bline.split() if len(parts) >= 8: # 确保有足够多的列 # 提取进程名(合并可能被分割的部分) cmd = ' '.join(parts[7:]) # 处理nvrcoreM进程 if 'nvrcoreM' in cmd: try: nvrcore_cpu = float(parts[7]) # %CPU是第6列(索引5) mem_str = parts[4] # 如 '134m' nvrcore_mem = float(mem_str.replace('m', ''))*1024 # 转换为 134.0 except (IndexError, ValueError): pass # 处理onvif进程(排除discovery) elif './onvif' in cmd and 'discovery' not in cmd: try: onvif_cpu = float(parts[7]) # %CPU是第6列(索引5) onvif_mem = float(parts[4])/1024.0 # %MEM是第7列(索引6) except (IndexError, ValueError): pass data['nvrcore_cpu'].append(nvrcore_cpu) data['nvrcore_mem'].append(nvrcore_mem) data['onvif_cpu'].append(onvif_cpu) data['onvif_mem'].append(onvif_mem) current_block = [] mem_match = re.match(r'Mem:\s*(\d+)K used,\s*(\d+)K free', line) if mem_match: # data['mem_used_mb'].append(int(mem_match.group(1)) / 1024) # data['mem_free_mb'].append(int(mem_match.group(2)) / 1024) data['mem_used_mb'].append(int(mem_match.group(1)) ) data['mem_free_mb'].append(int(mem_match.group(2))) data['time_sec'].append(time_counter) time_counter += 5 current_block.append(line) if line.startswith('CPU:'): cpu_match = re.match(r'CPU:\s*([\d.]+)% usr\s+([\d.]+)% sys', line) if cpu_match: data['cpu_usr'].append(float(cpu_match.group(1))) data['cpu_sys'].append(float(cpu_match.group(2))) if line.startswith('Load average:'): load_match = re.match(r'Load average:\s*([\d.]+)\s+([\d.]+)\s+([\d.]+)', line) if load_match: data['load_avg_1min'].append(float(load_match.group(1))) data['load_avg_5min'].append(float(load_match.group(2))) data['load_avg_15min'].append(float(load_match.group(3))) max_len = len(data['time_sec']) for key in data: if len(data[key]) < max_len: data[key].extend([0] * (max_len - len(data[key]))) return pd.DataFrame(data) # 使用示例 filtered_file = 'filtered_top_log_car.txt' # 1. 解析过滤后的日志文件 df = parse_filtered_log(filtered_file) df.to_csv('top_metrics_car.csv', index=False) print("已生成指标CSV文件: top_metrics_car.csv") # 2. 绘制图表 plt.figure(figsize=(16, 14)) plt.rcParams['axes.titlesize'] = 16 # 标题字体大小 plt.rcParams['axes.titleweight'] = 'bold' # 标题加粗 plt.rcParams['font.family'] = 'sans-serif' # 全局字体 # 进程CPU使用率 plt.subplot(4, 1, 1) plt.plot(df['time_sec'], df['nvrcore_cpu'], 'r-', label='nvrcore CPU%') # 只绘制onvif_cpu大于0的点 onvif_nonzero = df[df['onvif_cpu'] > 0] plt.plot(onvif_nonzero['time_sec'], onvif_nonzero['onvif_cpu'], 'b-', label='onvif CPU% (non-zero)') plt.title('Modules Process CPU Usage') plt.xlabel('Time (seconds)') plt.ylabel('CPU %') plt.legend() plt.grid(True) # 系统CPU使用率 plt.subplot(4, 1, 2) plt.plot(df['time_sec'], df['cpu_usr'], 'g-', label='User CPU%') plt.plot(df['time_sec'], df['cpu_sys'], 'm-', label='System CPU%') plt.title('NVR System CPU Usage') plt.ylabel('CPU %') plt.xlabel('Time (seconds)') plt.legend() plt.grid(True) # 内存使用情况 plt.subplot(4, 1, 3) # plt.plot(df['time_sec'], df['mem_used_mb'], 'c-', label='Used Memory (MB)') # plt.plot(df['time_sec'], df['mem_free_mb'], 'y-', label='Free Memory (MB)') # 计算内存使用变化量(相对于第一个点) if len(df['mem_used_mb']) > 0: base_used = df['mem_used_mb'].iloc[0] mem_used_change = df['mem_used_mb'] - base_used plt.plot(df['time_sec'], mem_used_change, 'c--', label='Used Memory Change (kB)') # if len(df['mem_free_mb']) > 0: # base_free = df['mem_free_mb'].iloc[0] # mem_free_change = df['mem_free_mb'] - base_free # plt.plot(df['time_sec'], mem_free_change, 'y--', label='Free Memory Change (MB)') plt.title('NVR Memory Usage Changes') plt.xlabel('Time (seconds)') plt.ylabel('Memory (kB)') plt.legend() plt.grid(True) # plt.subplot(4, 1, 4) # plt.plot(df['time_sec'], df['onvif_mem'], 'c-', label='Onvif Used Memory (kB)') # plt.plot(df['time_sec'], df['nvrcore_mem'], 'y-', label='Nvrcore Used Memory (kB)') # plt.title('Module Memory Usage') # plt.xlabel('Time (seconds)') # plt.ylabel('Memory (kB)') # plt.legend() # plt.grid(True) # 系统负载 # plt.subplot(4, 1, 4) # plt.plot(df['time_sec'], df['load_avg_1min'], 'r-', label='1-min Load Avg') # plt.plot(df['time_sec'], df['load_avg_5min'], 'g-', label='5-min Load Avg') # plt.plot(df['time_sec'], df['load_avg_15min'], 'b-', label='15-min Load Avg') # plt.title('System Load Average') # plt.xlabel('Time (seconds)') # plt.ylabel('Load Average') # plt.legend() # plt.grid(True) plt.tight_layout() plt.savefig('top_resource_usage_car.png', dpi=300) plt.show()根据这个代码统计一下如下数据并输出,在元数据推流交互过程中,onvif模块的cpu占用率不超过,变化在以内,nvrcore模块的cpu占用率不超过,变化在以内 NVR整体用户cpu占用了变化在以内 NVR整体内存变化在kB以内
11-05
import re import pandas as pd import matplotlib.pyplot as plt def parse_filtered_log(filtered_file_path): """解析过滤后的top日志文件""" data = { 'time_sec': [], 'mem_used_mb': [], 'mem_free_mb': [], 'cpu_usr': [], 'cpu_sys': [], 'load_avg_1min': [], 'load_avg_5min': [], 'load_avg_15min': [], 'nvrcore_cpu': [], 'nvrcore_mem': [], 'onvif_cpu': [], 'onvif_mem': [] } with open(filtered_file_path, 'r', encoding='utf-8') as f: lines = f.readlines() time_counter = 0 current_block = [] for line in lines: line = line.strip() if not line: continue if line.startswith('Mem:'): if current_block: nvrcore_cpu = 0.0 nvrcore_mem = 0.0 onvif_cpu = 0.0 onvif_mem = 0.0 for bline in current_block: parts = bline.split() if len(parts) >= 8: # 确保有足够多的列 # 提取进程名(合并可能被分割的部分) cmd = ' '.join(parts[7:]) # 处理nvrcoreM进程 if 'nvrcoreM' in cmd: try: nvrcore_cpu = float(parts[7]) # %CPU是第6列(索引5) # nvrcore_mem = float(parts[6]) # %MEM是第7列(索引6) except (IndexError, ValueError): pass # 处理onvif进程(排除discovery) elif './onvif' in cmd and 'discovery' not in cmd: try: onvif_cpu = float(parts[7]) # %CPU是第6列(索引5) # onvif_mem = float(parts[6]) # %MEM是第7列(索引6) except (IndexError, ValueError): pass data['nvrcore_cpu'].append(nvrcore_cpu) data['nvrcore_mem'].append(nvrcore_mem) data['onvif_cpu'].append(onvif_cpu) data['onvif_mem'].append(onvif_mem) current_block = [] mem_match = re.match(r'Mem:\s*(\d+)K used,\s*(\d+)K free', line) if mem_match: data['mem_used_mb'].append(int(mem_match.group(1)) / 1024) data['mem_free_mb'].append(int(mem_match.group(2)) / 1024) data['time_sec'].append(time_counter) time_counter += 5 current_block.append(line) if line.startswith('CPU:'): cpu_match = re.match(r'CPU:\s*([\d.]+)% usr\s+([\d.]+)% sys', line) if cpu_match: data['cpu_usr'].append(float(cpu_match.group(1))) data['cpu_sys'].append(float(cpu_match.group(2))) if line.startswith('Load average:'): load_match = re.match(r'Load average:\s*([\d.]+)\s+([\d.]+)\s+([\d.]+)', line) if load_match: data['load_avg_1min'].append(float(load_match.group(1))) data['load_avg_5min'].append(float(load_match.group(2))) data['load_avg_15min'].append(float(load_match.group(3))) max_len = len(data['time_sec']) for key in data: if len(data[key]) < max_len: data[key].extend([0] * (max_len - len(data[key]))) return pd.DataFrame(data) # 使用示例 filtered_file = 'filtered_top_log.txt' # 1. 解析过滤后的日志文件 df = parse_filtered_log(filtered_file) df.to_csv('top_metrics.csv', index=False) print("已生成指标CSV文件: top_metrics.csv") # 2. 绘制图表 plt.figure(figsize=(16, 14)) # 进程CPU使用率 plt.subplot(4, 1, 1) plt.plot(df['time_sec'], df['nvrcore_cpu'], 'r-', label='nvrcore CPU%') plt.plot(df['time_sec'], df['onvif_cpu'], 'b-', label='onvif CPU%') plt.title('Process CPU Usage') plt.xlabel('Time (seconds)') plt.ylabel('CPU %') plt.legend() plt.grid(True) # 系统CPU使用率 plt.subplot(4, 1, 2) plt.plot(df['time_sec'], df['cpu_usr'], 'g-', label='User CPU%') plt.plot(df['time_sec'], df['cpu_sys'], 'm-', label='System CPU%') plt.title('System CPU Usage') plt.ylabel('CPU %') plt.legend() plt.grid(True) # 内存使用情况 plt.subplot(4, 1, 3) plt.plot(df['time_sec'], df['mem_used_mb'], 'c-', label='Used Memory (MB)') plt.plot(df['time_sec'], df['mem_free_mb'], 'y-', label='Free Memory (MB)') plt.title('Memory Usage') plt.xlabel('Time (seconds)') plt.ylabel('Memory (MB)') plt.legend() plt.grid(True) # 系统负载 plt.subplot(4, 1, 4) plt.plot(df['time_sec'], df['load_avg_1min'], 'r-', label='1-min Load Avg') plt.plot(df['time_sec'], df['load_avg_5min'], 'g-', label='5-min Load Avg') plt.plot(df['time_sec'], df['load_avg_15min'], 'b-', label='15-min Load Avg') plt.title('System Load Average') plt.xlabel('Time (seconds)') plt.ylabel('Load Average') plt.legend() plt.grid(True) plt.tight_layout() plt.savefig('top_resource_usage.png', dpi=300) plt.show() 绘图时,onvif 的cpu%很多是0,跳过这些点不绘制,另外内存使用情况再加两条线,绘制内存的变化情况(相较于第一个点的变化)
11-04
<think> 我们正在讨论的是容器文件系统中可用inode数量指标:container_fs_inodes_free 根据用户需求,我们需要解释该指标的含义、用途及监控方法,并参考之前提供的引用内容(虽然引用中并没有直接提到inode,但我们可以结合文件系统监控的一般知识) 注意:用户提供的引用[3]提到了“inodesusedpercent”,这是与inode使用率相关的,我们可以借鉴。 指标名称:container_fs_inodes_free 含义:容器文件系统上可用的inode数量。inode是文件系统中用于存储文件元数据(如大小、权限、时间戳等)的数据结构。当inode用尽时,即使磁盘空间还有剩余,也无法创建新文件。 用途: 1. 预防因inode耗尽导致的容器故障(例如:应用无法写入日志或创建临时文件)。 2. 结合总inode数(container_fs_inodes_total)可以计算使用率,提前预警。 3. 在容器化环境中,由于容器共享主机内核但可能有独立的文件系统,监控每个容器的inode使用情况尤为重要。 监控方法: 1. 直接查询当前可用inode数量: container_fs_inodes_free{container="<container_name>", pod="<pod_name>", namespace="<namespace>"} 2. 计算inode使用率: (1 - (container_fs_inodes_free / container_fs_inodes_total)) * 100 或者使用PromQL表达式: (1 - container_fs_inodes_free{...} / container_fs_inodes_total{...}) * 100 3. 设置告警:当可用inode数量低于某个阈值(例如:1000)或者使用率超过90%时触发告警。 4. 结合引用[3]中的思路,我们可以监控inode使用百分比,表达式类似引用[2]中CPU限制的表达式,但这里是inode: (1 - container_fs_inodes_free / container_fs_inodes_total) * 100 5. 注意:该指标通常由cAdvisor采集,因此需要确保cAdvisor正常运行。 运维建议: - 定期清理容器内不需要的文件(特别是小文件)以释放inode。 - 在容器构建时,避免在镜像中包含大量小文件。 - 对于日志量大的容器,配置日志轮转,防止日志文件过多占用inode。 示例PromQL查询: 1. 按容器显示可用inode数量: container_fs_inodes_free{container!="", device=~"/dev/.*"} 2. 按容器显示inode使用率: (1 - container_fs_inodes_free{container!="", device=~"/dev/.*"} / container_fs_inodes_total{container!="", device=~"/dev/.*"}) * 100 3. 找出inode使用率超过90%的容器: (1 - container_fs_inodes_free{container!="", device=~"/dev/.*"} / container_fs_inodes_total{container!="", device=~"/dev/.*"}) * 100 > 90 4. 结合命名空间和Pod标签,可以更细粒度监控。 注意:由于文件系统可能有多个挂载点,因此需要根据device标签过滤,通常我们关注根文件系统(如`/`)或者主要数据卷。在Kubernetes中,容器的根文件系统通常对应`/`,而其他挂载点对应数据卷。 另外,引用[4]中提到了存储管理的持续监控与维护,这也是inode监控的一部分。 最后,生成相关问题。 </think>### `container_fs_inodes_free` 详解 #### **1. 指标含义** `container_fs_inodes_free` 是容器文件系统的核心监控指标,表示**容器文件系统中可用的 inode 数量**: - **Inode 本质**:文件系统的元数据结构,存储文件属性(权限/大小/位置等) - **关键限制**:每个文件/目录需占用 1 个 inode - **危险场景**:当 `container_fs_inodes_free ≈ 0` 时,即使磁盘空间充足也无法创建新文件[^3] #### **2. 核心用途** | **场景** | **重要性说明** | |------------------------|-----------------------------------------------------------------------------| | **容量预警** | 预防因 inode 耗尽导致的容器故障(如日志写入失败、应用崩溃) | | **存储优化** | 识别产生大量小文件的容器(如临时文件未清理) | | **资源规划** | 结合 `container_fs_inodes_total` 规划文件系统容量 | | **故障根因分析** | 区分磁盘空间不足(`container_fs_usage_bytes`)与 inode 耗尽问题 | #### **3. 监控方法** ##### (1) 基础查询 ```promql # 查看容器可用 inode 数量 container_fs_inodes_free{container="my-app", device="/dev/sda1"} # 计算 inode 使用率(百分比) (1 - container_fs_inodes_free{...} / container_fs_inodes_total{...}) * 100 ``` ##### (2) 关键告警规则 ```yaml # Inode 即将耗尽告警(可用数 < 1000) - alert: ContainerInodeExhaustion expr: container_fs_inodes_free{device!~"tmpfs"} < 1000 for: 10m labels: severity: critical annotations: summary: "容器 inode 即将耗尽 ({{ $labels.container }})" description: "可用 inode 仅剩 {{ $value }} 个" ``` ##### (3) 多维度分析 ```promql # 按命名空间统计 inode 使用率 sum by (namespace) ( (container_fs_inodes_total - container_fs_inodes_free) / container_fs_inodes_total * 100 ) # 检测 Top 3 inode 高消耗容器 topk(3, (container_fs_inodes_total - container_fs_inodes_free) ) ``` #### **4. 运维诊断流程** 当 `container_fs_inodes_free` 异常降低时: 1. **定位问题容器** ```bash # 查看容器 inode 使用 kubectl exec -it <pod> -- df -i ``` 2. **分析文件分布** ```bash # 统计容器内文件数量最多的目录 kubectl exec -it <pod> -- find / -type f | cut -d "/" -f 2 | sort | uniq -c | sort -n ``` 3. **清理策略** - 删除临时文件:`rm /tmp/*.log` - 配置日志轮转:使用 `logrotate` 限制日志文件数量 - 优化应用:避免高频创建临时小文件 #### **5. 与相关指标联动** | **指标** | **关联分析场景** | |----------------------------------|---------------------------------------------------------------------------------| | `container_fs_inodes_total` | 计算 inode 使用率:`(total - free)/total * 100` | | `container_fs_usage_bytes` | 联合分析磁盘空间与 inode 使用(可能出现磁盘空间充足但 inode 耗尽的情况)[^3] | | `container_fs_reads_total` | inode 不足时通常伴随文件读写错误激增 | | `kube_pod_container_status_ready`| inode 耗尽可能导致容器状态异常 | #### **6. 典型优化案例** 某 Java 应用容器频繁崩溃,监控发现: - 磁盘空间剩余 80% (`container_fs_usage_bytes`) - 但 inode 使用率 99.8% (`container_fs_inodes_free ≈ 15`) **根因**:未配置日志轮转,产生数百万小日志文件 **解决**:添加 logrotate 配置后 inode 使用率降至 45%[^4] > **最佳实践**:在 Grafana 面板中同时展示 > - `container_fs_inodes_free`(数值) > - `(1 - free/total)*100`(百分比) > - 设置阈值线(90% 警告,95% 严重告警) ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值