memory overcommit
vm.overcommit_memory = 2
vm.overcommit_ratio = 95 # **See [Note](https://gpdb.docs.pivotal.io/6-0/install_guide/prep_os.html#topic4__sysctl_conf) 2**
GP 相关说明
When vm.overcommit_memory is 2, you specify a value for vm.overcommit_ratio. For information about calculating the value for vm.overcommit_ratio when using resource queue-based resource management, see the Greenplum Database server configuration parameter gp_vmem_protect_limit in the Greenplum Database Reference Guide. If you are using resource group-based resource management, tune the operating system vm.overcommit_ratio as necessary. If your memory utilization is too low, increase the vm.overcommit_ratio value; if your memory or swap usage is too high, decrease the value.
linux 内核解释
http://linuxperf.com/?p=102
Memory Overcommit 的意思是操作系统承诺给进程的内存大小超过了实际可用的内存。一个保守的操作系统不会允许 memory overcommit,有多少就分配多少,再申请就没有了,这其实有些浪费内存,因为进程实际使用到的内存往往比申请的内存要少,比如某个进程 malloc() 了 200MB 内存,但实际上只用到了 100MB,按照 UNIX/Linux 的算法,物理内存页的分配发生在使用的瞬间,而不是在申请的瞬间,也就是说未用到的 100MB 内存根本就没有分配,这 100MB 内存就闲置了。下面这个概念很重要,是理解 memory overcommit 的关键:commit(或 overcommit)针对的是内存申请,内存申请不等于内存分配,内存只在实际用到的时候才分配。
Linux 是允许 memory overcommit 的,只要你来申请内存我就给你,寄希望于进程实际上用不到那么多内存,但万一用到那么多了呢?那就会发生类似“银行挤兑”的危机,现金 (内存) 不足了。Linux 设计了一个 OOM killer 机制 (OOM = out-of-memory) 来处理这种危机:挑选一个进程出来杀死,以腾出部分内存,如果还不够就继续杀…也可通过设置内核参数 vm.panic_on_oom 使得发生 OOM 时自动重启系统。这都是有风险的机制,重启有可能造成业务中断,杀死进程也有可能导致业务中断,我自己的这个小网站就碰到过这种问题,参见前文。所以 Linux 2.6 之后允许通过内核参数 vm.overcommit_memory 禁止 memory overcommit。
内核参数 vm.overcommit_memory 接受三种取值:
- 0 – Heuristic overcommit handling. 这是缺省值,它允许 overcommit,但过于明目张胆的 overcommit 会被拒绝,比如 malloc 一次性申请的内存大小就超过了系统总内存。Heuristic 的意思是“试探式的”,内核利用某种算法(对该算法的详细解释请看文末)猜测你的内存申请是否合理,它认为不合理就会拒绝 overcommit。
- 1 – Always overcommit. 允许 overcommit,对内存申请来者不拒。
- 2 – Don’t overcommit. 禁止 overcommit。
关于禁止 overcommit (vm.overcommit_memory=2),需要知道的是,怎样才算是 overcommit 呢?kernel 设有一个阈值,申请的内存总数超过这个阈值就算 overcommit,在 /proc/meminfo 中可以看到这个阈值的大小:
# grep -i commit /proc/meminfo
CommitLimit: 5967744 kB
Committed_AS: 5363236 kB
CommitLimit 就是 overcommit 的阈值,申请的内存总数超过 CommitLimit 的话就算是 overcommit。
这个阈值是如何计算出来的呢?它既不是物理内存的大小,也不是 free memory 的大小,它是通过内核参数 vm.overcommit_ratio 或 vm.overcommit_kbytes 间接设置的,公式如下:
【CommitLimit = (Physical RAM * vm.overcommit_ratio / 100) + Swap】
注:
vm.overcommit_ratio 是内核参数,缺省值是 50,表示物理内存的 50%。如果你不想使用比率,也可以直接指定内存的字节数大小,通过另一个内核参数 vm.overcommit_kbytes 即可;
如果使用了 huge pages,那么需要从物理内存中减去,公式变成:
CommitLimit = ([total RAM] – [total huge TLB RAM]) * vm.overcommit_ratio / 100 + swap
参见 https://access.redhat.com/solutions/665023
/proc/meminfo 中的 Committed_AS 表示所有进程已经申请的内存总大小,(注意是已经申请的,不是已经分配的),如果 Committed_AS 超过 CommitLimit 就表示发生了 overcommit,超出越多表示 overcommit 越严重。Committed_AS 的含义换一种说法就是,如果要绝对保证不发生 OOM (out of memory) 需要多少物理内存。
ip port
net.ipv4.ip_local_port_range = 10000 65535
GP 相关说明
To avoid port conflicts between Greenplum Database and other applications when initializing Greenplum Database, do not specify Greenplum Database ports in the range specified by the operating system parameter net.ipv4.ip_local_port_range. For example, if net.ipv4.ip_local_port_range = 10000 65535, you could set the Greenplum Database base port numbers to these values.
PORT_BASE = 6000
MIRROR_PORT_BASE = 7000
For information about the port ranges that are used by Greenplum Database, see gpinitsystem.
linux 内核解释
On Linux, there is a sysctl parameter calledip_local_port_range
that defines the minimum and maximum port a networking connection can use as its source (local) port. This applies to both TCP and UDP connections.
cat /proc/sys/net/ipv4/ip_local_port_range
shared memory
# kernel.shmall = _PHYS_PAGES / 2 # See Note 1
kernel.shmall = 4000000000
# kernel.shmmax = kernel.shmall * PAGE_SIZE # See Note 1
kernel.shmmax = 500000000
kernel.shmmni = 4096
查看限制、查看使用ipcs -lm
、ipcs -u
- shmall: This parameter sets the total amount of shared memory pages that can be used system wide. Hence, SHMALL should always be at least
ceil(shmmax/PAGE_SIZE)
.
共享内存能使用的总页数echo $(expr $(getconf _PHYS_PAGES) / 2)
- shmmax: This parameter defines the maximum size in bytes of a single shared memory segment that a Linux process can allocate in its virtual address space.
共享内存的总大小echo $(expr $(getconf _PHYS_PAGES) / 2 \* $(getconf PAGE_SIZE))
- shmmin: This parameter sets the system wide maximum number of shared memory segments.
semaphores
cat /proc/sys/kernel/sem
500 2048000 200 40960
SEMMSL, SEMMNS, SEMOPM, SEMMNI
kernel.sem = 500 2048000 200 40960
SEMMSL
含义:每个信号量 set 中信号量最大个数 设置:最小 250;对于 processes 参数设置较大的系统建议设置为 processes+10
SEMMNS
含义:linux 系统中信号量最大个数 设置:至少 32000;SEMMSL * SEMMNI
SEMOPM
含义:semop 系统调用允许的信号量最大个数设置:至少 100;或者等于 SEMMSL
SEMMNI
含义:linux 系统信号量 set 最大个数 设置:最少 128
link
管理 IPC 资源
分别查询 IPC 资源:
$ipcs -m 查看系统使用的 IPC 共享内存资源
$ipcs -q 查看系统使用的 IPC 队列资源
$ipcs -s 查看系统使用的 IPC 信号量资源
查看 IPC 资源被谁占用
示例:有个 IPCKEY(51036),需要查询其是否被占用;首先通过计算器将其转为十六进制:
51036 -> c75c
如果知道是被共享内存占用:
$ipcs -m | grep c75c
0x0000c75c 40403197 tdea3 666 536870912 2
如果不确定,则直接查找:
$ipcs | grep c75c
0x0000c75c 40403197 tdea3 666 536870912 2
0x0000c75c 5079070 tdea3 666 4
系统 IPC 参数查询
ipcs -l
清除 IPC 资源
ipcrm -M shmkey 移除用 shmkey 创建的共享内存段
ipcrm -m shmid 移除用 shmid 标识的共享内存段
ipcrm -Q msgkey 移除用 msqkey 创建的消息队列
ipcrm -q msqid 移除用 msqid 标识的消息队列
ipcrm -S semkey 移除用 semkey 创建的信号
ipcrm -s semid 移除用 semid 标识的信号
清除当前用户创建的所有的 IPC 资源:
ipcs -q | awk '{print"ipcrm -q "$2}' | sh > /dev/null 2>&1;
ipcs -m | awk '{print"ipcrm -m "$2}' | sh > /dev/null 2>&1;
ipcs -s | awk '{print"ipcrm -s "$2}' | sh > /dev/null 2>&1;
link
https://gpdb.docs.pivotal.io/6-0/install_guide/prep_os.html#topic_sqj_lt1_nfb~~~~