嗯…虽说是咱造成的,欸嘿~
摘要
咱最近不是更换服务器嘛,原因是旧服务器的磁盘总是有着 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_buffers 和 UNICORN_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 打败了论坛! ![]()
结语
Emoji 占领地球!