私は学術医学物理学者です。私の実験は多くのデータを生成しますが、実行するのに費用がかかります。私たちの大学には、IBMの技術を使用して廃棄された塩鉱山に位置するロボットテープライブラリからなるバックアップシステムがあります。スペクトル保護(というdsmc
)オフサイトバックアップに使用します。塩鉱山で送れる総サイズには制限はありませんが、はい1日の転送制限は200GBです。私が知っている限り、Spectrum Protectクライアントがこの制限に準拠して転送制限に達したときに停止するようにする方法はありません。
この制限に違反すると、サーバーはノードをロックし、誰かにノードのロックを解除するように求める謝罪電子メールを送信する必要があります。帯域幅が多すぎると混乱し、約24〜48時間後にノードをロック解除しました。
データを個々のチャンクで作成し(実験当日)、毎月または週ごとに帯域幅制限よりはるかに低いという事実を処理するためにdsmc
送信が発生した場合、出力を解析して終了する簡単なラッパースクリプトを作成しました。大きすぎました。
解析は、dsmc
単純なPythonスクリプトを使用してbashの出力をhereドキュメントとして処理することによって行われます。
#!/bin/bash
# A silly wrapper script to halt TSM backups
#
# Usage: sudo /path/to/script /path/to/backup/location
#
# Requires python3 accessible as python3, and the regex / os modules.
# Tested on MacOS and Linux
BYTES_SENT=0;
#MAX_SIZE_TO_SEND=150 #Bytes, for testing
MAX_SIZE_TO_SEND=$[185*(2**30)]
args=("$@")
sudo rm -f /tmp/dsmc-script.PID
function outputParser() {
python3 <<'EOF'
import os, re
rex=re.compile(r"Normal File\-\-\>\s*?([,0-9]*,?)\s*?\/")
valueToParse=os.environ.get('line');
match=rex.match(valueToParse);
try:
stringToReturn = str(match.group(1));
stringToReturn =stringToReturn.replace(',','');
except AttributeError:
stringToReturn = "";
#Check for failed transfers
failedResults = re.findall(r"\*\* Unsuccessful \*\*", valueToParse);
nFailedResults = len(failedResults);
if (nFailedResults >0):
stringToReturn = "";
print(stringToReturn);
EOF
} #I am sure that the above is a one-liner in sed or awk. I just don't know what the one line is.
function trapCaught() {
#Do cleanup, not shown
echo ", quitting."
}
trap trapCaught sigint
killCount=0
startTime=$SECONDS
while read -r line; do
echo "$line"
export line;
X=$(export line=$line; outputParser)
if [[ ! -z "$X" ]]; then
BYTES_SENT=$[$BYTES_SENT + $X]
echo "Sent $X bytes, $BYTES_SENT in total"
fi
if (( BYTES_SENT > MAX_SIZE_TO_SEND )); then
if (( killCount < 1)); then
echo "STOPPED BACKUP BECAUSE $BYTES_SENT is GREATER THAN THE PERMITTED MAXIMUM OF $MAX_SIZE_TO_SEND";
killStartTime=$(( SECONDS - startTime ))
pid=$(cat /tmp/dsmc-script.PID)
echo "PID is $pid"
echo $pid | sudo xargs kill
fi
killCount=$[$killCount + 1];
timeKillNow=$(( SECONDS - killStartTime ))
rm -f /tmp/dsmc-script.PID
if (( killCount > 100 || timeKillNow > 30 )); then
echo "Taking too long to die; retrying"
echo $pid | sudo xargs kill -9;
sleep 0.1;
sudo kill -9 0;
fi
fi
done < <( sudo dsmc incr ${args[0]} & echo $! > /tmp/dsmc-script.PID )
これは動作し、私の目的に適しています。しかし、パフォーマンスは不都合で恐ろしいほどです。これは、ループを繰り返すたびにwhile
Pythonインタプリタ/スクリプトの組み合わせの他のインスタンスが作成されるためと想定されます。
バイナリコンパイルされたブロブの制限や動作を変更できないことを考慮すると、3つの関連するdsmc
質問があります。
(a)これがこの問題を解決する合理的な方法ですか、それとも高度な魔法のように私が見逃しているより簡単な方法はありますかnetstat
?
(b) 与えられた Python実はそうです。ループのすべての反復で本質的に同じインタプリタのコード翻訳をキャッシュすることで、全体のプロセス速度を大幅に向上させる方法はありますか?
sed
(c)Pythonスクリプトを同等のOR構成に置き換えると、awk
全体の作業がはるかに高速になると思います。なぜ?このタイプの算術を簡単に実行できますか?それとも別の問題ですか?
編集する:おなじみの方のために、サンプル出力は次のdsmc
ようになります。文字列に「一般ファイル」が表示され、その後に対応するサイズ(バイト)が続く場合にのみファイルが送信されます。したがって、以下ではファイルがspclicert.kdb
転送されますが、TSM.PWD
ディレクトリも転送されませんCaptiveNetworkSupport
。
# dsmc incr /
< header message containing personal information>
Incremental backup of volume '/'
ANS1898I ***** Processed 79,000 files *****
Directory--> 0 /Library/Preferences/SystemConfiguration/CaptiveNetworkSupport [Sent]
Normal File--> 5,080 /Library/Preferences/Tivoli Storage Manager/Nodes/SHUG2765-MACBOOKPRO-PHYSICS/spclicert.kdb [Sent]
Updating--> 224 /Library/Preferences/Tivoli Storage Manager/BrokenOrOld/TSM.PWD (original) [Sent]
したがって、上記のスクリプトは転送された各ファイルのサイズ(バイト単位)を削除し、単純に合計します。
答え1
接続が安定していると仮定すると、簡単な解決策はユーザー空間トラフィックシェーパーを使用することです。 1日の最大帯域幅以上を無効にするだけです。
l=$(( (200*10**6)/(24*60**2) ))
trickle -d $l scp foo username@remotehost:~/
trickle
転送速度が遅くなります2314K1秒あたりの最大速度は次を超えません。199,929,600,000毎日のバイトです。ファイル転送プログラムは必ずしも必要ではありませんscp
。何でも(Webブラウザも可能)、(またはdsmc
)コマンドラインから実行できます。
この方法の利点は、ファイルを分割する必要がないことです。金持ち1日の上限を超える場合。もちろん過ごすのに時間がかかるでしょう。金持ち終わり、(もし金持ち1TBなら5日かかりますが、どうせそれほど長くかかるでしょう。
trickle
trickled
"trickle"の各後続の実行を制御するtrickleというデーモンバージョンがあります。例:
l=$(( (200*10**6)/(24*60**2) ))
trickled -d $l
trickle scp foo username@remotehost:~/ &
trickle scp bar username@remotehost:~/ &
trickle scp baz username@remotehost:~/ &
各ファイル金持ち、バーとブザー音はい1TBスケールの面では、trickled
まだ以前のレベルを維持しています。200GB/日制限。
答え2
あなたの入力は完全にすることができますbash
。例は次のとおりです。
max=$[185*(2**30)]
export total=0
while read first second third rest; do
[[ "$first" == "Normal" && "$second" == "File-->" ]] && {
size=${third//,/}
echo "file: $size"
total=$(( total + size ))
(( total > max )) && kill something
}
done < ~/tmp/your-input
子プロセスを作成するのにかかる時間が実際に制限されている場合、awk
またはsed
。