mongodb启动warning报错:
CONTROL [initandlisten] ** numactl --interleave=all mongod [other options]
解决方式:
1.改动内核參数
echo 0 > /proc/sys/vm/zone_reclaim_mode
2.在原启动命令前面加numactl --interleave=all
如# numactl --interleave=all ${MONGODB_HOME}/bin/mongod –config conf/mongodb.conf
如果没有 numactl这个命令的话,需要安装一下
yum install numactl -y
扩展部分:
1.NUMA和SMP
NUMA和SMP是两种CPU相关的硬件架构。
SMP (对称多处理器结构: Symmetric Multi-Processor)
在SMP架构里面,所有的CPU争用一个总线来访问所有内存,优点是资源共享,而缺点是当处理器的数目增大时,系统总线的竞争冲突加大,系统总线将成为瓶颈。随着PC服务器上的CPU数量变多(不仅仅是CPU核数),总线争用的弊端慢慢越来越明显。
NUMA ( 非一致存储访问结构: Non-Uniform Memory Access)
NUMA是指多处理器系统中,内存的访问时间是依赖于处理器和内存之间的相对位置的。这种设计里存在和处理器相对近的内存,通常被称作本地内存;还有和处理器相对远的内存,通常被称为非本地内存。NUMA最大的特点是引入了node和distance的概念。对于CPU和内存这两种最宝贵的硬件资源,NUMA用近乎严格的方式划分了所属的资源组(node),而每个资源组内的CPU和内存是几乎相等。资源组的数量取决于物理CPU的个数(现有的PC server大多数有两个物理CPU);distance是用来定义各个node之间调用资源的开销,为资源调度优化算法提供数据支持。
NUMA系统的结点通常是由一组CPU(如,SGI Altix 3000是2个Itanium2 CPU)和本地内存组成,有的结点可能还有I/O子系统。由于每个结点都有自己的本地内存,因此全系统的内存在物理上是分布的,每个结点访问本地内存和访问其它结点的远地内存的延迟是不同的,为了减少非一致性访存对系统的影响,在硬件设计时应尽量降低远地内存访存延迟(如通过Cache一致性设计等),而操作系统也必须能感知硬件的拓扑结构,优化系统的访存
2.NUMA的利与弊
现在的机器上都是有多个CPU和多个内存块的。以前我们都是将内存块看成是一大块内存,所有CPU到这个共享内存的访问消息是一样的,这就是之前普遍使用的SMP模型。但是随着处理器的增加,共享内存可能会导致内存访问冲突越来越厉害,且如果内存访问达到瓶颈的时候,性能就不能随之增加。NUMA(Non-Uniform Memory Access)就是在这样的背景下引入的一个模型。比如一台机器是有2个处理器,有4个内存块。我们将1个处理器和两个内存块合起来,称为一个NUMA node,这样这个机器就会有两个NUMA node。在物理分布上,NUMA node的处理器和内存块的物理距离更小,因此访问也更快。比如这台机器会分左右两个处理器(cpu1, cpu2),在每个处理器两边放两个内存块(memory1.1, memory1.2, memory2.1,memory2.2),这样NUMA node1的cpu1访问memory1.1和memory1.2就比访问memory2.1和memory2.2更快。所以使用NUMA的模式如果能尽量保证本node内的CPU只访问本node内的内存块,提高访问效率。
但是,因为NUMA默认的内存分配策略是优先在进程所在CPU的本地内存中分配,会导致CPU节点之间内存分配不均衡,当某个CPU节点的内存不足时,会导致swap产生,而不是从远程节点申请内存,即所谓的swap insanity 现象。现有的Redhat Linux中,localalloc策略是默认的NUMA内存分配策略(localalloc规定进程从当前node上请求分配内存,此外还有策略 preferred、membind、interleave),这个配置选项导致资源独占程序很容易将某个node的内存用尽。而当某个node的内存耗尽时,Linux又刚好将这个node分配给了某个需要消耗大量内存的进程(或线程),swap产生了。尽管此时还有很多page cache可以释放,甚至还有很多的free内存。SWAP的罪与罚文章就说到了一个numa的陷阱的问题。现象是服务器还有内存的时候,发现它已经在开始使用swap了,甚至导致机器出现停滞的现象。所以,如果限制一个进程只能使用自己的numa节点的内存,那么当它自身numa node内存使用光之后,就不会去使用其他numa node的内存了,会开始使用swap,甚至更糟的情况,机器没有设置swap的时候,可能会直接死机!
3、NUMA和swap的关系
NUMA的内存分配策略对于进程(或线程)之间来说,并非公平的。
在现有的Redhat Linux中,localalloc是默认的NUMA内存分配策略。这个配置选项导致资源独占程序非常easy将某个node的内存用尽。
而当某个node的内存耗尽时,Linux又刚好将这个node分配给了某个须要消耗大量内存的进程(或线程)。swap就妥妥地产生了。
虽然此时还有非常多page cache能够释放。甚至还有非常多的free内存。
4、解决swap问题
虽然NUMA的原理相对复杂,实际上解决swap却非常简单:只要在启动mongodb之前使用numactl --interleave来改动NUMA策略就可以。
值得注意的是。numactl这个命令不只能够调整NUMA策略,也能够用来查看当前各个node的资源是用情况,是一个非常值得研究的命令。
总结:
如果你的程序是会占用大规模内存的,应该考虑选择关闭numa node的限制(或从硬件关闭numa),因为这个时候很有可能会碰到numa陷阱。另外,如果你的程序并不占用大内存,而是要求更快的程序运行时间,可以考虑选择限制只访问本numa node的方法来进行处理。