努力
加油

CentOS或Ubuntu系统在1核1G配置下是否会出现内存频繁交换(swap)?

直接给结论:在1核1G的配置下,只要运行任何稍微“正常”一点的现代服务或应用栈,出现内存频繁交换(Swap)几乎是必然的,甚至可以说这是这种配置的常态。

这不是系统bug,而是物理资源的硬性瓶颈。下面从技术原理、实际场景和应对策略三个维度拆解这个问题。

1. 为什么一定会 Swap?

首先得认清 1G 内存的现状。

  • 操作系统开销:Linux 内核本身启动后,idle 状态下大约占用 100MB~200MB 内存。
  • 基础进程:SSH 守护进程、日志服务(rsyslog/journald)、网络管理服务等,加起来轻松吃掉 100MB+。
  • 可用内存:留给你的业务程序的实际可用内存,通常只有 600MB~800MB。

对于 CentOS 7/8 或 Ubuntu 18.04/20.04/22.04 来说,默认都会开启 Swap。当物理内存不足时,内核会将不常用的页面移动到磁盘上的 Swap 分区。

关键点在于: 1G 机器跑 Web 服务(Nginx + PHP-FPM/Apache + MySQL/MariaDB),或者跑 Java 应用,内存瞬间就会被撑爆。一旦物理内存耗尽,内核就会触发 OOM (Out Of Memory) 之前的最后手段——Swap。

2. “频繁交换”意味着什么?

很多用户看到 top 命令里 si (swap in) 和 so (swap out) 有数值跳动,就以为服务器卡死了。这里需要区分两种情况:

情况 A:低频 Swap(可接受)

如果你的负载很低,比如只是放一个静态博客,偶尔有人访问。

  • 现象:si/so 偶尔有几个 KB 的波动,然后归零。
  • 原因:内核为了释放内存给更紧急的任务,把一些长时间没用的缓存页换出到磁盘。
  • 影响:几乎无感。因为读磁盘的速度虽然比内存慢,但如果数据只在后台静默交换,且频率极低,CPU 不会因此阻塞。

情况 B:高频 Swap(性能杀手)

如果你的业务有一定并发,或者数据库在运行。

  • 现象:si/so 持续高位,wa (IO Wait) 指标飙升,top 中 CPU 使用率不高但响应极慢。
  • 原因:业务真的缺内存了,不得不频繁地在内存和磁盘之间倒腾数据。
  • 影响:严重卡顿。磁盘 IO 是机械硬盘的万倍差距,SSD 稍好但也有数量级差异。频繁 Swap 会导致请求超时、数据库查询变慢、网站白屏。

在 1核1G 上,只要不是纯静态 HTML,大概率会进入“情况 B”。

3. 不同系统的表现差异

  • CentOS/RHEL 系列:

    • 默认启用 Swap,且 swappiness 值通常为 60。这意味着内核比较“积极”地把数据换出到磁盘,以保留更多物理内存给文件缓存等。
    • 在 1G 配置下,如果跑 MySQL,很容易因为临时表或排序操作触发 Swap。
  • Ubuntu 系列:

    • 同样默认启用 Swap。
    • Ubuntu 的内存管理策略在某些版本中对 ZRAM(压缩内存)支持更好,但标准云服务器镜像通常还是用普通 Swap 文件。
    • 如果你安装的是桌面版 Ubuntu,那 1G 根本打不开浏览器,必 Swap。服务器版相对轻量,但依然扛不住多服务叠加。

4. 真实场景模拟

假设你在 1核1G 上搭建 LNMP (Linux+Nginx+MySQL+PHP):

  1. 开机空闲:内存使用 ~350MB,Swap 未使用。
  2. 启动 Nginx + PHP-FPM:内存使用 ~500MB。
  3. 启动 MySQL:MySQL 默认配置对内存要求较高,即使最小化配置,启动后也会占用 100-200MB。此时总内存接近 700-800MB。
  4. 第一个请求进来:PHP 解析代码,MySQL 执行查询。内存使用飙升至 900MB+。
  5. 第二个并发请求:内存超过 1GB。
  6. 结果:内核开始 Swap Out PHP-FPM 的工作集。下一个请求到来时,可能需要 Swap In。这就是你看到的“频繁交换”。

5. 如何解决或缓解?

既然硬件限制无法改变,只能从软件层面优化:

方案一:调整 Swappiness(治标不治本)

# 查看当前值
cat /proc/sys/vm/swappiness

# 临时调整为 10,降低内核主动 swap 的意愿
sysctl vm.swappiness=10
  • 注意:这不能消除 Swap,只是让内核更倾向于用满物理内存再考虑 Swap。在 1G 机器上,最终还是会 Swap,只是时机稍晚。

方案二:优化 MySQL/MariaDB 配置(关键!)

MySQL 是内存大户。编辑 /etc/my.cnf 或 /etc/mysql/my.cnf:

[mysqld]
innodb_buffer_pool_size = 128M  # 默认可能是几百兆,必须调小
max_connections = 50            # 限制最大连接数
query_cache_size = 0            # MySQL 5.7+ 已移除,旧版本建议关闭
tmp_table_size = 16M
max_heap_table_size = 16M

通过大幅缩减 MySQL 的缓冲池,可以显著减少内存压力,避免 Swap。

方案三:更换轻量级替代方案

  • 数据库:如果数据量不大,考虑使用 SQLite 或 Redis 作为缓存层,减轻 MySQL 负担。
  • Web 服务:使用 Nginx + PHP-FPM 而非 Apache。PHP-FPM 可以设置 pm.max_children,限制同时运行的 PHP 进程数,防止内存爆炸。

方案四:使用 Swap 文件而非分区,并配合 ZRAM(高级)

部分 Linux 发行版支持 ZRAM,它是在 RAM 中划分一块区域做压缩存储,速度远快于磁盘 Swap。

  • 检查是否支持:zramctl
  • 如果支持,启用 ZRAM 可以将有效内存提升 30%-50%,极大缓解 Swap 压力。但这需要手动配置,非所有云厂商默认开启。

方案五:终极建议 —— 升级配置

说实话,1核1G 在当今互联网环境下,仅适合用于:

  • 个人学习 Linux 命令
  • 部署极简的静态网站(GitHub Pages 风格)
  • 运行 Go/Python 编写的轻量级 API 服务(无数据库或仅连外部 DB)
  • 反向XX/Nginx 单独节点

任何涉及动态内容、数据库、Java/.NET 应用的场景,1核1G 都是灾难性的体验。 如果预算允许,升级到 2核2G 或 2核4G,成本增加不多,但体验是天壤之别。

总结

在 1核1G 的 CentOS 或 Ubuntu 上,内存频繁交换是预期行为,而非异常故障。

  • 如果是低频访问的个人项目,可以通过优化 MySQL 和 PHP 配置来维持可用状态。
  • 如果是生产环境或有并发需求,请放弃抵抗,直接升级实例规格。试图在 1G 内存上强行承载现代 Web 架构,是在与物理定律对抗,性价比极低。