Ubuntu 交换空间的自动扩展与扩容实践
核心结论
- Linux 内核不提供“自动伸缩”交换空间的能力,无论是 Swap 分区 还是 Swap 文件,大小在创建后是固定的,需要手动调整或通过脚本/工具按需扩容。
- 实际运维中常用的“自动扩展”做法是:准备一个较大的 Swap 文件 作为“池”,按需启用其中的一部分;或编写脚本在内存紧张时临时增大 Swap 使用量,并在负载恢复后回收。这样既获得弹性,又避免频繁改动分区表。
方案一 使用 Swap 文件按需启用实现弹性扩展
- 思路:创建一个足够大的 Swap 文件 作为备用池,默认只启用其中一部分;当监控到内存压力升高时,启用更多 Swap 或提高 swappiness,压力降低后再降低 swappiness 或关闭新增部分(可选)。
- 快速步骤(一次性准备大文件,后续按需启用/停用):
- 创建大文件(示例 32G,可按需调整):
sudo fallocate -l 32G /swapfile
- 安全权限:
sudo chmod 600 /swapfile
- 格式化为 Swap:
sudo mkswap /swapfile
- 开机自动启用整个文件(默认可能不启用,由脚本按需 swapon/swapoff 控制):
echo ‘/swapfile none swap sw 0 0’ | sudo tee -a /etc/fstab
- 按需启用部分容量(示例先启用 8G):
sudo swapon /swapfile
如需只“启用一部分”,可用 cgroups + memory.swap.max 限制该挂载点的使用上限(高级用法)
- 验证:
free -h
swapon --show
- 提示:Swap 文件大小固定,但“启用多少”可动态控制;若未来需要更大弹性,直接增大文件并重复 mkswap/swapon 即可。上述创建、权限、启用与 fstab 配置均为标准做法。
方案二 监控触发脚本自动扩容与回收
- 思路:用 cron 或 systemd timer 定期采样内存与 Swap 使用率,超过阈值时启用更多 Swap 或提高 swappiness,低于阈值时恢复,达到“自动扩展/收缩”的效果。
- 示例脚本(简化版,按需调整阈值与步长)
#!/usr/bin/env bash
set -Eeuo pipefail
THRESHOLD=80
SWAPFILE=/swapfile
STEP=8G
SWAPPINESS_HIGH=60
SWAPPINESS_LOW=10
mem_info() {
read -r total used free shared buff cache avail < <(free -m | awk 'NR==2{print $2,$3,$4,$5,$6,$7}')
echo "$total $used $free $avail"
}
current_swap() {
swapon --show=NAME,SIZE --bytes | awk 'NR>1{sum+=$2} END{print sum}'
}
adjust() {
local avail_mb used_pct
read -r total used free shared buff cache avail < <(mem_info)
used_pct=$((100 - avail*100/total))
local cur_swap=$(current_swap)
local cur_swap_mb=$((cur_swap/1024/1024))
if (( used_pct >= THRESHOLD && cur_swap_mb < 32768 )); then
echo "$(date) High memory pressure ($used_pct%), enabling ${STEP} more swap"
sudo swapon "$SWAPFILE" || true
echo "$SWAPPINESS_HIGH" | sudo tee /proc/sys/vm/swappiness
elif (( used_pct < THRESHOLD*0.7 && cur_swap_mb > STEP )); then
echo "$(date) Memory pressure relieved ($used_pct%), reducing swap usage"
echo "$SWAPPINESS_LOW" | sudo tee /proc/sys/vm/swappiness
fi
}
adjust
- 使用要点
- 将脚本加入 root 的 cron(如每 5 分钟):*/5 * * * * /usr/local/bin/swap-manager.sh >> /var/log/swap-manager.log 2>&1
- 首次请确保已按“方案一”准备好 /swapfile 并在 /etc/fstab 中配置开机启用。
- 该方案通过“启用/停用”和 swappiness 调整实现弹性,避免频繁改分区;阈值与步长请结合磁盘空间与业务容忍度设置。
方案三 扩容现有 Swap 分区或文件到更大固定值
- 适用场景:明确需要一次性把 Swap 扩大到指定容量(非运行时自动伸缩)。
- 扩容 Swap 文件(通用、风险低)
- 关闭现有 Swap:sudo swapoff -a
- 删除旧文件:sudo rm /swapfile
- 创建更大的文件:sudo fallocate -l 16G /swapfile(示例 16G)
- 权限:sudo chmod 600 /swapfile
- 格式化:sudo mkswap /swapfile
- 启用:sudo swapon /swapfile
- 开机自动启用:在 /etc/fstab 添加 /swapfile none swap sw 0 0
- 扩容 Swap 分区(涉及分区表变更,谨慎)
- 关闭 Swap:sudo swapoff -a
- 用 fdisk/lsblk 确认分区设备(如 /dev/nvme0n1p2)
- 调整分区大小(使用分区工具,步骤略,务必备份)
- 重新初始化:sudo mkswap /dev/nvme0n1p2
- 启用:sudo swapon /dev/nvme0n1p2
- 更新 /etc/fstab 中的对应条目
- 说明:分区方式更“重”,但同样有效;文件方式更灵活、可随时重建与替换。
注意事项与优化建议
- 性能与寿命:Swap 会显著影响性能,频繁换页会导致 SSD 磨损;仅在必要时启用较大 Swap,或优先使用内存更大的实例。
- 文件系统支持:fallocate 在大多数现代文件系统上可用;若失败,可改用 dd if=/dev/zero of=/swapfile bs=1G count=N 创建文件。
- swappiness 调优:默认 60;数据库、实时计算等对延迟敏感的场景可适当降低;内存紧张且磁盘空间充足时可适度提高,以换取稳定性。
- 监控与告警:建议配合 Prometheus Node Exporter + Alertmanager 或系统监控脚本,在可用内存低、Swap 使用飙升时提前介入。