스왑 오프가 어떻게 느려질 수 있습니까? 200MB / s를 쉽게 복사

어떻게 든 14GB의 메모리를 교체했습니다. 범인을 죽인 후, 나는 다시 많은 양의 여유 메모리를 가지고있어서 중요한 데이터를 다시 가져올 수 있다고 생각 했다. 따라서 32GB 중 5GB를 사용하고 14GB의 스왑 공간을 사용하여 swapoff -a…..를 실행 했으며 약 4 시간 후에 작업의 절반이 완료되었습니다.

이것은 1MB / s 미만을 의미하지만 200MB / s를 쉽게 복사 할 수 있습니다. 내 스왑은 암호화되었지만 모든 일반 파티션과 마찬가지로 aes-ni를 사용 하면 눈에 띄는 CPU로드가 발생하지 않습니다 (스왑 공간을 채우는 데 몇 분 밖에 걸리지 않았습니다). 최적화해야 할 특별한 이유는 swapoff없지만 어떻게 느려질 수 있을지 궁금합니다.


더 많은 데이터 추가하기 : 메인 메모리는 32GB이고 4 개의 하드 디스크 각각에 32GB의 스왑 공간이 있습니다. 전체 스왑 공간은 5 분 이내에 해독 (읽고 해독 가능) 할 수 있습니다.

time -p sudo sh -c 'for i in /dev/mapper/cryptswap?; do md5sum $i & done; wait'
014a2b7ef300e11094134785e1d882af  /dev/mapper/cryptswap1
a6d8ef09203c1d8d459109ff93b6627c  /dev/mapper/cryptswap4
05aff81f8d276ddf07cf26619726a405  /dev/mapper/cryptswap3
e7f606449327b9a016e88d46049c0c9a  /dev/mapper/cryptswap2
real 264.27

파티션의 일부를 읽는 것이 모든 것을 읽는 것보다 느릴 수는 없습니다. 그러나 약 10 분의 1을 읽는 데는 약 100 배가 걸립니다.

나는 swapoff두 CPU 동안 대부분 유휴 상태 (아마도 한 코어의 10 %)와 디스크 (LED에 의해 “측정”)가 유휴 상태 인 것을 관찰했다 . 또한 스왑 공간이 차례로 꺼지는 것을 보았습니다.



답변

먼저, 하드 드라이브에서 기대할 수있는 것을 살펴 보겠습니다. 하드 드라이브는 200MB / s를 순차적으로 수행 할 수 있습니다 . 탐색 시간을 고려하면 훨씬 느려질 수 있습니다 . 임의의 예를 선택하려면 Seagate의 최신 3TB 디스크 중 하나 인 ST3000DM001 의 사양을 살펴 보십시오 .

  • 최대 지속 데이터 속도 : 210MB / s

  • 평균 판독 값 찾기 : <8.5ms

  • 섹터 당 바이트 : 4,096

검색 할 필요가없고 스왑이 디스크 가장자리에 가까운 경우 최대 속도 = 210MB / s 까지 예상 할 수 있습니다.

그러나 스왑 데이터가 완전히 조각난 경우 최악의 시나리오에서는 읽은 모든 섹터를 찾아야합니다. 즉, 8.5ms마다 4KB 또는 4KB / 0.0085 = 470KB / s 만 읽을 수 있습니다.

따라서 배트 바로 에서 실제로 하드 드라이브 속도에 맞서는 것은 상상할 수 없습니다 .


즉, swapoff너무 느리게 실행되고 페이지가 빠르게 작성된 경우 (순서대로) 페이지를 순서대로 읽어야 하는 것은 어리석은 것처럼 보입니다 . 그러나 그것은 커널이 작동하는 방식 일 수 있습니다. 우분투 버그 보고서 # 486666 은 같은 문제를 논의합니다 :

The swap is being removed at speed of 0.5 MB/s, while the
hard drive speed is 60 MB/s;
No other programs are using harddrive a lot, system is not under
high load etc.

Ubuntu 9.10 on quad core.

Swap partition is encrypted.
Top (atop) shows near 100% hard drive usage
  DSK | sdc | busy 88% | read 56 | write 0 | avio 9 ms |
but the device transfer is low (kdesysguard)
  0.4 MiB/s on /dev/sdc reads, and 0 on writes

답글 중 하나는 다음과 같습니다.

It takes a long time to sort out because it has to rearrange and flush the
memory, as well as go through multiple decrypt cycles, etc. This is quite
normal

버그 보고서가 해결되지 않았습니다.

Mel Gorman의 저서 ” Linux Virtual Memory Manager 이해 “는 약간 오래되었지만 이것이 느리게 작동한다는 데 동의합니다.

영역 비활성화를 담당하는 기능을 충분히 예측할 수 sys_swapoff()있습니다. 이 기능은 주로 swap_info_struct. 각 페이지 아웃 페이지에서 페이징하는 주요 작업은 책임 try_to_unuse()
매우 높습니다.

linux-kernel 메일 링리스트에서 2007 년부터 ” 스왑 오프 속도 향상 “이라는 주제에 대해 조금 더 논의하고 있습니다. 비록 그들이 논의하고있는 속도가보고있는 것보다 약간 높습니다


swapoff거의 사용되지 않기 때문에 아마도 일반적으로 무시되는 흥미로운 질문입니다 . 나는 당신이 정말로 그것을를 추적하고자한다면, 첫 번째 단계는 더 신중 디스크 사용 패턴을 시청하려고 할 것이라고 생각한다 (아마와 함께 atop, iostat또는 더욱 강력한 도구와 같은 perf또는 systemtap). 찾아야 할 것은 과도한 탐색, 작은 I / O 작업, 지속적인 재 작성 및 데이터 이동 등일 수 있습니다.


답변

SSD가있는 랩톱에서 동일한 문제가 발생했기 때문에 탐색 시간은 문제가되지 않습니다.

나는 다른 설명을 찾았다 . 여기 발췌가 있습니다

현재 작동 방식에 따라 swapoff는 스왑 파티션에서 스왑 아웃 된 각 메모리 페이지를보고이를 사용하는 모든 프로그램을 찾습니다. 만약 그것들을 바로 찾을 수 없다면, 그것들을 찾기 위해 실행중인 모든 프로그램의 페이지 테이블을 볼 것입니다. 최악의 경우 파티션에서 스왑 아웃 된 모든 페이지에 대해 모든 페이지 테이블을 검사합니다. 맞습니다. 동일한 페이지 테이블을 계속해서 확인합니다.

따라서 다른 것보다는 커널 문제입니다.


답변

그래, 그 swapoff메커니즘은 엄청나게 비효율적입니다. 해결 방법은 쉽습니다. 프로세스를 반복하는 대신 스왑 된 페이지를 반복하는 것입니다. 이 파이썬 스크립트를 사용하십시오 (나는 제휴하지 않습니다).

git clone https://github.com/wiedemannc/deswappify-auto

데몬 작동 모드는 최대 절전 모드 인 데스크톱 / 노트북에만 해당됩니다. 서버 시스템에서 데몬으로 실행하지 않습니다. 포 그라운드에서 실행하고 일부 프로세스를 처리했다고보고 될 때까지 기다렸다가 중지하고 시도하십시오.

swapoff /dev/x

대부분의 페이지가 이제 스왑과 메모리에 모두 존재하기 때문에 swapoff할 일이 거의 없으며 매우 빠릅니다 (수백 MB / s 보았습니다).

연혁

전술 파이썬 스크립트를 차례로 내 개선했다이 답변의 나머지를 기반으로 이 오래된 대답 에 의해 작성된 jlong를 . 스크립트가 훨씬 안전 하므로 마지막 방어선으로 나머지 답변을 시도하는 것이 좋습니다 .

perl -we 'for(`ps -e -o pid,args`) { if(m/^ *(\d+) *(.{0,40})/) { $pid=$1; $desc=$2; if(open F, "/proc/$pid/smaps") { while(<F>) { if(m/^([0-9a-f]+)-([0-9a-f]+) /si){ $start_adr=$1; $end_adr=$2; }  elsif(m/^Swap:\s*(\d\d+) *kB/s){ print "SSIZE=$1_kB\t gdb --batch --pid $pid -ex \"dump memory /dev/null 0x$start_adr 0x$end_adr\"\t2>&1 >/dev/null |grep -v debug\t### $desc \n" }}}}}' | sort -Vr | head

이것은 어쩌면 2 초 실행하고 실제로는 아무것도하지 않습니다, 단지 상위 10 메모리 세그먼트를 (실제로는 더 한 라이너를 인쇄 목록, 그래, 난 않는 복사하고 붙여 넣습니다, 단지 명령을 검토 될 위험을 감수 할 수있는 하나 – 라이너 사랑 쉘; 이들은 실제로 스왑에서 읽습니다).

...Paste the generated one-liners...
swapoff /your/swap    # much faster now

메인 one-liner는 많은 / proc를 읽는 것을 제외하고는 안전합니다.

수동 검사를 위해 준비된 하위 명령은 안전하지 않습니다 . 각 명령은 스왑에서 메모리 세그먼트를 읽는 동안 하나의 프로세스를 정지시킵니다. 따라서 일시 중지를 허용하지 않는 프로세스에서는 안전하지 않습니다. 내가 본 전송 속도는 분당 1 기가 바이트 정도였습니다. (위의 파이썬 스크립트는 그 결함을 제거했습니다).

또 다른 위험은 시스템에 너무 많은 메모리 압력을 가하는 것이므로 일반적인 사항을 확인하십시오. free -m

무엇을합니까?

for(`ps -e -o pid,args`) {

  if(m/^ *(\d+) *(.{0,40})/) {
    $pid=$1;
    $desc=$2;

    if(open F, "/proc/$pid/smaps") {

      while(<F>) {

        if(m/^([0-9a-f]+)-([0-9a-f]+) /si){
          $start_adr=$1;
          $end_adr=$2;
        } elsif( m/^Swap:\s*(\d\d+) *kB/s ){
          print "SSIZE=$1_kB\t gdb --batch --pid $pid -ex \"dump memory /dev/null 0x$start_adr 0x$end_adr\"\t2>&1 >/dev/null |grep -v debug\t### $desc \n"
        }
      }
    }
  }
}

이 perl 스크립트의 출력은 스왑 된 페이지를 메모리로 호출 하는 일련의 gdb명령 dump memory (range)입니다.

출력은 크기로 시작하므로 | sort -Vr | head크기 (SSIZE)로 상위 10 개의 가장 큰 세그먼트를 얻기 위해 통과 할 수 있습니다. -V버전 번호-적절한 정렬을위한 스탠드,하지만 내 목적을 위해 사용할 수 있습니다. 숫자 정렬 작업을 수행하는 방법을 알 수 없었습니다.


답변

스왑 오프 중에 사용중인 스왑 슬롯이 감지되면 커널은 먼저 페이지에서 스왑합니다. 그런 다음 unuse_process () 함수는 방금 스왑 된 페이지에 해당하는 모든 페이지 테이블 항목을 찾으려고 시도하여 페이지 테이블을 업데이트합니다. 검색은 철저하고 시간 소모적입니다. 전체 시스템의 모든 메모리 설명자를 방문하여 페이지 테이블 항목을 하나씩 검사합니다.

“Linux Kernel 3rd 버전 이해”의 724 페이지를 참조하십시오.