欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 汽车 > 新车 > k8s node 内存碎片化如何优化?

k8s node 内存碎片化如何优化?

2025/5/7 17:55:22 来源:https://blog.csdn.net/ygq13572549874/article/details/147734532  浏览:    关键词:k8s node 内存碎片化如何优化?

在 Kubernetes 集群中,内存碎片化(Memory Fragmentation)会导致系统无法分配连续的内存块,即使总内存充足,也可能触发 OOM(Out of Memory)或影响性能。以下是针对 k8s Node 内存碎片化的优化策略:

一、内存碎片化的原因

  1. 频繁分配和释放不同大小的内存:容器频繁创建和销毁,导致内存块分散。
  2. 大内存请求与小内存碎片不匹配:连续内存块不足,无法满足大内存分配。
  3. 内存分配器限制:Linux 默认的内存分配器(如 slab、slub)在某些场景下效率较低。
  4. 长时间运行的节点:随着时间推移,内存碎片化问题会逐渐积累。

二、诊断内存碎片化

参考:如何使用vmstat 和 free 查看内存碎片化信息?-CSDN博客

1. 使用 vmstat 和 free 查看总体内存
vmstat 1 5  # 每1秒采样,共5次
free -h     # 查看内存使用情况
2. 检查 /proc/buddyinfo 查看内存碎片程度
cat /proc/buddyinfo
# 输出示例(关注高阶内存块数量):
# Node 0, zone      DMA      0      0      0      0      0      0      0      0      1      1      3
# Node 0, zone    DMA32   123    89    72    56    38    25    16    10     5     2     1
# Node 0, zone   Normal  156   120   100    80    60    40    25    15     8     3     1

输出详解 

1)基本格式

Node <节点ID>, zone <内存区域> <各阶内存块数量>
  • Node:表示 NUMA 节点(单节点系统通常为 0)
  • zone:内存区域类型(如 DMA、Normal、HighMem)
  • 各阶内存块数量:从阶 0 到阶 N 的连续页框数量 

2)内存阶(Order)的概念

  • 阶 0:1 个页框(通常 4KB)
  • 阶 1:2 个连续页框(8KB)
  • 阶 2:4 个连续页框(16KB)
  • 阶 N:2^N 个连续页框

例如:阶 10 = 1024 个页框 = 4MB(假设页大小为 4KB)

3)输出解析

  • Node 0:NUMA 节点 0
  • zone DMA:用于 DMA 的内存区域(地址低于 16MB)
  • 各阶数量
    • 阶 0:0 个 4KB 页框
    • 阶 1:0 个 8KB 页框
    • ...
    • 阶 9:1 个 2MB 页框
    • 阶 10:1 个 4MB 页框
    • 阶 11:3 个 8MB 页框

4)关键指标

  • 高阶值低(如阶 8 及以上):表明大内存块稀缺,可能存在碎片化
  • 低阶值高(如阶 0-3):表明小内存块充足

5)内存碎片化判断

正常情况

  • 各阶内存块分布相对均匀
  • 高阶内存块(如阶 8+)有一定数量

碎片化特征

  • 高阶内存块数量极低(如全为 0)
  • 低阶内存块数量高,但无法合并成大内存块

6)相关命令

查看内存区域详情

cat /proc/zoneinfo | grep -E 'Node|free_pages'

计算总可用内存

# 总可用页框数
grep 'free_pages' /proc/zoneinfo | awk '{sum+=$2} END {print sum}'# 转换为 MB(假设页大小为 4KB)
echo "$(cat /proc/zoneinfo | grep 'free_pages' | awk '{sum+=$2} END {print sum}') * 4 / 1024" | bc

3. 使用 smem 分析内存使用模式
# 安装 smem
yum install smem  # CentOS/RHEL
apt install smem  # Ubuntu/Debian# 按进程查看内存使用
smem -s rss -k | head -n 20  # 按 RSS 排序,显示前20

三、优化策略

1. 调整内核参数
# 启用内存碎片整理(临时)
echo 1 > /proc/sys/vm/compact_memory# 调整 swappiness(减少内存压力)
echo 10 > /proc/sys/vm/swappiness  # 永久修改需编辑 /etc/sysctl.conf# 启用透明大页(THP)
echo always > /sys/kernel/mm/transparent_hugepage/enabled
2. 优化容器资源配置
# 为容器设置合理的 requests 和 limits
resources:requests:memory: "256Mi"limits:memory: "512Mi"  # 避免过大的内存限制导致碎片
3. 使用内存密集型 Pod 的亲和性
# 将内存密集型 Pod 调度到专用节点
affinity:nodeAffinity:requiredDuringSchedulingIgnoredDuringExecution:nodeSelectorTerms:- matchExpressions:- key: memory-intensiveoperator: Invalues:- "true"
4. 定期重启节点
# 使用 CronJob 定期重启节点
apiVersion: batch/v1beta1
kind: CronJob
metadata:name: node-reboot
spec:schedule: "0 2 * * 0"  # 每周日凌晨2点jobTemplate:spec:template:spec:hostPID: truecontainers:- name: rebootimage: alpinecommand: ["/sbin/reboot"]securityContext:privileged: truerestartPolicy: Never
5. 调整内存分配器
# 切换到更高效的内存分配器(如 jemalloc)
echo "export MALLOC_CONF=background_thread:true,metadata_thp:auto" >> /etc/profile
source /etc/profile
6. 避免内存碎片的应用优化
# Python 示例:预分配内存池
import gc
import psutil# 禁用垃圾回收器,减少内存碎片
gc.disable()# 预分配内存
def allocate_memory(size):process = psutil.Process()memory_before = process.memory_info().rssdata = bytearray(size)memory_after = process.memory_info().rssprint(f"Allocated {memory_after - memory_before} bytes")return data
7 减少大内存分配

避免申请超过 1GB 的连续内存 

四、监控与告警

1. Prometheus + Grafana 监控
# 关键指标
- name: memory-fragmentation.rulesrules:- alert: HighMemoryFragmentationexpr: (node_memory_MemFree_bytes + node_memory_Cached_bytes + node_memory_Buffers_bytes) / node_memory_MemTotal_bytes < 0.1for: 10mlabels:severity: warningannotations:summary: "High memory fragmentation on {{ $labels.instance }}"
2. 自定义脚本监控
#!/bin/bash# 监控内存碎片率
THRESHOLD=0.3fragmentation=$(cat /proc/buddyinfo | awk '/Normal/ {sum = 0;for (i = 1; i <= NF; i++) {if (i > 4) {sum += $(i) * (2 ^ (i - 5));}}print sum;}
')total=$(cat /proc/meminfo | grep MemTotal | awk '{print $2}')
fragmentation_ratio=$(echo "scale=2; $fragmentation / $total" | bc)if (( $(echo "$fragmentation_ratio > $THRESHOLD" | bc -l) )); thenecho "Warning: High memory fragmentation ($fragmentation_ratio)"# 触发告警或自动修复
fi

五、验证优化效果

# 对比优化前后的内存碎片情况
cat /proc/buddyinfo > before.txt
# 执行优化措施后
cat /proc/buddyinfo > after.txt
diff before.txt after.txt

六、注意事项

  1. 测试先行:在生产环境应用任何变更前,先在测试环境验证。
  2. 渐进式调整:逐步调整参数,避免对系统造成冲击。
  3. 日志分析:定期分析系统日志,识别内存碎片化的根本原因。

通过以上措施,可有效缓解 k8s Node 的内存碎片化问题,提升系统稳定性和资源利用率。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词