여유 메모리가 많은 영구 스왑

여유 메모리가 많은 영구 스왑

32G RAM이 설치되고 16G 스왑이 구성된 Debian 4.0.5(커널 4.0.0-2)를 실행하는 Linux 서버가 있습니다. 시스템은 파티셔닝을 위해 lxc 컨테이너를 사용하지만 여기서는 중요하지 않습니다. 문제는 다른 컨테이너 내부와 외부에 존재합니다.

전형적인 것은 다음과 같습니다 free -h.

              total        used        free      shared  buff/cache   available
Mem:            28G        2.1G         25G         15M        936M         26G
Swap:           15G        1.4G         14G

/proc/meminfo가지다

Committed_AS:   12951172 kB

따라서 할당된 모든 것을 실제로 즉시 사용하더라도 여전히 여유 메모리가 많이 남아 있습니다. 그러나 시스템은 실행 중인 프로세스도 즉시 페이징합니다.

iotop이는 Unicorn을 사용하는 Rails 애플리케이션인 Gitlab에서 가장 두드러집니다. 새로 분기된 Unicorn 작업자 스레드는 즉시 교체되며 요청이 수신되면 디스크에서 약 1400kB/s(의 데이터 ) 로 읽어야 하며 제한시간(현재 30초)을 설정하여 제때에 다시 시작할 수 있도록 합니다. 일반 요청은 메모리에 완전히 로드되어 즉시 종료되기까지 5초 이상 걸리지 않아야 합니다. 이것은 단지 예일 뿐이며 redis, amavis, postgres, mysql, java(openjdk) 등에서 이런 일이 발생하는 것을 보았습니다.

그렇지 않으면 시스템의 부하가 낮아서 CPU 사용률이 약 5%이고 부하 평균이 약 2(8개 코어)입니다.

우리가 시도한 것(특정 순서 없음):

  1. swapoff -a: 800M 정도 교환 실패
  2. 감소된 교환성을 사용합니다(단계별) sysctl vm.swappiness=NN. 전혀 효과가 없는 것 같습니다. 0%로 떨어졌지만 여전히 동일한 동작을 보입니다.
  3. 필수적이지 않은 서비스(Jetty 기반 웹 애플리케이션인 Gitlab...)를 중지하고 대략적으로 릴리스합니다. 8G의 커밋되었지만 매핑되지 않은 메모리와 Comfilled_AS를 약 5G로 줄입니다. 전혀 변한 것이 없습니다.
  4. 명확한 시스템 캐시를 사용하십시오 sync && echo 3 > /proc/sys/vm/drop_caches. 이렇게 하면 메모리가 해제되지만 스왑 사례에는 아무 작업도 수행되지 않습니다.
  5. 위의 조합

테스트로 fstab을 통해 스왑을 완전히 비활성화하기 위해 시스템을 재부팅하는 것은 실제로는 옵션이 아닙니다. 일부 서비스에는 가용성 문제가 있고 "사냥"보다는 계획된 가동 중지 시간이 필요하기 때문입니다. 그리고 우리는 대체적으로 스왑을 비활성화하고 싶지 않습니다. .

여기서 왜 교환이 일어나는지 이해가 안 돼요. 무슨 일이 일어날 지 아이디어가 있습니까?


이 문제는 한동안 존재했지만 높은 IO 로드(긴 백그라운드 데이터 처리 작업) 중에 처음 나타났기 때문에 특정 이벤트를 정확히 찾아낼 수는 없습니다. 이 작업이 완료된 지 며칠이 지났으나 문제가 여전히 지속되어 이 질문이 발생합니다.

답변1

내가 말한 것을 기억하세요:

시스템은 파티셔닝을 위해 lxc 컨테이너를 사용하지만 여기서는 중요하지 않습니다.

글쎄, 그것은 밝혀졌다했다문제. 아니면 오히려 lxc의 중심에 있는 cgroup이 중요합니다.

호스트는 커널이 업그레이드될 때만 재부팅됩니다. 그렇다면 마지막으로 사용된 커널은 무엇이었나요? 3.19는 두 달 전 4.0.5와 어제 4.1.3으로 대체되었습니다. 어제 무슨 일이 있었나요? 왼쪽, 오른쪽, 중앙의 프로세스가 멤킬됩니다. 검사 결과 /var/log/kern.log, 영향을 받은 프로세스는 메모리가 512M인 cgroup에 있습니다. 잠깐, 512M? 이는 옳지 않습니다(예상 요구 사항이 약 4G인 경우!). 밝혀진 바와 같이, 이것은 우리가 몇 달 전에 설정할 때 lxc 구성에서 구성된 것과 정확히 같습니다.

따라서 3.19는 cgroup의 메모리 제한을 완전히 무시합니다. 4.0.5는 허용된 것보다 더 많은 cgroup이 필요한 경우 항상 페이징을 수행하며(이것이 이 문제의 핵심임) 4.1.3만이 전체 memkiller-sweep을 수행합니다.

호스트 시스템의 스왑 가능성은 물리적 메모리가 거의 부족해지지 않기 때문에 이에 영향을 미치지 않습니다.

해결책:

box1임시 변경의 경우 예를 들어 cgroup이라는 lxc 컨테이너를 호출하여 cgroup을 직접 수정할 수 lxc/box1있으며 호스트 시스템에서 루트로 다음을 실행할 수 있습니다.

$ echo 8G > /sys/fs/cgroup/memory/lxc/box1/memory.limit_in_bytes

영구적인 해결책은 컨테이너를 올바르게 구성하는 것입니다./var/lb/lxc/...

lxc.cgroup.memory.limit_in_bytes = 8G

이야기의 교훈:항상 구성을 확인하세요. 이것이 문제가 될 수 없다고 생각하더라도(실제로 실패하는 커널에는 다른 버그/불일치가 있습니다).

관련 정보