
IO 속도를 늦추는 Linux 페이지 캐시에 큰 문제가 있습니다. 예를 들어 dd를 사용하여 lvm 파티션을 복사하면 Linux는 버퍼나 캐시(free –m)에 데이터를 캐시합니다. 문제는 아니지만 버퍼가 특정 값에 도달하면 복사 프로세스가 중지되고 몇 mbs 또는 심지어 kbs까지 느려집니다. 디스크 또는 /dev/null에 쓰기 작업을 수행하면서 많은 테스트를 수행했지만 문제는 소스 드라이브나 대상과 아무 관련이 없습니다.
상세히:
- 거의 동일한 서버가 두 개 있습니다. 둘 다 동일한 커널로 CentOS 6.5를 실행합니다. 그들은 동일한 디스크, 동일한 설정, 동일한 기타 하드웨어를 가지고 있으며 모든 면에서 동일합니다. 유일한 차이점은 한 서버에는 CPU 2개와 64GB RAM이 있고 다른 서버에는 CPU 1개와 32GB RAM이 있다는 것입니다.
- 다음 복사 프로세스의 이미지도 있습니다.https://i.stack.imgur.com/tYlym.jpg
- 여기에 meminfo가 포함된 새 버전도 있습니다. meminfo는 다른 실행에서 나온 것이므로 값은 동일하지 않지만 완전히 동일한 동작은 아닙니다.https://i.stack.imgur.com/4SIJG.jpg
- dd 또는 기타 파일 시스템 복사 프로그램을 사용하여 복사를 시작합니다.
- 버퍼 또는 캐시가 채워지기 시작합니다. 모두 괜찮습니다.
- 버퍼 또는 캐시가 최대 수에 도달함(64GB RAM 서버에서는 32GB 또는 17GB와 같은 값, 32GB RAM 서버에서는 모든 사용 가능한 메모리)
- 64GB RAM 서버에서 복사 프로세스가 이제 중지되거나 몇 MB로 제한됩니다. 32GB RAM 서버에서는 모든 것이 정상입니다.
- 64GB RAM 서버에서는 "sync; echo 3 > /proc/sys/vm/drop_caches"를 사용하여 캐시를 강제 실행하여 잠시 동안 문제를 해결할 수 있습니다. 하지만 당연히 버퍼가 즉시 다시 커지기 시작하고 문제가 다시 발생합니다.
결론:
문제는 두 번째 CPU 또는 총 메모리 양과 관련이 있습니다. 문제가 있을 수 있다는 "느낌"이 있습니다. 모든 CPU에는 자체 32GB RAM이 있고 복사 프로세스는 CPU에서만 실행된다는 것입니다. 그래서 마지막으로 복사 프로세스는 버퍼/캐시를 거의 32GB 또는 다른 CPU의 사용되지 않는 메모리로 늘렸고 Linux는 아직 메모리가 있다고 생각하므로 버퍼를 더 늘릴 수 있지만 아래 하드웨어는 메모리에 액세스할 수 없습니다. 그렇게.
누구든지 아이디어나 해결책이 있나요?물론 직접 플래그와 함께 dd를 사용할 수 있지만 삼바 등을 통한 외부 액세스도 있기 때문에 문제가 해결되지 않습니다.
편집1:
64GB RAM 서버의 /proc/zoneinfo도 여기에 있습니다. 1.http://pastebin.com/uSnpQbeD(dd가 시작되기 전) 2.http://pastebin.com/18YVTfdb(dd가 작동을 멈출 때)
편집2:
- VM 설정:http://pastebin.com/U9E9KkFS
- /proc/sys/vm/zone_reclaim_mode는 32GB RAM 서버 0과 64GB RAM 서버 1에 있었습니다. 저는 이 값을 절대 건드리지 않습니다. 설치 프로그램이 이를 설정했습니다. 임시 값을 0으로 변경하고 테스트를 다시 시도합니다. 이제 모든 메모리는 버퍼와 캐시에 사용됩니다. 그래서 보기에도 좋고 다른 서버와 비슷합니다. 하지만 즉시 최고 속도로 교환이 시작됩니다. 교환성을 0으로 설정했습니다. 도움이 되었지만 여전히 초당 몇 MB를 교환합니다. 그리고 매초마다 버퍼가 증가합니다. 따라서 버퍼를 교환하지 않고 vms의 메모리를 교환하여 버퍼를 늘리기 위해 더 많은 메모리를 얻습니다. 미친. 하지만 어쩌면 이것이 정상일까요!?
편집3:
/proc/buddyinfo 및 numactl --hardware: http://pastebin.com/0PmXxxin
최종 결과
- /proc/sys/vm/zone_reclaim_mode는 확실히 기술적으로 정확한 방법이지만 그 이후에는 기계가 잘 작동하지 않았습니다. 예를 들어, 디스크 Linux를 복사하면 이제 여유 메모리의 100%를 버퍼링에 사용합니다(이전에는 XGB만 사용한 다음 중지하지 않음). 그러나 마지막 여유 메모리가 버퍼링에 사용된 순간 Linux는 VM 메모리 교환을 시작하고 총 버퍼 및 캐시 양을 늘립니다. 내 시스템에서는 일반적으로 스왑이 필요하지 않으므로 스왑 메모리는 일부 VM과 동일한 디스크에 있습니다. 결과적으로 이러한 vms의 백업을 만들면 Linux는 백업을 위해 디스크에서 읽는 동시에 스왑을 작성합니다. 따라서 vms를 교체하는 것은 좋지 않지만 Linux가 내 백업 읽기 속도를 파괴한다는 것은 훨씬 더 나쁩니다... 따라서 /proc/sys/vm/zone_reclaim_mode를 0으로 설정해도 전체 문제가 해결되지 않습니다... 현재 저는 10초마다 캐시를 동기화하고 푸시하는 스크립트를 검사합니다. 좋지는 않지만 저에게는 훨씬 더 잘 작동합니다. 시스템에 웹서버나 일반 파일 서버가 없습니다. 저는 vms만 실행하고, 백업을 만들고, 삼바를 통해 백업을 저장합니다. 나는 해결책을 좋아하지 않는다.
답변1
보고 있는 동작은 Linux가 NUMA 시스템에서 메모리를 할당하는 방식으로 인해 발생합니다.
나는 32GB 시스템이 Numa가 아니거나 Linux가 관리할 만큼 Numa가 아니라고 가정합니다.
Numa를 처리하는 방법은 옵션에 따라 결정됩니다 /proc/sys/vm/zone_reclaim_mode
. 기본적으로 Linux는 Numa 시스템을 사용하고 있는지 감지하고 더 나은 성능을 제공할 것이라고 판단되면 회수 플래그를 변경합니다.
메모리는 여러 영역으로 나누어져 있으며, Numa 시스템에는 첫 번째 CPU 소켓을 위한 영역과 두 번째 CPU 소켓을 위한 영역이 있습니다. 이것들은 node0
및 로 나타납니다 node1
. 고양이를 키우면 볼 수 있습니다 /proc/buddyinfo
.
영역 회수 모드가 1로 설정되면 첫 번째 CPU 소켓의 할당으로 인해 해당 CPU와 연결된 메모리 영역에서 회수가 발생합니다. 이는 로컬 Numa 노드에서 회수하는 것이 성능 측면에서 더 효율적이기 때문입니다. 이러한 의미에서 회수는 캐시를 지우거나 해당 노드에서 항목을 교체하는 등 페이지를 삭제하는 것입니다.
값을 0으로 설정하면 영역이 채워지는 경우 회수가 발생하지 않고 대신 메모리에 대한 외부 Numa 영역에 할당됩니다. 이는 해당 메모리 영역에 대한 독점 액세스를 얻기 위해 다른 CPU를 잠시 잠그는 대가로 발생합니다.
하지만 즉시 교환이 시작됩니다! 몇 초 후: 메모리: 총 66004536k, 사용된 65733796k, 사용 가능한 270740k, 버퍼 34250384k 스왑: 총 10239992k, 사용된 1178820k, 사용 가능한 9061172k, 캐시된 91388k
스와핑 동작과 스와핑 시기는 몇 가지 요소에 의해 결정됩니다. 그 중 하나는 애플리케이션에 할당된 페이지의 활성 정도입니다. 활동량이 많지 않은 경우 캐시에서 발생하는 더 바쁜 작업을 위해 교체됩니다. VM의 페이지가 자주 활성화되지 않는다고 가정합니다.