![pv(1)를 사용하여 rsync 속도 제한](https://rvso.com/image/1414685/pv(1)%EB%A5%BC%20%EC%82%AC%EC%9A%A9%ED%95%98%EC%97%AC%20rsync%20%EC%86%8D%EB%8F%84%20%EC%A0%9C%ED%95%9C.png)
rsync 전송의 대역폭을 제한하기 위해 pv
rsync의 내장 기능 대신 사용하려고 합니다. 왜냐하면 rsync 전송은 최종적으로 일관된 방식으로 구현되고 전송이 너무 짧아서 제한이 실제로 시작되지 않기 때문입니다.--bwlimit
--bwlimit
거의작동하지만 시스템이 제대로 종료되지 않습니다.
익숙하지 않은 분들을 위해 설명하자면, pv
파이프 뷰어 유틸리티가 있지만 파이프를 통과하는 데이터 속도를 제한하는 기능은 거의 알려지지 않았습니다.
추가 편집: 근본적인 문제를 발견했다고 생각합니다. 일반적으로 파이프라인의 프로세스는 a) stdin이 닫히거나 b) stdout에 쓰는 동안 SIGPIPE를 받기 때문에 중지됩니다. a) rsync는 (분명히) stdin의 소켓을 절대 닫지 않고 b) rsync는 stdout이 닫히는 것과 동일한 순간에 stdin에서 데이터 전송을 중지하기 때문에 stdout에 쓰기를 시도하지 않기 때문에 발생하지 않습니다.
내가 필요한 것은 stdin이 여전히 데이터를 보내고 있는지 여부에 관계없이 stdout이 닫히자마자 pv가 종료되도록 하는 일종의 래핑 명령입니다.
데모:
head -c 100000 /dev/urandom > random4.bin
ls -lh random4.bin
> -rw-r--r-- 1 buck users 98K 2014-07-07 11:01 random4.bin
export RSYNC_RSH='sh -c '\''pv -qL10k | ssh "$@" | pv -qL11k'\'' ssh'
rsync -av --progress localhost:$PWD/random4.bin random5.bin
> receiving incremental file list
> random4.bin
> 100000 100% 17.47kB/s 0:00:05 (xfer#1, to-check=0/1)
>
> sent 30 bytes received 100109 bytes 10540.95 bytes/sec
> total size is 100000 speedup is 1.00
> (never exits)
이 시점에서 터미널 제어권을 다시 얻으려면 Ctrl-C를 눌러야 합니다. 문제는 pv
ssh의 입력에 있는 것이 출력이 닫혀도 절대 종료되지 않는다는 것입니다.
약간의 디버깅:
pstree -lap 29532
> rsync,29532 -av --progress localhost:/nail/home/buck/tmp/random4.bin random5.bin
> └─sh,29533 -c pv -qL10k | ssh "$@" | pv -qL11k ssh localhost rsync --server --sender -vlogDtpre.iLsf . /nail/home/buck/tmp/random4.bin
> └─pv,29534 -qL10k
lsof -p 29532
> COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
> rsync 29532 buck cwd DIR 252,0 4096 7345851 /nail/home/buck/tmp
> rsync 29532 buck rtd DIR 9,1 4096 2 /
> rsync 29532 buck txt REG 9,1 405368 94575 /usr/bin/rsync
> rsync 29532 buck mem REG 9,1 51712 554006 /lib/libnss_files-2.11.1.so
> rsync 29532 buck mem REG 9,1 43552 553997 /lib/libnss_nis-2.11.1.so
> rsync 29532 buck mem REG 9,1 97256 553992 /lib/libnsl-2.11.1.so
> rsync 29532 buck mem REG 9,1 35712 553831 /lib/libnss_compat-2.11.1.so
> rsync 29532 buck mem REG 9,1 18704 553802 /lib/libattr.so.1.1.0
> rsync 29532 buck mem REG 9,1 1584520 554000 /lib/libc-2.11.1.so
> rsync 29532 buck mem REG 9,1 44008 554064 /lib/libpopt.so.0.0.0
> rsync 29532 buck mem REG 9,1 31208 553800 /lib/libacl.so.1.1.0
> rsync 29532 buck mem REG 9,1 136936 554003 /lib/ld-2.11.1.so
> rsync 29532 buck mem REG 9,1 256324 172607 /usr/lib/locale/en_US.utf8/LC_CTYPE
> rsync 29532 buck mem REG 9,1 26048 93726 /usr/lib/gconv/gconv-modules.cache
> rsync 29532 buck 0u CHR 136,10 0t0 13 /dev/pts/10
> rsync 29532 buck 1u CHR 136,10 0t0 13 /dev/pts/10
> rsync 29532 buck 2u CHR 136,10 0t0 13 /dev/pts/10
> rsync 29532 buck 3u unix 0xffff882026de4100 0t0 349807593 socket
> rsync 29532 buck 4u unix 0xffff880d79016e80 0t0 349851596 socket
lsof -p 29533
> COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
> sh 29533 buck cwd DIR 252,0 4096 7345851 /nail/home/buck/tmp
> sh 29533 buck rtd DIR 9,1 4096 2 /
> sh 29533 buck txt REG 9,1 101608 504936 /bin/dash
> sh 29533 buck mem REG 9,1 1584520 554000 /lib/libc-2.11.1.so
> sh 29533 buck mem REG 9,1 136936 554003 /lib/ld-2.11.1.so
> sh 29533 buck 0u unix 0xffff880d79014100 0t0 349851595 socket
> sh 29533 buck 1u unix 0xffff880d79014e00 0t0 349851598 socket
> sh 29533 buck 2u CHR 136,10 0t0 13 /dev/pts/10
lsof -p 29534
> COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
> pv 29534 buck cwd DIR 252,0 4096 7345851 /nail/home/buck/tmp
> pv 29534 buck rtd DIR 9,1 4096 2 /
> pv 29534 buck txt REG 9,1 35336 106025 /usr/bin/pv
> pv 29534 buck mem REG 9,1 1584520 554000 /lib/libc-2.11.1.so
> pv 29534 buck mem REG 9,1 136936 554003 /lib/ld-2.11.1.so
> pv 29534 buck mem REG 9,1 256324 172607 /usr/lib/locale/en_US.utf8/LC_CTYPE
> pv 29534 buck mem REG 9,1 54 172608 /usr/lib/locale/en_US.utf8/LC_NUMERIC
> pv 29534 buck mem REG 9,1 2454 172707 /usr/lib/locale/en_US.utf8/LC_TIME
> pv 29534 buck mem REG 9,1 1170770 172610 /usr/lib/locale/en_US.utf8/LC_COLLATE
> pv 29534 buck mem REG 9,1 286 172708 /usr/lib/locale/en_US.utf8/LC_MONETARY
> pv 29534 buck mem REG 9,1 57 172710 /usr/lib/locale/en_US.utf8/LC_MESSAGES/SYS_LC_MESSAGES
> pv 29534 buck mem REG 9,1 34 172614 /usr/lib/locale/en_US.utf8/LC_PAPER
> pv 29534 buck mem REG 9,1 77 172615 /usr/lib/locale/en_US.utf8/LC_NAME
> pv 29534 buck mem REG 9,1 155 172711 /usr/lib/locale/en_US.utf8/LC_ADDRESS
> pv 29534 buck mem REG 9,1 59 172712 /usr/lib/locale/en_US.utf8/LC_TELEPHONE
> pv 29534 buck mem REG 9,1 23 172618 /usr/lib/locale/en_US.utf8/LC_MEASUREMENT
> pv 29534 buck mem REG 9,1 26048 93726 /usr/lib/gconv/gconv-modules.cache
> pv 29534 buck mem REG 9,1 373 172713 /usr/lib/locale/en_US.utf8/LC_IDENTIFICATION
> pv 29534 buck 0u unix 0xffff880d79014100 0t0 349851595 socket
> pv 29534 buck 1w FIFO 0,8 0t0 349847461 pipe
> pv 29534 buck 2u CHR 136,10 0t0 13 /dev/pts/10
답변1
pv
의 데이터를 기다리고 있는 것 같고 rsync
, rsync
데이터도 기다리고 있고( 에 갇혀 있음 select()
) 에 대한 입력을 닫지 않는 것 같습니다 pv
. 그래서 교착상태입니다. pv
다른 것으로 대체할 때도 마찬가지입니다 (예 dd
: ). 해당 명령은 rsync
예상 대로 작동하지 않는 것 같습니다 .
모든 것을 죽이는 것 외에는 해결 방법을 찾지 못했습니다.
export RSYNC_RSH="sh -c 'pv -qL10k | ssh \"\$@\" | (pv -qL11k; kill \$\$)' ssh"
kill
내가 만족할 해결책이 아닙니다. 하지만 다른 것을 찾지 못했습니다.
물론 사용하는 것은 $$
게으른 방법이었습니다. pv
대신 kill해야 하지만 oneliner에서 pid를 얻는 방법은 무엇입니까? pidof
그냥 pv
PID를 제공합니다. 각각의 상위 PID를 쿼리하는 것은 oneliner의 경우 약간 이상해 보였습니다.
진정한 해결책을 기대합니다... ;)