vm.overcommit_memory 구성의 영향


41

CentOS 5.4 (Linux 커널 2.6.16.33-xenU)에서 실행중인 VPS 웹 서버가 oom-killer 시작으로 인해 한 달에 한 번 또는 몇 주가 걸리는 것처럼 불규칙적으로 응답하지 않습니다. 서버를 모니터링하면 서버가 일반적으로 너무 자주 메모리가 부족합니다.

다음 sysctl 설정을 사용하여 오버 커밋을보다 잘 관리 할 수 ​​있도록 커널을 구성하는 방법을 설명 하는 이 페이지 를 가리키는 몇 가지 블로그를 읽었습니다 .

vm.overcommit_memory = 2
vm.overcommit_ratio = 80

이것에 대한 나의 이해 (잘못 될 수도 있지만 명확히 할 정식 정의를 찾을 수 없음)는 이것이 커널이 실제 메모리의 스왑 + 80 %를 초과하는 메모리 초과 할당을 방지한다는 것입니다.

그러나 나는 또한 읽고 몇 가지 이러한 설정은 좋은 아이디어 아니라는 것을 제안 다른 소스를 -이 방법의 비평가들이 가정한다는 점에서 "오히려이 kludge을하지는 않고, 시스템을 파괴하는 일을하지 않는다"말하는 것 같다 있지만, 원인은 항상 알려져 있습니다.

그래서 제 질문은 약 10 개의 트래픽이 적은 사이트를 호스팅하는 Apache2 웹 서버와 관련 하여이 접근법의 장단점이 무엇입니까? 필자의 경우 웹 서버에는 512Mb RAM이 있으며 1024Mb 스왑 공간이 있습니다. 이것은 대부분의 시간에 적합한 것으로 보입니다.

답변:


32

overcommit_ratio80으로 설정 하는 것이 올바른 조치가 아닐 수 있습니다. 값을 100 미만으로 설정하면 거의 항상 올바르지 않습니다.

그 이유는 리눅스 응용 프로그램이 실제로 필요한 것보다 더 많은 것을 할당하기 때문입니다. 두 개의 문자열을 저장하기 위해 8kb를 할당한다고 가정 해보십시오. 거기에 몇 KB가 사용되지 않습니다. 응용 프로그램은이 작업을 많이 수행하며 오버 커밋을위한 것입니다.

따라서 기본적으로 100 이상의 오버 커밋을 사용하면 커널은 응용 프로그램이 더 많은 메모리를 할당 할 수 없습니다 (스왑 + 램). 100 미만으로 설정하면 모든 메모리를 사용하지 않습니다. 이 설정을 설정하려면 앞에서 언급 한 시나리오로 인해 100보다 높게 설정해야합니다. 이는 매우 일반적입니다.

이제 OOM 킬러 트리거링 문제와 관련하여 수동 커밋을 설정해도 문제가 해결되지 않습니다. 기본 설정 (휴리스틱 결정)은 상당히 지능적입니다.

이것이 실제로 문제의 원인인지 확인 /proc/meminfo하려면 OOM 킬러 실행시기를 확인하십시오. 당신이 보는 경우 Committed_AS에 가까운 CommitLimit,하지만 free여전히 무료로 사용 가능한 메모리를 보여주고, 다음 예를 수동으로 시나리오의 오버 커밋을 조정할 수 있습니다. 이 값을 너무 낮게 설정하면 여전히 메모리가 충분할 때 OOM 킬러가 응용 프로그램 종료를 시작합니다. 너무 높게 설정하면 할당 된 메모리를 사용하려고 할 때 임의의 응용 프로그램이 종료 될 수 있지만 실제로는 사용 가능하지 않습니다 (모든 메모리가 실제로 사용되는 경우).


1
감사합니다-overcommit_ratio가 100으로 설정되어 어떤 일이 일어나고 있는지 확인하려고합니다. 내가 가진 주요 문제는 oom-killer가 시작될 때 sshd를 항상 죽여서 서버에 액세스하지 못하고 무슨 일이 일어나고 있는지 알 수 없다는 것입니다. 내가 정말로 필요로하는 것은 oom-killer가 실행되는 것을 막고 문제가 발생했을 때 발생하는 일을 기록하는 방법으로 문제의 원인을 찾을 수 있습니다.
dunxd

4
@dunxd /proc/<PID>/oom_score_adj이 목적으로 사용할 수 있습니다 . 예를 들어 sshd에 대해 oom_score_adj를 -1000으로 설정하면 oom killer는 무언가를 죽이고 싶을 때 sshd를 대상으로하지 않습니다. oom killer를 중지시키는 것은 완전히 좋은 생각이 아니므로 프로그램이 메모리를 몰수 할 수 없으므로 어쨌든 죽을 것입니다.
Patrick

4
@dunxd의 상속. init 스크립트가 자체적으로 설정하도록하고 init 스크립트에 의해 시작된 모든 것이이를 상속합니다.
Patrick

4
4KB 예가 잘못되었습니다. 가상 메모리는 페이지와 함께 사용되며 Linux에서 페이지의 가장 작은 크기는 4KB입니다. 즉, 몇 개의 문자를 저장하려면 초과 커밋 설정에 관계없이 4KB를 매핑해야합니다. 적절한 메모리 초과 확약의 예는 예를 들어 10KB를 할당하고 처음 4100 바이트 만 사용하는 것입니다. 즉, 2 개의 4KB 페이지가 데이터를 저장해야하고 1 개의 추가 페이지가 사용되지 않습니다. 오버 커밋하지 않는 시스템은 항상 요청이 도착하면 데이터를 저장할 수있는 세 번째 페이지를 준비해야합니다.
jlliagre

2
/ proc / self는 현재 프로세스를 가리 키므로 / proc / self / oom_score_adj를 사용하여 현재 프로세스의 oom_score_adj를 변경할 수 있습니다.
r_2

23

@dunxd가 언급 한 문서의 섹션 9.6 "오버 커밋 및 OOM"은 특히 오버 커밋을 허용하는 위험에 대한 그래픽입니다. 그러나 80나에게도 흥미로워 보였으므로 몇 가지 테스트를 수행했습니다.

내가 찾은 것은 overcommit_ratio모든 프로세스에 사용 가능한 총 RAM에 영향을 미친다 는 것입니다 . 루트 프로세스는 일반 사용자 프로세스와 다르게 취급되지 않는 것 같습니다.

비율 100이하로 설정하면 반환 값 malloc/sbrk이 신뢰할 수있는 클래식 시맨틱을 제공해야합니다 . 100캐싱 등과 같은 비 프로세스 활동에 더 많은 RAM을 예약하는 방법 보다 비율을 낮게 설정하십시오 .

그래서, 스왑과 RAM의 24 지브, 내 컴퓨터로, 9 지브 사용에서 사용 안 함 top을 보여주는

Mem:  24683652k total,  9207532k used, 15476120k free,    19668k buffers
Swap:        0k total,        0k used,        0k free,   241804k cached

다음은 overcommit_ratio램 소비 프로그램이 잡을 수있는 RAM 용량과 각 페이지를 터치하는 RAM 양 malloc입니다.

 50    ~680 MiB
 60   ~2900 MiB
 70   ~5200 MiB
100  ~12000 MiB

루트 사용자 인 경우에도 한 번에 여러 개를 실행해도 함께 소비 한 총량은 변경되지 않았습니다. 마지막 3+ GiB 정도를 소비 할 수 없다는 것이 흥미 롭습니다. 이 free많은 여기에 표시된 무슨 이하로 떨어지지 않았다 :

Mem:  24683652k total, 20968212k used,  3715440k free,    20828k buffers

많은 프로그래머가 C에서 malloc 오류를 확인하는 데 끔찍하고 일부 인기있는 콜렉션 라이브러리는 완전히 무시하고 C ++ 및 기타 여러 언어는 보다 나쁜.

내가 본 가상 RAM의 초기 구현의 대부분은 매우 큰 경우를 처리하는 것이 었습니다. 가용 메모리의 51 % +와 같은 하나의 큰 프로세스 fork()exec()일부 지원 프로그램 (보통 훨씬 훨씬 작은 프로세스) 을 위해 필요했습니다 . COW (copy-on-write) 시맨틱이있는 OS는을 허용 fork()하지만 포크 프로세스가 실제로 너무 많은 메모리 페이지를 수정하려고 시도한 경우 (각각 초기 초기 프로세스와 독립적 인 새 페이지로 인스턴스화해야 함) 결국 살해 당할 것입니다. 상위 프로세스는 더 많은 메모리를 할당하고 일부 경우 다른 프로세스가 종료 될 때까지 기다렸다가 계속해서 부족을 처리 할 수있는 경우에만 위험에 처했습니다. 자식 프로세스는 일반적으로 다음을 통해 (일반적으로 작은) 프로그램으로 대체되었습니다.exec() 그리고 나서 프로 비소가 없었습니다.

Linux의 오버 커밋 개념은 fork()단일 프로세스를 전체적으로 대량으로 처리 할 수있을뿐만 아니라 발생 을 허용하는 극단적 인 접근 방식 입니다. OOM 킬러로 인한 사망 메모리 할당을 책임감있게 처리 하는 프로그램에서도 비동기 적으로 발생 합니다. 나는 개인적으로 시스템 전반의 오버 커밋과 특히 옴 킬러를 개인적으로 싫어 합니다. 라이브러리를 감염시키는 메모리 관리 및 라이브러리를 사용하는 모든 앱을 통해 악마 관리 접근 방식을 장려합니다.

비율을 100으로 설정하고 스왑 파티션을 사용하여 일반적으로 거대한 프로세스에서 사용하게되는 스왑 파티션을 사용하는 것이 좋습니다. 스왑 파티션은 스왑에 들어가는 부분의 작은 부분 만 사용하므로 종종 대부분의 프로세스를 OOM 킬러의 잘못된 기능으로부터 보호하십시오. 이렇게하면 웹 서버가 무작위로 사망 malloc하지 않도록 안전하게 보호해야하며 책임 있게 처리하도록 작성된 경우 자체를 죽이지 않아도 안전합니다 (그러나 후자는 내기하지 마십시오).

이것은 내가 이것을 사용하고 있음을 의미합니다. /etc/sysctl.d/10-no-overcommit.conf

vm.overcommit_memory = 2
vm.overcommit_ratio = 100

vm.overcommit_memory를 2로 유지하는 것이 좋습니다?
Ut xD

1
좋은 참고 사항-그것은 실제로 내가 사용하고있는 것입니다. 나는 이미 질문에 있기 때문에 내 대답에서 그것을 생략했다고 생각합니다
Alex North-Keys
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.