rsyncまたはscpを使用してmachineBとmachineCからmachineAにファイルを効率的にコピーするには?

rsyncまたはscpを使用してmachineBとmachineCからmachineAにファイルを効率的にコピーするには?

machineA.NETでファイルを変換するシェルスクリプトを実行していますmachineBmachineCmachineA

ファイルが にない場合は必ず になけれmachineBばなりません。machineCだからまずコピーを試みてmachineB、存在しない場合は同じファイルをコピーしてmachineBみましょう。machineC

このフォルダ内には次のフォルダがmachineBあります。machineCYYYYMMDD

/data/pe_t1_snapshot

したがって、上記のフォルダ内で、この形式の最新の日付が何であれ、そのYYYYMMDDフォルダをファイルのコピーを開始する必要があるフルパスとして選択します。

20140317したがって、これが内部の最新の日付フォルダである場合、/data/pe_t1_snapshotこれが私のフルパスになるとしましょう。

/data/pe_t1_snapshot/20140317

machineBどこでファイルのコピーを開始する必要がありますかmachineC?と400からファイルをコピーする必要があります。各ファイルサイズはです。machineAmachineBmachineC1.5 GB

現在私はそれを使用するとうまく動作する次のシェルスクリプトを持っていますが、どういうわけかscpmachineArsyncのファイルを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内のファイルをコピーしています。SECONDARYmachineA

今私の質問は - ファイルのrsync代わりにこれをどのように使用しますか?scp(ing)私が知る限り、これはrsyncファイルよりはるかに高速です。scp(ing)私のシェルスクリプトと同じロジックを持ちたいですrsync。以前に一緒に働いたことがなかったrsyncので、いくつかの問題がありました。

誰でも例をあげることができますか?

私のユースケースを考えると、rsyncscpよりも速いでしょうか?それ以外の場合は、ファイル転送速度を上げるために他のどのオプションを試すことができますか?

直す:-

terdonの質問を明確にするには -

この質問では、たとえば10個のファイルのみを表示します。

PRIMARY_PARTITION=(0 3 5 7 9)
SECONDARY_PARTITION=(1 2 4 6 8)

通常、PRIMARY_PARTITION配列には約150個のファイル番号があり、配列にはSECONDARY_PARTITION別の200個のファイル番号があります。

今やるべきことは、私が持っているファイル番号の数にかかわらず、ディレクトリ内でそのファイルを見つけるPRIMARY_PARTITION必要があります。だから、今からファイルをコピーして。machineBPRIMARYmachineAmachineBmachineCmachineCPRIMARYmachineA

繰り返しますが、で同じことをする必要があります。ディレクトリ内のファイルを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ディレクトリにコピーする必要がありますが、ファイルを1つだけコピーし、2番目のファイルをコピーしません。

しかし、これはうまく機能し、1つのファイルがコピーされます。

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

これはうまくいきますか?

関連情報