[技术研究报告] 记一次咱的错误配置导致的论坛服务器磁盘“起飞”()

嗯…虽说是咱造成的,欸嘿~

摘要

咱最近不是更换服务器嘛,原因是旧服务器的磁盘总是有着 50~150 MB/s 的读取占据了服务器的大部分资源,咱就寻思着换个新的服务器,还能节省开支(霓碳[1]好久没吃到新赞助了,要开始啃服务器啦!抢救服务器!

结果!霓碳[2]吃太胖了!新服务器的内存不够霓碳住,她把 pgsql 和 redis 全挤出去了!
服务器炸啦!磁盘读取速度飙升到 2.4 GB/s!!!

问题表现

初见端倪

Nginx 报错 X-Accel-Mapping header missing
磁盘 I/O 监控显示持续读取,速度达 150 MB/s

(咱开始检查事故原因)

不兑!

磁盘 I/O 监控显示读取速度已达 2.4 GB/s
服务器开始卡顿

完啦!

SSH 完全卡死
服务器可视化管理面板超时
服务器死机

原因分析

跟 Discourse 配置文件里的两个参数有关:
db_shared_buffersUNICORN_WORKERS

前者是负责控制数据库的共享缓冲区大小,太大就会导致内存耗尽。而后者是论坛能同时运行的工作进程数量,启动时会占用约 300~500 MB 的内存,同时常驻

好!参数了解完了,接下来说说咱设置的值:
db_shared_buffers: 2048MB
UNICORN_WORKERS: 8

如果使用上述参数运行,至少需要 5.5 GB 的可用内存。而咱的新服务器给论坛的可用内存总共就 4 GB!
(至于为什么会是这个值…因为咱之前的服务器是 8 GB 的可用内存,所以…没钱(

Linux 内核一看:这不行啊!内存溢出了,我还怎么运行!
于是 Linux 内核让 OOM Killer(内存不足杀手)终止了论坛的 Redis 和 PostgreSQL 进程,以释放内存。

Discourse(论坛所使用的程序)一看,说:这不行啊!你把这俩关键进程关了我怎么办!
于是 Discourse 就先在日志里写个异常,然后立即重试!

这个重试没有任何延迟执行,咱的新服务器还是 AMD EPYC 7702。因为 OOM Killer 一直在杀进程,所以 Discourse 一直在尝试重启。而重启这些进程需要读取不少配置文件,一般情况下这只会造成短期的大读取,例如 50 MB/s
但是! 正如前面所写,这种重启是没有执行延迟的,所以服务器在一秒内进行了数千次的进程重启,导致读取过大,最终服务器在 2.4 GB/s 的时候不堪重负,死机了(

其实从日志来看,是论坛在读取 emoji 时失败导致的问题,所以从某种意义上来说是 Emoji 打败了论坛! :c_baka_1:

结语

Emoji 占领地球!


  1. 站娘 ↩︎

  2. 站娘 ↩︎

1 个赞

好玩~ 右下角的弹跳人也会导致内核较旧的浏览器一会一卡,建议检查这个小程序的原作者有没有更新新版本~

1 个赞

好~ 已经将弹跳人的版本改到最新了!
从 2.7.0 改成了 3.0.1 (跨越世纪的更新)

1 个赞