Tag Archives: OOM

从 Flickr 的 DB 服务器配置说起 Swap

又读了一遍这个 PPT: Federation at Flickr: Doing Billions of Queries Per Day ,发现还是值得咀嚼一下,尽管这”甘蔗”已经被吃过了。

针对主机环境的实践参考

Flickr 数据库的硬件配置一般用 16G 内存,6块 15K 硬盘,RAID 10,在 EM64T 下跑 RHEL 4,运行在 Deadline I/O 调度器 模式 。回写 Cache 用控制器电池而不用磁盘的 Cache。Swappiness 设置为 0 . 。

大内存数据库服务器的 Swap 设置问题

上面提到了 Flickr 是把 Swappiness 设置为 0 ,简单的通过:

echo 0 > /proc/sys/vm/swappiness 

个别情况下这样也可能没起作用,因为实际上对 Swap 的调用是由如下的公式计算得到的:

swap_tendency = mapped_ratio/2 + distress + vm_swappiness; 

其中 vm_swappiness 默认值是 60.

这是个防御性的措施。Linux Kernel 2.6 (个别版本)有些诡异行为,当有大量物理内存空闲的时候,Linux 仍(或许)会傻乎乎的调用 Swap 空间,这导致有的时候系统性能很差。有人建议如果是 INNODB 的引擎的话,可以用 O_DIRECT 的方式强制直接调用物理内存。但似乎副作用很大(存疑)。

如果关闭 Swap (swapoff -a)的话,又会遇到 OOM 的问题。这是绝对不推荐的。

还有人用的方式是把 Swap 建立到 RAM 盘上。

Swap 的自动校正其实是个老问题,几年前可能超过 4g 的 Linux 服务器都不多,而现在动辄几十 G 的内存配置,应用场景发生了很大变化,Kernel 的算法思路肯定也要调整一些了吧(尽管几年来不断看到有小的 Patch 出来,可好像 RHEL 的 Kernel 还是老样子)。

我在这里抛砖引玉,大家实际应用中应该也遇到类似问题吧? 有什么建议? 还是干脆就不管? 默认情况下其实也能跑…

EOF

Linux 的 Out-of-Memory (OOM) Killer

同事在 Linux 服务器上遇到点小问题,我也上去折腾半天。这还是第一次注意到 Linux 这个多年来就存在的特性:OOM Killer 。说白了 OOM Killer 就是一层保护机制,用于避免 Linux 在内存不足的时候不至于出太严重的问题,把无关紧要的进程杀掉,有些壮士断腕的意思。

先要学习点老知识,在 32 位CPU 架构下寻址是有限制的。Linux 内核定义了三个区域:

# DMA: 0x00000000 -  0x00999999 (0 - 16 MB) 
# LowMem: 0x01000000 - 0x037999999 (16 - 896 MB) - size: 880MB
# HighMem: 0x038000000 - <硬件特定>

LowMem 区 (也叫 NORMAL ZONE ) 一共 880 MB,而且不能改变(除非用 hugemem 内核)。对于高负载的系统,就可能因为 LowMem 利用不好而引发 OOM Killer 。一个可能原因是 LowFree 太少了,另外一个原因是 LowMem 里都是碎片,请求不到连续的内存区域【根据我遇到的一个案例,一个猜想是 有些应用一次性请求比较大的内存,恰恰又是 880M 之内的,空闲的(LowFree)不够大,就会触发 OOM Killer 出来干活】。检查当前 LowFree 的值:

# cat /proc/meminfo |grep LowFree 

检查LowMem内存碎片:

# cat /proc/buddyinfo

上面这条命令要在 2.6 Kernel 环境下有效。据说使用 SysRq 的方式更好,不过 Hang 的时候再用吧。参见 Metalink Note:228203.1 。

根据一些文档描述,OOM Killer 在 2.4 与 2.6 上表现是不一样的。2.4 的版本中是把新进来(新申请内存)的进程杀掉。而 2.6 上是杀掉占用内存最厉害的进程(这是很危险的,很容易导致系统应用瘫痪)。

对于 RHEL 4 ,新增了一个参数: vm.lower_zone_protection 。这个参数默认的单位为 MB,默认 0 的时候,LowMem 为 16MB。建议设置 vm.lower_zone_protection = 200 甚至更大以避免 LowMem 区域的碎片,是绝对能解决这个问题的(这参数就是解决这个问题出来的)。

而对于 RHEL 3 (Kernel 2.4) 似乎没什么好办法,一个是用 Hugemem 内核(天知道会不会引入新的毛病),一个是升级到 2.4.21-47 并且使用新的核心参数 vm.vm-defragment 控制碎片的数量。再就是使用 RHEL 4 (Kernel 2.6),这又绕回去了。说白了,如果遇到 OOM Killer ,基本上是低版本 Kernel 设计上有点缺陷。

其它,如果去查询 RedHat 的 Bug 库,会发现不少 Kernel 版本也有 Bug 的。尤其在使用 NFS 的场景。

Tip: OOM Killer 的关闭与激活方式:

# echo "0" > /proc/sys/vm/oom-kill 
# echo "1" > /proc/sys/vm/oom-kill

更多参考信息:

EOF

头疼欲裂,零散记录点东西,备查。