machineA
.NET에서 파일을 변환 하는 쉘 스크립트를 실행 중입니다 machineB
.machineC
machineA
파일이 에 없으면 반드시 machineB
에 있어야 합니다. machineC
그래서 먼저 복사를 시도하고 machineB
, 존재하지 않으면 동일한 파일을 복사해 machineB
보겠습니다 .machineC
이 폴더 안에는 다음과 같은 폴더가 machineB
있습니다 .machineC
YYYYMMDD
/data/pe_t1_snapshot
따라서 위 폴더 내에서 이 형식의 최신 날짜가 무엇이든 간에 YYYYMMDD
해당 폴더를 파일 복사를 시작해야 하는 전체 경로로 선택하겠습니다.
20140317
따라서 이것이 내부의 최신 날짜 폴더라면 /data/pe_t1_snapshot
이것이 내 전체 경로가 될 것이라고 가정해 보겠습니다.
/data/pe_t1_snapshot/20140317
machineB
어디 에서 파일 복사를 시작해야 할까요 machineC
? 및 400
에서 파일을 복사해야 합니다. 각 파일 크기는 입니다.machineA
machineB
machineC
1.5 GB
현재 나는 그것을 사용할 때 잘 작동하는 다음 쉘 스크립트를 가지고 있지만 scp
어떻게 rsync
든 machineA의 파일을 5 hours
복사 해야하는데 400
이는 나에게 너무 긴 것 같습니다. :(
아래는 내 쉘 스크립트입니다 -
#!/bin/bash
readonly PRIMARY=/export/home/david/dist/primary
readonly SECONDARY=/export/home/david/dist/secondary
readonly FILERS_LOCATION=(machineB machineC)
readonly MEMORY_MAPPED_LOCATION=/data/pe_t1_snapshot
PRIMARY_PARTITION=(0 3 5 7 9)
SECONDARY_PARTITION=(1 2 4 6 8)
dir1=$(ssh -o "StrictHostKeyChecking no" david@${FILERS_LOCATION[0]} ls -dt1 "$MEMORY_MAPPED_LOCATION"/[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9] | head -n1)
dir2=$(ssh -o "StrictHostKeyChecking no" david@${FILERS_LOCATION[1]} ls -dt1 "$MEMORY_MAPPED_LOCATION"/[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9] | head -n1)
echo $dir1
echo $dir2
if [ "$dir1" = "$dir2" ]
then
# delete all the files first
rm -rf $PRIMARY/*
# below for-loop copies one file at a time in PRIMARY folder
for el in "${PRIMARY_PARTITION[@]}"
do
scp david@${FILERS_LOCATION[0]}:$dir1/t1_weekly_1680_"$el"_200003_5.data $PRIMARY/. || scp david@${FILERS_LOCATION[1]}:$dir2/t1_weekly_1680_"$el"_200003_5.data $PRIMARY/.
done
# delete all the files first
rm -rf $SECONDARY/*
# below for-loop copies one file at a time in SECONDARY folder
for sl in "${SECONDARY_PARTITION[@]}"
do
scp david@${FILERS_LOCATION[0]}:$dir1/t1_weekly_1680_"$sl"_200003_5.data $SECONDARY/. || scp david@${FILERS_LOCATION[1]}:$dir2/t1_weekly_1680_"$sl"_200003_5.data $SECONDARY/.
done
fi
폴더 PRIMARY_PARTITION
내의 파일 과 PRIMARY
폴더 SECONDARY_PARTITION
내의 파일을 복사하고 있습니다.SECONDARY
machineA
이제 내 질문은 - 파일 rsync
대신 이것을 어떻게 사용합니까 ? scp(ing)
내가 아는 한 이것은 rsync
파일보다 훨씬 빠릅니다. scp(ing)
내 쉘 스크립트와 동일한 논리를 갖고 싶습니다 rsync
. 이전에 함께 일한 적이 없었기 rsync
때문에 몇 가지 문제가 있었습니다.
누구든지 예를 들어 줄 수 있습니까?
내 사용 사례를 고려할 때 rsync
scp에 비해 더 빠를까요? 그렇지 않은 경우 파일 전송 속도를 높이기 위해 어떤 다른 옵션을 시도할 수 있습니까?
고쳐 쓰다:-
terdon 질문을 명확히하려면 -
이 질문에서는 예를 들어 10개의 파일만 표시합니다.
PRIMARY_PARTITION=(0 3 5 7 9)
SECONDARY_PARTITION=(1 2 4 6 8)
일반적으로 PRIMARY_PARTITION
배열에는 약 150개의 파일 번호가 있고 배열에는 SECONDARY_PARTITION
또 다른 200개의 파일 번호가 있습니다.
이제 내가 해야 할 일은 내가 가지고 있는 파일 번호의 수에 관계없이 디렉터리에서 해당 파일을 PRIMARY_PARTITION
찾아야 하며 파일이 이미 존재하는 경우 해당 폴더 에 복사하고 파일이 존재하지 않으면 거기에 있어야 합니다. , 그러니 지금부터 파일을 복사 해서 .machineB
PRIMARY
machineA
machineB
machineC
machineC
PRIMARY
machineA
다시 말하지만 , 로 동일한 작업을 수행해야 합니다. 디렉터리에서 해당 파일을 SECONDARY_PARTITION
찾아 파일 machineB
이 있으면 machineA
보조 디렉터리에 복사하고, 없으면 보조 디렉터리에 machineB
있어야 합니다. machineC
복사하여 보조 디렉토리 machineC
에 배치합니다 .machineA
따라서 우리가 가지고 있는 모든 파일 번호는 - PRIMARY_PARTITION
및 에 있습니다 SECONDARY_PARTITION
.
일반적으로 나는 PRIMARY_PARTITION
다음과 같은 것을 가질 것입니다 SECONDARY_PARTITION
-
PRIMARY_PARTITION=(0 548 272 4 544 276 8 556 280 12 552 284 16 256 564 20 260 560 24 264 572 28 268 568 516 304 32 512 308 36 524 312 40 520 316 44 288 532 48 292 528 52 296 540 56 300 536 60 68 608 340 64 336 76 348 72 344 84 324 80 320 92 332 88 328 576 372 100 580 368 96 584 380 108 588 376 104 356 592 116 352 596 112 364 600 124 360 604 120 136 408 140 412 128 400 132 404 152 392 156 396 144 384 148 388 440 168 444 172 432 160 436 164 424 184 428 188 416 176 420 180 204 476 200 472 196 468 192 464 220 460 216 456 212 452 208 448 508 236 504 232 500 228 496 224 492 252 488 248 484 244 480 240)
SECONDARY_PARTITION=(1101 1374 1641 1371 1647 1098 1635 1365 1095 1638 1089 1362 1659 1359 1119 1113 1662 1353 1350 1650 1110 1347 1653 1107 1134 1407 1611 1401 1131 1614 1602 1125 1398 1122 1605 1395 1389 1149 1626 1629 1146 1386 1617 1143 1383 1377 1623 1137 1305 1581 1578 1311 1299 1575 1302 1569 1599 1290 1593 1293 1590 1281 1587 1287 1551 1338 1341 1545 1071 1329 1542 1335 1539 1083 1566 1323 1086 1563 1326 1557 1074 1314 1317 1077 1554 1221 1494 1491 1218 1503 1230 1227 1497 1479 1239 1233 1473 1245 1485 1482 1242 1254 1527 1251 1521 1263 1533 1530 1257 1509 1269 1266 1506 1278 1518 1275 1515 1155 1425 1431 1158 1434 1161 1167 1437 1410 1170 1173 1413 1419 1179 1422 1182 1671 1458 1185 1665 1191 1461 1677 1194 1467 1470 1197 1674 1203 1443 1206 1446 1449 1209 1215 1455)
또 다른 업데이트:-
삭제한 후 2>/dev/null
스크립트를 다시 실행했지만 다음 오류가 발생했습니다.
ssh: Could not resolve hostname machineB : Name or service not known rsync: connection unexpectedly closed (0 bytes received so far) [Receiver] rsync error: unexplained error (code 255) at io.c(605) [Receiver=3.0.9] ssh: Could not resolve hostname machineC : Name or service not known rsync: connection unexpectedly closed (0 bytes received so far) [Receiver] rsync error: unexplained error (code 255) at io.c(605) [Receiver=3.0.9] ssh: Could not resolve hostname machineB : Name or service not known rsync: connection unexpectedly closed (0 bytes received so far) [Receiver] rsync error: unexplained error (code 255) at io.c(605) [Receiver=3.0.9] ssh: Could not resolve hostname machineC : Name or service not known rsync: connection unexpectedly closed (0 bytes received so far) [Receiver] rsync error: unexplained error (code 255) at io.c(605) [Receiver=3.0.9]
무슨 일인지 아이디어가 있나요? 쉘 스크립트를 실행하기 전에 machineB
실제 이름으로 바꾸었습니다. 내 시스템은 다음과 같습니다.machineC
root@machineA:/home/david# uname -a
Linux machineA 3.2.0-24-generic #37-Ubuntu SMP Wed Apr 25 08:43:22 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux
다음은 내가 실행 중인 쉘 스크립트입니다.
#!/usr/bin/env bash
readonly PRIMARY=/export/home/david/dist/primary
readonly SECONDARY=/export/home/david/dist/secondary
readonly FILERS_LOCATION=(machineB machineC)
readonly MEMORY_MAPPED_LOCATION=/data/pe_t1_snapshot
PRIMARY_PARTITION=(0 3 5 7 9)
SECONDARY_PARTITION=(1 2 4 6 8)
dir1=$(ssh -o "StrictHostKeyChecking no" david@${FILERS_LOCATION[0]} ls -dt1 "$MEMORY_MAPPED_LOCATION"/[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9] | head -n1)
dir2=$(ssh -o "StrictHostKeyChecking no" david@${FILERS_LOCATION[1]} ls -dt1 "$MEMORY_MAPPED_LOCATION"/[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9] | head -n1)
echo $dir1
echo $dir2
## Build your list of filenames before the loop.
for n in "${PRIMARY_PARTITION[@]}"
do
primary_files="$primary_files :$dir1"/t1_weekly_1680_"$n"_200003_5.data
done
## Repeat for $SECONDARY_PARTITION
for n in "${SECONDARY_PARTITION[@]}"
do
secondary_files="$secondary_files :$dir2"/t1_weekly_1680_"$n"_200003_5.data
done
echo $primary_files
echo $secondary_files
if [ "$dir1" = "$dir2" ]
then
find "$PRIMARY" -mindepth 1 -delete
find "$SECONDARY" -mindepth 1 -delete
rsync -avz david@${FILERS_LOCATION[0]}"${primary_files}" $PRIMARY/
rsync -avz david@${FILERS_LOCATION[1]}"${primary_files}" $PRIMARY/
## Do the same for $secondary_partition files
rsync -avz david@${FILERS_LOCATION[0]}"${secondary_files}" $SECONDARY/
rsync -avz david@${FILERS_LOCATION[1]}"${secondary_files}" $SECONDARY/
fi
rsync
구문이 잘못된 것 같습니다 . 이와 같은 단일 명령을 실행하면 제대로 작동하기 때문입니다.
rsync -avz david@machineB":/data/pe_t1_snapshot/20140317/t1_weekly_1680_0_200003_5.data" /export/home/david/dist/primary
또 다른 작은 업데이트:-
이렇게 달리면 -
root@machineA:/export/home/david# rsync -avz david@machineB':/data/pe_t1_snapshot/20140317/t1_weekly_1680_0_200003_5.data :/data/pe_t1_snapshot/20140317/t1_weekly_1680_1_200003_5.data' /data01/primary
receiving incremental file list
rsync: change_dir "/home/david/:/data/pe_t1_snapshot/20140317" failed: No such file or directory (2)
t1_weekly_1680_0_200003_5.data
sent 30 bytes received 504982813 bytes 6196108.50 bytes/sec
total size is 1761988281 speedup is 3.49
rsync error: some files/attrs were not transferred (see previous errors) (code 23) at main.c(1536) [generator=3.0.9]
위 명령은 파일을 /data01/primary
디렉터리에 복사해야 하지만 파일 하나만 복사하고 두 번째 파일은 복사하지 않습니다.
하지만 이것은 잘 작동하고 하나의 파일이 복사됩니다.
root@machineA:/export/home/david# rsync -avz david@machineB':/data/pe_t1_snapshot/20140317/t1_weekly_1680_0_200003_5.data' /data01/primary
receiving incremental file list
t1_weekly_1680_0_200003_5.data
sent 30 bytes received 504982698 bytes 6351984.00 bytes/sec
total size is 1761988281 speedup is 3.49
답변1
스크립트의 주요 문제점은 scp
각 파일에 대해 별도의 연결을 열어서많은불필요한 오버헤드. 다음과 같이 시도해 볼 수 있습니다.
#!/usr/bin/env bash
readonly PRIMARY=/export/home/david/dist/primary
readonly SECONDARY=/export/home/david/dist/secondary
readonly FILERS_LOCATION=(machineB machineC)
readonly MEMORY_MAPPED_LOCATION=/data/pe_t1_snapshot
PRIMARY_PARTITION=(0 548 272 4 544 276 8 556 280 12 552 284 16 256 564 20 260 560 24 264 572)
SECONDARY_PARTITION=(1101 1374 1641 1371 1647 1098 1635 1365 1095 1638 1089 1362 1659 1359)
dir1=$(ssh -o "StrictHostKeyChecking no" david@${FILERS_LOCATION[0]} ls -dt1 "$MEMORY_MAPPED_LOCATION"/[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9] | head -n1)
dir2=$(ssh -o "StrictHostKeyChecking no" david@${FILERS_LOCATION[1]} ls -dt1 "$MEMORY_MAPPED_LOCATION"/[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9] | head -n1)
## Build your list of filenames before the loop.
for n in "${PRIMARY_PARTITION[@]}"
do
primary_files="$primary_files :$dir1"/t1_weekly_1680_"$n"_200003_5.data
done
## Repeat for $SECONDARY_PARTITION
for n in "${SECONDARY_PARTITION[@]}"
do
secondary_files="$secondary_files :$dir2"/t1_weekly_1680_"$n"_200003_5.data
done
if [ "$dir1" = "$dir2" ]
then
## I am using find largely because the *
## in rm -rf "$PRIMARY"/* screws up the syntax
## highlighting on the site and it is a good habit to
## get into anyway. Feel free to use rm -rf in your script.
find "$PRIMARY" -mindepth 1 -delete
find "$SECONDARY" -mindepth 1 -delete
## rsync can be run with this format:
## rsync user@dest:/target/path1 :/target/path2 :/target/pathN /dest/path
#
## which is why I added the : in the loop above. So, these commands will
## open only 2 conections per file list. First you will try to copy all $primary_partition
## files from machineA, then all $primary_partition files from machineB.
## rsync will complain about files not found (which is why I'm redirecting standard
## error to /dev/null) but will continue. You then repeat the process for machineC.
rsync -avz david@${FILERS_LOCATION[0]}"${primary_files}" $PRIMARY/ 2>/dev/null
rsync -avz david@${FILERS_LOCATION[1]}"${primary_files}" $PRIMARY/ 2>/dev/null
## Do the same for $secondary_partition files
rsync -avz david@${FILERS_LOCATION[0]}"${secondary_files}" $SECONDARY/ 2>/dev/null
rsync -avz david@${FILERS_LOCATION[1]}"${secondary_files}" $SECONDARY/ 2>/dev/null
fi
답변2
rsync
책임: 변경된 파일만 복사하고 복사하고 싶지 않은 파일은 무시합니다( -C
예: 무엇이든 지정할 수 있지만 CVS가 저장소에서 제외하는 것과 동일한 파일을 제외하는 스위치). 전체 파일 디렉터리 구조를 재귀적으로 복사합니다(물론). , 필요한 변경 사항만 있고 전부는 아닙니다). 스트림을 압축하여 전송 속도를 높이는 옵션이 있습니다. 또한 단일 연결 내에서 전체 복사본을 수행하므로 더 빠릅니다.
단일 파일만 복사하므로 대부분의 기능은 사용되지 않습니다. 당신은 사용할 것이다
rsync -avz "$firstfile" "$secondfile"
scp
이는 플래그(a - 아카이브가 권한과 타임스탬프를 유지함, v는 자세한 내용, z는 압축)를 제외하고는 완전히 동일합니다.
그러나 압축을 위해 scp를 사용할 수도 있습니다.
scp -p -C …
나는 이것이 여기서 가장 간단한 해결책이라고 생각합니다. 로고만 추가하면 끝입니다.
답변3
readonly TGT=/export/home/david/dist
readonly TGT1=${TGT}/primary
readonly TGT2=${TGT}/secondary
readonly MMAP_LOC=/data/pe_t1_snapshot
readonly PART1='t1_weekly_1680_[03579]_200003_5.data' # shell globbing does
readonly PART2='t1_weekly_1680_[12468]_200003_5.data' # the bulk of the work
readonly F_LOC=BC
readonly SSH="david@machine"
#hoping the = works - I don't know
SSH1='ssh -o "StrictHostKeyChecking=no" '"${SSH}${F_LOC%?}"
SSH2="${SSH1%?}${F_LOC#?}"
DIR="${MMAP_LOC}/"'[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]'
DIR1="$($SSH1 'cd ${d='"$DIR"'} && echo $d')" #shell glob
DIR2="$($SSH2 'cd ${d='"$DIR"'} && echo $d')" #shell glob
${DIR1:?FAIL} [ -n "${DIR1#"$DIR2"}" ] && exit 1 #tests if d1=d2 or dies
F1="$($SSH1 'printf "%s\n" '"${DIR1}/${PART1}")" #prefers primary
F1="${F1}$(echo ; $SSH1 'for f in '"${DIR2}/${PART1}"'\ #shell glob in
do { case "'"$F1"'" in "${f#'"$DIR2"'}") continue ;;\ # favor
*) printf "%s\n" "$f" ;;\ #of files found in primary
esac ; } ; done')" #with secondary as backup
F2="$($SSH2 'printf "%s\n" '"${DIR2}/${PART2}")" #secondary
rsync -avzt -e "${SSH1}:/" "${TGT1}"/. \ #if it works, based on your
--exclude=* $(printf --include=%s\\n $F1) #file sizes, should
rsync -avzt -e "${SSH2}:/" "${TGT2}"/. \ #dramatically decrease
--exclude=* $(printf --include=%s\\n $F2) #transfer times
이것이 작동합니까?