Shared Memory
shmmax
한 shared memory 세그먼트의 최고 크기로 byte 단위. 이는 리눅스 프로세스가 할당할 수 있는 virtual address space이다.
hugepage를 쓴다면 hugepage의 수치와 맞게 정하는 것을 강력하게 추천하고 있다 by redhat. 그런데 예시 문서는 그냥 나누기 2를 하고 있다..
오라클은 총 메모리 사이즈의 50%를 정할 것을 추천하고 있다. 하지만 SGA 영역이 50% 이상으로 잡혀있다면 이리 하면 안되겠지
1. 오라클 권장대로 하자면
cat /proc/meminfo 로 확인
Memtotal: 16777216 kb
2. 계산: 16777216*1024/2 = 8589934592
3. 입력 /etc/sysctl.conf
kernel.shmmax=8589934592
shmmni
시스템의 shared memory 세그먼트 최고 갯수를 정한다. 오라클은 10g에서 최소 4096을 정할것을 권장하고, 4096이나 그 이상을 정하는게 좋다.
kernel.shmmni=4096
shmall
페이지 단위로, shared memory의 총 갯수로 시스템이 한번에(use at one time) 쓸수 있는 양이다.
OS 메모리/page_size
1. pagesize 확인
getconf PAGE_SIZE
4096
2. 16GB ram이라면 계산
16*1024*1024*1024/4096=4194304
3. /etc/sysctl.conf 적용
kernel.shmall=4194304
semaphore
세마포어는 공유 리소스(예:shared memory)를 사용하는 프로세스와 같이 동작하는 프로세스 혹은 쓰레드간의 동기화를 위해 사용되는 counter이다.
어플리케이션이 세마포어를 요청하면 커널은 세마포어의 sets를 release한다.
semmsl
set당 세마포어의 갯수. 권장값은 250이다.
그러나 만약 천개 이상의 커런트 커넥션이 DB와 연결되고 있다면 init 파라미터의 process 값은 매우 클 것이다.
그렇다면 semmsl 값도 마찬가지로 커져야 한다.
semmsl 값은 processes 파라미터 값 + 10 정도가 적절하다. 이는 현재 프로세스의 갯수와 연관이 크다.
semmni
리눅스 전체 세마포어 sets의 최대 갯수로 10.2와 11.1은 오라클에서 validate된 수치로
142 이다
semmns
OS상의 총 세마포어의 갯수를 의미한다(not 세마포어 sets). semmsl * semmni 값보다 커야하나 보통 동일하게 설정한다.
오라클은 semmns 값을 최소 32000 설정할 것을 권장한다. 이 값은 semmsl * semmni(250*128=32000)으로부터 기인한다.
만약 위에서 들었던 예의 값을 이용해 계산하면 250 * 142 = 35500
semopm
세마포어 콜당 작동할 수 있는 세마포어 작업의 최대값이다. semmsl 값과 동일하게 설정할 것을 권장한다.
오라클은 100이 10.2와 11.1 버전에 validated로 되어있다
만약 semmsi 값이 250이라면 semmsl도 250으로 한다.
설정예시
/etc/sysctl.conf
kernel.sem=550 78100 550 142
순서대로 semmsl, semmns, semopm, semmni 이다.
page cache tuning
페이지 캐쉬는 파일의 데이터나 실행 프로그램을 잡고 있는 디스크 캐시이다. 디스크 읽기를 줄이기 위해 사용한다.
swappiness
이 값은 기본값이 60
값이 높을수록 페이지캐쉬가 많아짐
값이 낮을수록 페이지캐쉬가 적어짐
그런데 hugepage를 사용할 경우 이건 필요 없음
hugepage 미사용시 only DB만을 위한 서버라면
/etc/sysctl.conf
vm.swappiness=0
dirty_writeback_centisecs(default 500)
리눅스는 pdflush 커널 쓰레드들을 통해 페이지캐시를 비워낸다. 2에서 8개의 쓰레드가 보통 시스템에서 활동한다.
/proc/sys/vm/nr_pdflush_threads 로 확인 가능
만약 모든 pdflush 쓰레드들이 최소 1초이상 바쁘다고 판단되면 pdflush 쓰레드가 추가된다.
추가된 쓰레드는 데이터를 디스크큐에 쓰게 되고 이는 혼잡이 발생하지 않는다.
pdflush 쓰레드가 1초간 활성화되지 않으면 하나씩 줄어들게 된다.
dirty_writeback_centisecs 는 얼마만큼의 간격으로 페이지캐시를 비워내는가의 수치이며 기본값이 500이다.
이 값을 낮추면 메모리가 많고 활성화된 쓰기 프로세스가 많은 경우 이점이 있다.
이 값을 낮추면 pdflush 쓰레드가 공격적으로 dirty page를 클리닝할 수 있게 한다.
결과로 한번에 비워내야할 page들의 수가 줄어들게 된다. 100(1초)보다 낮게 잡는건 무리가 있다.
vm.dirty_writeback_centisecs=100
dirty_expire_centisecs(default 3000=30sec)
만료된것으로 간주되고 반드시 다음 기회에 write되기 전까지 얼마나 오랫동안 페이지캐시에 데이터가 있을 수 있는지를 정한다.
이 값은 기본 30초로 굉장이 긴 편이다. 이것은 일반적인 상황에서 다른 pdflush 가 동작되어 디스크에 write하기까지 리눅스는
30초가 지나기 전까지 실제로 commit하지 않는다는 의미이다. 일반적인 desctop에서는 수용할만하지만 쓰기가 많은 작업에는 너무 높다.
너무 낮게 설정하지는 않으면서 낮출 필요가 있다. 너무 낮을 시에는 지속적인 dirty page를 쓰기 시도하기에 I/O 혼잡 코드가 더 빈번히
발생할 수 있다.
vm.dirty_expire_centisecs=500
dirty_background_ratio(default 10)
pdflush가 동작하여 write하기 전에 dirty page로 채워질 수 있는 활성된 메모리의 최고 비율을 말한다.
active memory 값은 meminfo로 확인할 수 있고
MemFree + Cached - Mapped 이다.
큰 메모리와 헤비한 writing 어플리케이션 환경이라면 튜닝할 필요가 있다.
리눅스가 데이터를 너무 많이 버퍼링하여 이슈가 된다. 이는 파일시스템이 시스템 call인 fsync를 통해 동기화가 필요할 시 문제가 된다.
만약 너무 많은 데이터가 버퍼캐쉬에 있는 상태에서 fsync call이 들어올 경우 시스템이 약간의 시간동안 프리징될 수 있다.
또 다른 이슈로 많은 write되어야 할 데이터가 캐쉬되어 물리적으로 쓰기 시작될 때 I/O 부하가 생긴다.
리눅스가 데이터를 너무 많이 캐쉬하지 않게 하기 위해 이 값을 줄이는 것이 효과적이다.
vm.dirty_background_ratio=3
dirty_ratio(default 40)
유저 프로세스가 dirty buffer로 쓰여지기 전에 dirty page로 채워질 수 있는 총 메모리량의 최고 비율
Maximum percentage of total memory that can be filled with dirty pages before user processes are forced to write dirty buffers
themselves during their time slice intead of being allowed to do more writes.
Note that all processes are blockes for writes when this happens, not just the one that filled the write buffers.
This can cause that is perceived as an unfair behavior where a single process can "hog" all I/O on the system.
Applications that can cope with their writes being blocked altogether might benefit from substantially decreasing this value
vm.dirty_ratio=15
memory
vm.min_free_kbytes
최소로 유지해야하는 free 메모리의 양을 결정한다.
vm.min_free_kbytes=50000
vm.highmem_is_dirtyable
rhel6부터 지원. 페이지 반환이 좀더 빠르게 된다.
vm.highmem_is_dirtyable=1
file
file-max
프로세스가 한번에 file descriptor(handler)를 열수 있는 최고치
ASM을 사용한다면 상관 없다.
10g => fs.file-max=65536
11g => fs.file-max=6553600
좀더 대규모환경이라면 327679 로 설정하는 것도 좋다.
network
오라클 RAC는 기본적으로 linux에서 interconnect를 위해 UDP를 사용한다.
리눅스 2.6 커널이상은 기본적으로 receive/send 소켓 버퍼를 자동 튜닝하지만 수치가 적어질 수 있다.
rmem_default
소켓 receive 버퍼 기본 크기. 오라클 권장 256kb
net.core.rmem_default=262144
wmem_default
소켓 send 버퍼 기본 크기. 오라클 권장 256kb
net.core.wmem_default=262144
rmem_max
receive 버퍼 최고치. 오라클 권장 10gr2는 2mb, 11g이상은 4mb
net.core.rmem_max=2097152
or
net.core.rmem_max=4194304
wmem_max
send 버퍼 최고치. 오라클 권장 256kb
10g => net.core.wmem_max=262144
11g => net.core.wmem_max=1048576
tcp_rmem, tcp_wmem
이들도 추가적으로 설정해야 한다. auto tuning때문에 작은 수치가 나올 수 있다.
순서대로 최소치, default, 최고치의 버퍼 크기이다.
net.ipv4.tcp_rmem=4096 262144 2097152
net.ipv4.tcp_wmem=4096 262144 262144
ipv4.ip_local_port_range
redhat => net.ipv4.ip_local_port_range = 1024 65000
oracle => net.ipv4.ip_local_port_range = 9000 65500
빠른 rac failover를 위한 설정(클라이언트측 설정이므로 서버에는 설정 불필요)
net.ipv4.tcp_keepalive_time=30(redhat권장,pro rac) or 3000(오라클문서). 기본값 7200초
net.ipv4.tcp_keepalive_intvl=60 (redhat,pro rac) 기본값 75초
net.ipv4.tcp_keepalive_probes=9 (redhat,pro rac) 기본값도 9
net.ipv4.tcp_retries2=3 (redhat, pro rac원서) 기본값 15
net.ipv4.tcp_syn_retries=2 (redhat, pro rac) or 1(오라클문서) 기본값 5
기타
보안 이슈때문에 ip_forward는 0으로
net.ipv4.ip_forward = 0
역시 보안 이슈때문에 1로 설정. 아이태니엄은 기본이 1임
net.ipv4.conf.default.rp_filter = 1
swap
적정 swap size
1g~2g = 1.5 * total ram
2g~4g = 1 * total ram
4g 이상 = 4gb
aio
fs.aio-max-nr
현재 비동기 I/O 요청 갯수 제한
기본값은 65536(64k)로 오라클 디비에겐 너무 작다.
오라클은 3145728 값을 권장한다.
fs.aio-max-nr = 3145728