디스크 / 디스크 복사 속도를 늦춤


28

Linux에서 복사 프로세스를 느리게하는 방법이 있습니까?

10GB와 같은 큰 파일이 있는데 다른 디렉토리에 복사하고 싶지만 최대 속도로 복사하고 싶지 않습니다. 빠른 속도가 아닌 1mb / s의 속도로 복사하고 싶다고 가정 해 봅시다. 표준 Linux cp명령 을 사용하고 싶습니다 .

이것이 가능한가? (그렇다면 어떻게?)

편집 : 그래서, 내가 성취하려는 것에 더 많은 맥락을 추가 할 것입니다.

USB를 통해 대용량 파일을 (펜 드라이브, USB 디스크 등으로) 복사 할 때 ArchLinux 시스템에 문제가 있습니다. USB 버퍼 캐시를 채운 후 시스템이 응답을 멈 춥니 다 (마우스가 멈추더라도 산발적으로 만 움직입니다). 복사 작업이 계속 진행 중이지만 상자의 100 % 리소스가 필요합니다. 복사 작업이 완료되면 모든 것이 정상으로 돌아갑니다. 모든 것이 완벽하게 반응합니다.

어쩌면 하드웨어 오류 일지 모르지만이 문제가있는 두 대의 컴퓨터가 있다는 것을 알고 있습니다 (둘 다 ArchLinux에 있고, 하나는 데스크탑 상자이고 다른 하나는 랩톱입니다).

가장 쉽고 빠른 "솔루션"(이것은 '실제'솔루션이 아니며 추악한 '해킹'이 아닙니다)은 USB 드라이브의 평균 쓰기 속도로 파일을 복사 하여이 버퍼가 채워지지 않도록하는 것입니다. 충분할 것입니다.


7
시스템의 다른 I / O 바운드 프로세스에 "좋아"기 위해 디스크 간 복사 속도를 제한하려는 경우 커널의 I / O 일정 조정 기능을 활용하는 것이 좋습니다. 대신에. 특히 ionice디스크 간 복사 프로세스가 일반 프로세스보다 우선 순위가 낮은 I / O로 스케줄되도록하는 데 사용할 수 있습니다.
Steven 월요일

3
이것은 고전적인 XY 문제 질문입니다. 대신 파일을 USB 장치로 복사 할 때 데스크탑이 응답하지 않는 이유에 대해 문의해야합니다.
Michael Hampton

4
리눅스는 요즘 엄청나게 큰 I / O 버퍼를 가지고 있습니다. RAM 크기가 대용량 스토리지 속도보다 빠르게 증가했습니다. dd (1) 및 sync를 사용하여 복사를 수행하여 실제로 버퍼링하는 대신 주기적으로 동기화되도록 할 수 있습니까? 파이프 뷰어 (pv)에는 속도 제한 옵션이 있습니다. 같은 것 cat file | pv -L 3k > outfile. 그러나 cp (1)을 사용하는 것과 동일하지 않습니다.
ptman

@MichaelHampton, ArchLinux의 포럼 에서이 문제에 대해 해결되지 않은 몇 가지 주제가 있으므로 다른 방식으로 해결하려고 노력할 것입니다.
antonone

@antonone But Unix.SE는 ArchLinux의 포럼이 아닙니다. 여기 누군가가 해결책이있을 수 있습니다.
이즈 카타

답변:


23

파이프를 스로틀 pv -qL하거나 cstream -t유사한 기능을 제공 할 수 있습니다.

tar -cf - . | pv -q -L 8192 | tar -C /your/usb -xvf -

-q stderr 진행률보고를 제거합니다.

-L제한 바이트입니다.

에서 --rate-limit/-L플래그 에 대한 자세한 내용 man pv:

-L RATE, --rate-limit RATE

    Limit the transfer to a maximum of RATE bytes per second.
    A suffix of "k", "m", "g", or "t" can be added to denote
    kilobytes (*1024), megabytes, and so on.

이 답변은 원래 지적 throttle했지만 해당 프로젝트를 더 이상 사용할 수 없으므로 일부 패키지 시스템에서 벗어났습니다.


cp속도를 늦출 수 없다면 사용자 정의 명령을 사용하는 것이 유일한 옵션입니다.
antonone

1
다음과 비교하여 너무 복잡하게 들리는rsync
LinuxSecurityFreak

더 복잡해 보이지만 더 유용합니다. 파일 잠금 메커니즘을 테스트해야하며 rsync로는 불가능한 것으로 보이는 일부 바이트로 복사 속도를 늦춰야합니다. 그것을 시도하고 스로틀 파이프를 통해 파일을 '고양이'
cljk

슬프지만 프로젝트는 죽었습니다 bugs.debian.org/cgi-bin/bugreport.cgi?bug=426891
cljk

1
@cljk가로 업데이트되었습니다 pv. 감사.
매트

23

대신 필요에 따라 대역폭을 cp -a /foo /bar사용 rsync하고 제한 할 수도 있습니다 .

로부터 rsync수동이야 '

--bwlimit=KBPS

I / O 대역폭 제한; 초당 킬로바이트

따라서 진도를 보여주는 actuall 명령은 다음과 같습니다.

rsync -av --bwlimit=100 --progress /foo /bar

이것은 내가 원하지 않는 오래된 드라이브를 복사하는 좋은 아이디어처럼 들립니다.
jeremyjjbrown

에서 읽 /dev/zero거나 작동하지 않습니다/dev/random
cdosborn

rsync -a --bwlimit=1500 /source /destination1,5 MB / s 속도로 거대한 폴더를 복사하는 데 완벽하게 작동합니다 (서버 속도 저하를 피하고 시간이 많이 걸리지 않는 것이
좋습니다

참고 사항 : 매뉴얼 페이지에서 단위에 문자를 사용할 수 있다고 말할 수도 있지만, 예를 들어 20m모든 플랫폼에서 지원되는 것은 아니므로 KBytes 표기법을 따르는 것이 좋습니다.
허버트 Grzeskowiak

내 하루를 구했다! cgroup cgexec -g ... cp /in /out은 항상 작동하지 않았으며 (터미널에서 몇 번이나 스크립트에서 전혀 작동하지 않았 음) 왜 ​​그런지 모르겠습니다.
Aquarius Power

13

다른 활동을 방해하지 않으려 고 생각합니다. 최신 Linux 버전에는 ioniceIO 스케줄링을 제어 할 수있는 기능이 포함 되어 있습니다.

다양한 우선 순위를 허용하는 것 외에도 디스크가 유휴 상태 일 때 IO를 시간으로 제한하는 추가 옵션이 있습니다. 이 명령 man ionice은 설명서를 표시합니다.

다음과 같은 명령을 사용하여 파일을 복사하십시오.

ionice -c 3 cp largefile /new/directory

두 디렉토리가 동일한 장치에있는 경우 파일을 링크하면 원하는 작업을 수행 할 수 있습니다. 백업 목적으로 복사하는 경우이 옵션을 사용하지 마십시오. ln파일 자체가 복사되지 않으므로 매우 빠릅니다. 시험:

ln largefile /new/directory

또는 다른 장치의 디렉토리에서 액세스하려면 다음을 시도하십시오.

ln -s largefile /new/directory

ionice는 리눅스에서 잘 작동합니까? 난 그냥 "에뮬레이션"작업을 읽고 실제 차이가 없다? 링크의 경우 +1
Nick

1
@ Nick 그것을 사용하면 예상대로 작동합니다. Ionice를 적용한 프로세스는 상당히 느려졌으며 I / O가 필요한 다른 프로세스는 예상대로 수행 할 수있었습니다. 다른 프로세스의 I / O로드가 적당하면 예상대로 최대 'niceness'를 적용하여 높은 I / O 프로세스를 효과적으로 일시 중단 할 수있었습니다. 경쟁 I / O가 없으면 이온화 공정이 정상적으로 수행됩니다.
BillThor

400MB 파일을 사용하면 하나의 HD에서 SSD로 복사하는 초기 10 초가 완벽하게 작동 한 다음 갑자기 높은 IO로드를 보았고 1 분 동안 기계가 정지 된 것처럼 기다려야했습니다 : /. cgroup write io throttle과 동일한 문제가 발생하는 경우가 있으며 때로는 작동하지 않는 경우가 있습니다.
물병 자리 힘

7

는 IF ionice솔루션은 충분하지 않다 (whyever) 그리고 당신이 정말로 I를 제한하려면 / 절대 값 O 몇 가지 가능성이 있습니다 :

  1. 아마 가장 쉬운 방법 : ssh. 대역폭 제한이 내장되어 있습니다. 예를 들어 tar(대신 cp) 또는 scp(충분한 경우 symlinks 및 하드 링크를 처리하는 방법을 모르겠습니다) 또는을 사용 rsync합니다. 이 명령은 데이터를 파이프 할 수 있습니다 ssh. 의 경우에 tar사용자에게 연락 /dev/stdout(또는 -)와 파이프로 그 ssh다른 실행 클라이언트 tar"원격"쪽에.

  2. 우아하지만 바닐라 커널 (AFAIK)에는 없음 : 장치 매퍼 대상 ioband. 물론 이것은 소스 또는 대상 볼륨을 마운트 해제 할 수있는 경우에만 작동합니다.

  3. 자체 작성 재미 : grep "^write_bytes: " /proc/$PID/io프로세스가 작성한 데이터 양을 제공합니다. cp백그라운드에서 시작 하여 1/10 초 동안 휴면하고 백그라운드 cp프로세스를 중지 하는 스크립트 ( kill -STOP $PID)를 작성하고 기록 된 양을 확인하고 (이 경우 동일한 값에 대해 읽었습니까?), 시간을 계산 하는 스크립트를 작성할 수 있습니다. cp평균 전송 속도를 의도 한 값으로 낮추고 해당 시간 동안 절전 모드로 전환하거나 깨우기 cp( kill -CONT $PID) 등을 하려면 일시 중지해야합니다 .


예, 보통 lftp를 사용하여 scp를 통해 localhost에 연결하고 거기에서 대역폭을 제한합니다.
antonone

5

컴퓨터에 문제가 없을 수도 있습니다. 그 자체로는 문제가 없습니다. 그러나 USB 플래시 트랜지션 레이어에는 자체 쓰기 프로세서가있어 모든 쓰기 작업을 매핑하여 90 % 결함이있는 플래시 칩에 대한 보상을해야합니다. 당신은 그것을 범람하고 당신의 버퍼를 범람 한 다음 전체 버스를 범람 한 다음에 갇혀 있습니다. 결국 모든 것이 있습니다. 직관적이지 않은 것처럼 들리지만 실제로 필요한 것은 I / O를 차단하는 것입니다. FTL이 속도를 설정 한 다음 계속 유지해야합니다.

(FTL 마이크로 컨트롤러 해킹시 : http://www.bunniestudios.com/blog/?p=3554 )

위의 모든 답변이 작동해야하므로 이것이 "나도!" 다른 것보다 : 나는 완전히 거기에 있었다. rsync의 --bwlimit arg (2.5mbs는 단일 오류없이 실행하기에 좋은 장소 인 것처럼 보였으며 더 많은 쓰기 방지 오류가 발생했습니다)로 내 문제를 해결했습니다. rsync는 전체 파일 시스템으로 작업했기 때문에 특히 내 목적에 적합했습니다. 파일이 많았 기 때문에 rsync를 두 번째로 실행하면 첫 번째 실행 문제가 모두 해결됩니다. 2.5MB 이상으로 가감 속).

여전히 단일 파일에는 실용적이지 않다고 생각합니다. 귀하의 경우 dd set to raw-write로 파이프 할 수 있습니다. 한 번에 하나의 대상 파일 만 처리 할 수 ​​있습니다 (단일 파일은 물론 전체 블록 장치 일 수 있음).

## OBTAIN OPTIMAL IO VALUE FOR TARGET HOST DEV ##
## IT'S IMPORTANT THAT YOUR "bs" VALUE IS A MULTIPLE ##
## OF YOUR TARGET DEV'S SECTOR SIZE (USUALLY 512b) ##
% bs=$(blockdev --getoptio /local/target/dev)

## START LISTENING; PIPE OUT ON INPUT ##
% nc -l -p $PORT | lz4 |\ 
## PIPE THROUGH DECOMPRESSOR TO DD ## 
>    dd bs=$bs of=/mnt/local/target.file \
## AND BE SURE DD'S FLAGS DECLARE RAW IO ##
>        conv=fsync oflag=direct,sync,nocache

## OUR RECEIVER'S WAITING; DIAL REMOTE TO BEGIN ##
% ssh user@remote.host <<-REMOTECMD
## JUST REVERSED; NO RAW IO FLAGS NEEDED HERE, THOUGH ## 
>    dd if=/remote/source.file bs=$bs |\
>    lz4 -9 | nc local.target.domain $PORT
> REMOTECMD  

데이터 전송시 netcat이 ssh보다 약간 빠르다는 것을 알 수 있습니다. 어쨌든 다른 아이디어는 이미 취해진 것입니다. 왜 그렇지 않습니까?

[편집] : 다른 게시물에서 lftp, scp 및 ssh에 대한 언급을보고 원격 사본에 대해 이야기하고 있다고 생각했습니다. 현지인이 훨씬 더 쉽습니다.

% bs=$(blockdev --getoptio /local/target/dev)
% dd if=/src/fi.le bs=$bs iflag=fullblock of=/tgt/fi.le \
>    conv=fsync oflag=direct,sync,nocache

[EDIT2] : 마감일 : ptman이 댓글에서 5 시간 정도 나에게 이겼다는 것을 알게되었습니다.

분명히 승수로 성능을 위해 $ bs를 조정할 수 있지만 일부 파일 시스템에서는 대상 fs의 섹터 크기의 배수가 필요할 수 있으므로 명심하십시오.


내 컴퓨터에서 깃발은 --getioopt아닙니다--getoptio
Michael Mior

2

문제는 사본이 "유용한"데이터를 가득 채운 "비행 중"블록으로 메모리를 채우고 있다는 것입니다. 장치를 느리게하기 위해 I / O를 처리하는 Linux 커널 처리의 알려진 버그 ( 매우 수정하기 어려운 버그) (이 경우 USB).

예를 들어 다음과 같은 스크립트 (사실 증명 된 스케치, 완전히 테스트되지 않은 스크립트)를 사용하여 복사를 시도 할 수 있습니다 .

while true do
  dd if=infile of=outfile bs=4096 count=... seek=... skip=...
  sleep 5
done

조정 seekskip의해 count각 라운드. count너무 많은 메모리를 채우지 않고 비울 수 있도록 튜닝 해야합니다 5.


2

더티 페이지 제한을 낮추십시오. 기본 제한은 제정신입니다.

다음을 사용하여 /etc/sysctl.d/99-sysctl.conf를 작성하십시오.

vm.dirty_background_ratio = 3
vm.dirty_ratio = 10

그런 다음 sysctl -p를 실행하거나 재부팅하십시오.

현재 데이터가 대상 디스크에 기록 할 수있는 것보다 빠르게 읽히고 있습니다. linux가 파일을 복사 할 때 파일을 RAM으로 읽은 다음 대상에 쓸 때 페이지를 더티로 표시합니다. 더티 페이지는 교체 할 수 없습니다. 따라서 소스 디스크가 대상 디스크보다 빠르고 여유 RAM이있는 것보다 더 많은 데이터를 복사하는 경우 복사 작업은 사용 가능한 모든 RAM (또는 더티 페이지 제한이있는 모든 것 이상을 차지합니다. 더티 페이지를 교체 할 수없고 페이지가 비워 질 때 더티 페이지가 사용되어 더티로 표시되므로 사용 가능한 RAM)과 기아 상태가 발생합니다.

그의 문제가 완전히 해결되지는 않을 것입니다 ... 리눅스가 실제로 필요로하는 것은 더티 페이지 생성을 중재하는 방법이므로 대량의 전송이 사용 가능한 모든 RAM / 허용되는 더티 페이지를 모두 소비하지는 않습니다.


0

이 문제는 하드웨어 나 소프트웨어의 오류나 결함과 아무 관련이 없습니다. 단지 커널이 당신에게 친절하고 다시 메시지를주고 백그라운드에서 복사하는 것입니다 (커널 캐시를 사용합니다 : 더 많은 RAM, 더 많은 캐시, 그러나 / proc 어딘가에 작성하여 제한 할 수는 있지만 권장하지는 않습니다). 플래시 드라이브가 너무 느리고 커널이이를 쓰는 동안 다른 IO 작업을 충분히 빠르게 수행 할 수 없습니다. ionice다른 답변에서 여러 번 언급해도 괜찮습니다. 그러나 -o syncOS 버퍼링을 피하기 위해 드라이브를 마운트하려고 했습니까? 아마도 가장 간단한 해결책 일 것입니다.


-o sync를 활성화하면 인터넷이이 USB 드라이브의 쓰기 속도보다 빠릅니다. 내가 이해하지 못하는 것은 커널이 캐시 페이지가 얼마나 빨리 플러시되는지 추적하지 않고 그에 따라 향후 플러시를 예약하는 이유입니다. 이 불량한 드라이브가 속도를 따라갈 수없는 경우에도 항상 최고 속도를 유지하는 것과 같습니다. 그러나 그것은 내가 추측하는 또 다른 질문에 대한 주제입니다.
antonone
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.