- 과도한 스와핑으로 인해 응답하지 않거나 매우 느린 Linux 시스템을 다시 제어 할 수있는 가장 빠른 방법은 무엇입니까?
이미 Alt-SysRq-F로 답변했습니다
- 예를 들어 프로세스가 할당을 시도 할 수있는 메모리 양을 제한하여 이러한 스와핑을 방지 할 수있는 효과적인 방법이 있습니까?
나는이 두 번째 부분에 대답하고 있습니다. 예, ulimit
여전히 단일 프로세스를 제한하기에 충분합니다. 당신은 할 수 있습니다 :
- 통제 불능 상태 인 프로세스에 대한 소프트 한계 설정
- 추가 보험을 원할 경우 모든 프로세스에 대한 제한을 설정하십시오
또한 간단히 언급했듯이 :
CGroup을 사용하여 리소스 사용을 제한하고 이러한 문제를 방지 할 수 있습니다.
실제로 cgroup은 고급 제어 기능을 제공하지만 현재는 구성하기가 더 복잡합니다.
올드 스쿨 ulimit
일단 떨어져
간단한 예를 들면 다음과 같습니다.
$ bash
$ ulimit -S -v $((1*2**20))
$ r2(){r2 $@$@;};r2 r2
bash: xmalloc: .././subst.c:3550: cannot allocate 134217729 bytes (946343936 bytes allocated)
그것:
- 전체 메모리 사용의 소프트 제한을 1GB로 설정합니다 (ulimit는 kB 단위로 제한을 가정 함)
r2(){ r2 $@$@;};r2 r2
스택 메모리를 요청하는 동안 무한히 자신을 두 배로 늘려 CPU와 RAM을 기하 급수적으로 증가 시키는 재귀 bash 함수 호출 을 실행합니다 .
보시다시피 1GB 이상을 요청할 때 중지되었습니다.
참고 -v
(즉, 실제 + 스왑 총) 가상 메모리 할당을 운영하고 있습니다.
영구적 인 보호
가상 메모리 할당을 제한 as
하는 것은 -v
for 와 같습니다 limits.conf
.
단일 오작동 프로세스로부터 보호하기 위해 다음을 수행합니다.
- 모든 프로세스에 대해 하드 주소 공간 제한을 설정하십시오.
address space limit = <physical memory> - 256MB
.
- 따라서 욕심 많은 메모리 사용이나 활성 루프 및 메모리 누수를 가진 단일 프로세스는 모든 실제 메모리를 소비 할 수 없습니다.
- 256MB 헤드 룸은 ssh 또는 콘솔을 사용한 필수 처리를위한 것입니다.
짧막 한 농담:
$ sudo bash -c "echo -e \"*\thard\tas\t$(($(grep -E 'MemTotal' /proc/meminfo | grep -oP '(?<=\s)\d+(?=\skB$)') - 256*2**10))\" > /etc/security/limits.d/mem.conf"
이를 확인하기 위해 다음과 같은 결과가 발생합니다 (예 : 16GB 시스템).
$ cat /etc/security/limits.d/mem.conf
* hard as 16135196
$ ulimit -H -v
161351960
노트:
- 메모리를 사용하여 단일 프로세스에 대해서만 완화합니다.
- 메모리 부족으로 인해 스 래싱을 유발하는 다중 프로세스 워크로드를 방지하지 않습니다 (cgroup이 그 해답입니다).
rss
limits.conf에서 옵션을 사용하지 마십시오 . 최신 커널에서는 존중하지 않습니다.
- 보수적이다.
- 이론적으로 프로세스는 많은 양의 메모리를 추측 적으로 요청할 수 있지만 서브 세트 (작은 작업 세트 / 상주 메모리 사용) 만 적극적으로 사용합니다.
- 위의 하드 제한으로 인해 그러한 프로세스가 중단 될 수 있습니다 (리눅스가 가상 메모리 주소 공간을 초과 커밋 할 수있는 경우에는 프로세스가 제대로 실행 되더라도).
최신 C 그룹
더 많은 제어 기능을 제공하지만 현재 사용하기가 더 복잡합니다.
- ulimit 오퍼링을 향상시킵니다.
memory.max_usage_in_bytes
물리적 메모리를 개별적으로 설명하고 제한 할 수 있습니다.
- 반면
ulimit -m
및 / 또는 rss
에서 limits.conf
유사한 기능을 제공하는 것을 의미하지만 커널 리눅스 2.4.30 이후 일을하지 않는 한!
- bootloader에서 일부 커널 cgroup 플래그를 활성화해야합니다
cgroup_enable=memory swapaccount=1
.
- 우분투 16.04에서는 기본적으로 발생하지 않았습니다.
- 추가 회계 오버 헤드의 일부 성능 영향 때문일 수 있습니다.
- cgroup / systemd 제품은 비교적 새롭고 공정한 비트를 변경하기 때문에 플럭스 업스트림은 Linux 배포판 공급 업체가 아직 사용하기 쉽지 않은 것을 의미합니다. 14.04LTS와 16.04LTS 사이에서 cgroup을 사용하는 사용자 공간 도구가 변경되었습니다.
cgm
이제 공식적으로 지원되는 사용자 공간 도구 인 것 같습니다.
- 시스템 단위 파일은 아직 ssh와 같은 중요한 서비스의 우선 순위를 지정하기 위해 미리 정의 된 "공급 업체 / 디스트로"기본값을 가지고 있지 않은 것 같습니다.
예 : 현재 설정을 확인하려면 :
$ echo $(($(cat /sys/fs/cgroup/memory/memory.max_usage_in_bytes) / 2**20)) MB
11389 MB
$ cat /sys/fs/cgroup/memory/memory.stat
...
예를 들어 단일 프로세스의 메모리를 제한하려면 :
$ cgm create memory mem_1G
$ cgm setvalue memory mem_1G memory.limit_in_bytes $((1*2**30))
$ cgm setvalue memory mem_1G memory.memsw.limit_in_bytes $((1*2**30))
$ bash
$ cgm movepid memory mem_1G $$
$ r2(){ r2 $@$@;};r2 r2
Killed
실제로 RAM을 백그라운드 프로세스로 씹어 죽인 것을 보려면 :
$ bash -c 'cgm movepid memory mem_1G $$; r2(){ r2 $@$@;};r2 r2' & while [ -e /proc/$! ]; do ps -p $! -o pcpu,pmem,rss h; sleep 1; done
[1] 3201
0.0 0.0 2876
102 0.2 44056
103 0.5 85024
103 1.0 166944
...
98.9 5.6 920552
99.1 4.3 718196
[1]+ Killed bash -c 'cgm movepid memory mem_1G $$; r2(){ r2 $@$@;};r2 r2'
메모리 요청이 기하 급수적으로 증가하는 것에 주목하십시오.
앞으로는 "distro / vendors"가 SSH 및 그래픽 스택과 같은 중요한 요소에 대해 cgroup 우선 순위 및 제한 (시스템 단위를 통해)을 미리 구성하여 메모리가 고갈되지 않도록하겠습니다.