NAS上に溜まっていくPlotsの振り分けを自動化する

(この記事は 2021年7月 くらいの情報です)

割とどこでもそうだろうけど、うちの環境では Plot の生成用 PC(Plotter-PC)と、それを使って farming をする PC(Farmer-PC)が別なので、どうにかして生成した Plots を移動しなければなりません。

これまでやってた方法は
 1)USB-HDD にコピーして繋ぎなおして再コピー
 2)Windows ファイル共有経由で手動コピー
 3)最終出力をファイル共有フォルダに指定
 4)3 の後 Farmer-PC で保管用 HDD に手でコピー
 5)NAS を出力先にしてそこから手動コピー
という感じで変わってきたんだけど、Farmer-PC の HDD が埋まったことで次のフェーズは NAS に接続した USB-HDD が保管先になっています。

これ、NAS 上に生成したものをわざわざ PC 上から動かすのは無駄な感じだし、せっかく QTS にはシェル(bash)や cron が動く環境があるので、自動化しちゃいましょう!

1. 準備

実際に試す前に色々検証しておきます。

1-1. スクリプトを試す

とりあえず、スクリプトが動かないと何もできないので、確認します。

[~] # ls -l /bin/sh /bin/bash
lrwxrwxrwx 1 admin administrators      2 2021-07-02 23:58 /bin/bash -> sh*
-rwxr-xr-x 1 admin administrators 947808 2021-06-30 09:23 /bin/sh*

[~] # vi test.sh
--
#! /bin/sh
set
--

[~] # sh ./test.sh
(略)

うん、OK っぽい。
ついでに cron が動いてるのかどうかも。

[~] # crontab -l
# m h dom m dow cmd
0 3 * * * /usr/local/sbin/ImR_all -soft /Qmultimedia
0 2 * * * /sbin/qfstrim
0 3 * * 0 /etc/init.d/idmap.sh dump
0-59/20 3 * * * /sbin/adjust_time
0 4 * * * /sbin/hwclock -s
0 3 * * * /sbin/clean_reset_pwd
0-59/15 * * * * /etc/init.d/nss2_dusg.sh
30 7 * * * /sbin/clean_upload_file
0-59/10 * * * * /etc/init.d/storage_usage.sh
30 3 * * * /sbin/notice_log_tool -v -R
*/10 * * * * /sbin/config_cache_util 0
1 9,21 * * * /sbin/notify_update --nc 1>/dev/null 2>&1
0 1 * * * /etc/init.d/flush_memory.sh >/dev/null 2>&1
0 0 * * * /sbin/auto_update 1>>/dev/null 2>>/dev/null
00 03 * * * sh /share/CACHEDEV1_DATA/.qpkg/MalwareRemover/MalwareRemover.sh scan;#_QSC_:MalwareRemover:malware_remover_schedule:None:d::
00 01 * * * sh /share/CACHEDEV1_DATA/.qpkg/MalwareRemover/Upgrade.sh;#_QSC_:MalwareRemover:malware_remover_upgrade:None:d::
14 7 * * * /share/CACHEDEV1_DATA/.qpkg/HybridBackup/rr2/scripts/insight/insight.sh -runall >/dev/null 2>&1
0 23 */1 * * /sbin/qpkg_cli -U 1>/dev/null 2>/dev/null
26 1 * * * /bin/sh /etc/init.d/disk_data_collection.sh
* * * * * /var/cache/netmgr/lock_timer.sh
0 0 * * * /usr/local/sbin/qulog-archive local_event retention 0 >/dev/null 2>&1
0 1 * * * /usr/local/sbin/qulog-archive remote_event retention 0 >/dev/null 2>&1
0 2 * * * /usr/local/sbin/qulog-archive local_access retention 0 >/dev/null 2>&1
0 3 * * * /usr/local/sbin/qulog-archive remote_access retention 0 >/dev/null 2>&1
0 4 * * * (source /etc/init.d/qulog.sh dummy; check_mariadb) >/dev/null 2>&1
50 7 * * * /sbin/qpkg_cli --check_license 0 > /dev/null 2>/dev/null
0 4 * * * /etc/init.d/wsd.sh restart
0 3 * * * /sbin/vs_refresh
4 3 * * 3 /etc/init.d/backup_conf.sh
0 12 * * * /mnt/ext/opt/LicenseCenter/bin/qlicense_tool local_check
0 0 * * * /usr/local/sbin/qsh nc.archive >/dev/null 2>&1
0 1 * * * (source /etc/init.d/nc.sh dummy; check_mariadb) >/dev/null 2>&1
04 16 * * * /mnt/ext/opt/QcloudSSLCertificate/bin/ssl_agent_cliめ

めっちゃごっつりだな、おい。
まぁ、動いてそうです。
これで cron 動いてないとかだったらアホかと言っていいレベル。

1-2. 方針を考える

目的は Plottiing で作成される Plots を保管用の HDD に移動して、作成用ディスクが溢れるのを防止することです。
そのために何をしなければいけないかを考えておきます。

どうせ作っているうちに違う方法に気付くのは明白なので、ここではざっくりと考えればいいです。

・NAS (TS-473) 上のシェルで全てやる
 ・シェルスクリプトで組む
 ・元ファイルの場所と、コピー先のディレクトリを探す必要
・コピー先は複数個所指定して、自動選択してくれるようにする
・cron 利用して定期的に自動実行する
 ・ファイル名は自動で取得する
 ・前の処理が終わってなかったら重複起動される
・動作を確認できるようにする
 ・コピー中なのかどうか
 ・ログを保存

とりあえずこんな感じ?

洗濯物溜まったら洗濯も自動で起動してくれると楽なのに。

1-3. 共有フォルダはどこに?

なにはともあれ、共有フォルダを探さないと何もできません。

画像2

共有の権限設定から、対象フォルダーのプロパティを開くとそれっぽいパスの情報が出てきます。
ただ、デバイス番号?かなんかっぽく、接続の度に変わる可能性があるのかどうかイマイチ判断つきません。
安定してコピーするには固定の名前が必要です。

シェルからも調べてみましょう

[~] # df
Filesystem                Size      Used Available Use% Mounted on
none                    400.0M    261.8M    138.2M  65% /
devtmpfs                 31.4G      8.0K     31.4G   0% /dev
tmpfs                    64.0M    788.0K     63.2M   1% /tmp
tmpfs                    31.4G    136.0K     31.4G   0% /dev/shm
tmpfs                    16.0M         0     16.0M   0% /share
/dev/sde5                 7.8M     28.0K      7.8M   0% /mnt/boot_config
tmpfs                    16.0M         0     16.0M   0% /mnt/snapshot/export
/dev/md9                493.5M    136.1M    357.4M  28% /mnt/HDA_ROOT
cgroup_root              31.4G         0     31.4G   0% /sys/fs/cgroup
/dev/mapper/cachedev1
                        14.2T     10.5T      3.7T  74% /share/CACHEDEV1_DATA
/dev/md13               417.0M    380.4M     36.6M  91% /mnt/ext
tmpfs                    48.0M     72.0K     47.9M   0% /share/CACHEDEV1_DATA/.samba/lock/msg.lock
tmpfs                    16.0M         0     16.0M   0% /mnt/ext/opt/samba/private/msg.sock
/dev/sdf1                 7.3T      1.2T      6.1T  16% /share/external/DEV3303_1
/dev/sdj2                 7.3T      1.1T      6.2T  15% /share/external/DEV3309_2
/dev/sdi2                 7.3T      1.1T      6.2T  15% /share/external/DEV3310_2
/dev/sdh2                 7.3T      1.1T      6.2T  15% /share/external/DEV3311_2
/dev/sdg2                 7.3T      1.1T      6.2T  15% /share/external/DEV3312_2

tmpfs だらけやな?
内蔵ディスクの RAID が /dev/mapper/cachedev1 ってどういうことなの?
とりあえず /share/external/ 以下にあるっぽいことはわかりました。

[~] # ls /share/external/
DEV3303_1/  DEV3310_2/  DEV3312_2/  sdb/  sdd/  sdf/  sdh/  sdj/  sdl/  sdn/  sdp/  sdr/  sdt/  sdv/  sdx/  sdz/
DEV3309_2/  DEV3311_2/  sda/        sdc/  sde/  sdg/  sdi/  sdk/  sdm/  sdo/  sdq/  sds/  sdu/  sdw/  sdy/で

でもやっぱりデバイス番号…

なので、ちょっとこのパスを共有フォルダ名に書き変えてみましょう。

とかやってはいけません!
いーけーまーせーんー!!!

いや、本当はやってもいいのかもしれないけど、うちの環境でそれやったらディスクの認識に問題が発生し、ディスク関連の機能に全くアクセスできなくなって再起動する羽目になりました。

色々戻しーの…気を取り直しーの…

/share/external/ ってことは、/share/ があるんじゃね?

g[~] # ls -l /share/
total 4
drwxrwxrwx 38 admin administrators 4096 2021-07-04 17:21 CACHEDEV1_DATA/
drwxrwxr-x 33 admin administrators  660 2021-07-02 15:07 external/
drwxrwxrwx  2 admin administrators   40 2005-09-19 12:32 HDA_DATA/
drwxrwxrwx  2 admin administrators   40 2005-12-07 20:41 HDB_DATA/
(略)
drwxrwxrwx  2 admin administrators   40 2005-12-07 20:42 HDY_DATA/
drwxrwxrwx  2 admin administrators   40 2005-12-07 20:42 HDZ_DATA/
lrwxrwxrwx  1 admin administrators   20 2021-07-02 15:08 homes -> CACHEDEV1_DATA/homes/
lrwxrwxrwx  1 admin administrators   21 2021-07-02 15:08 NAS2-1 -> CACHEDEV1_DATA/NAS2-1/
lrwxrwxrwx  1 admin administrators   18 2021-07-02 15:08 NAS2-U1 -> external/DEV3303_1/
lrwxrwxrwx  1 admin administrators   18 2021-07-02 15:08 NAS2-U2 -> external/DEV3312_2/
lrwxrwxrwx  1 admin administrators   18 2021-07-02 15:08 NAS2-U3 -> external/DEV3311_2/
lrwxrwxrwx  1 admin administrators   18 2021-07-02 15:08 NAS2-U4 -> external/DEV3310_2/
lrwxrwxrwx  1 admin administrators   18 2021-07-02 15:08 NAS2-U5 -> external/DEV3309_2/
lrwxrwxrwx  1 admin administrators   21 2021-07-02 15:08 Public -> CACHEDEV1_DATA/Public/
lrwxrwxrwx  1 admin administrators   18 2021-07-02 15:08 Web -> CACHEDEV1_DATA/Web/びびnるほど

ビンゴ!

/share/<共有名>/ でアクセスすれば良さそうです!

1-4. スクリプトが消えた!?

再起動とか試していて、ある時ふと気づきました。

[~] # ls
index_default.html
[~] #

ホームに置いてたファイルが無い!?

これは、定期的に消されるのか、再起動で消されるのか、どちらにしても消えてしまう場所には置いておけません。
ちゃんと調べればわかる(ユーザーフォルダとかの関係だと思うけど)だろうけど、面倒なので共有フォルダ内に置いてしまうことにします。そこなら消えないでしょう。

<2021/7 追記>
どうも、QTS のバージョンアップをするとシステム標準のディレクトリのものは消えてしまうらしい?
ある時自動実行されてないことに気付いて見てみたら crontab も初期化されてしまっていた…
<さらに追記>
普通に再起動した後も crontab 消えてた。
ていうか外部ディスクの抜き差しだけでも消えてるような気も…構成変更で消える?

共有フォルダ内で、. で始まるディレクトリを作れば隠しフォルダになるのでそうします。

[/share/NAS2-1] # mkdir .bin
[/share/NAS2-1] # ls -a
./
../
.bin/
Moved/
New/
plot-k32-...
  :
  :

画像1

Windows から見えてないので OKOK。


2. スクリプトを作る

では、本格的にスクリプトを作っていきましょう。

2-1. 対象ファイルを探す

コピー対象となるファイルは Plots なのでファイル名フォーマットが決まっています。

しかし、ファイル名は見てみないとわかりません。

また、起動したときに「ファイルがいくつあるかわからない、無いこともある」という点も考慮する必要があります。

なので、
・ファイル名はリストで取得する
・ファイルが無い場合を検出する
ために glob (ワイルドカード展開) を使います。

targetPtn="plot-*.plot"
files=`echo $targetPtn`

# No targets?
if [ X"$files" = X"$targetPtn" ]; then exit; fi

結果はスペース区切りで列挙されているので、普通に取得すればリストとして使えます。

bash の glob は「対象が無いと指定した文字列をそのまま返す」という素敵仕様なので、元の文字列と比較すれば容易に「ファイルが無かった」チェックができます。

テスト中はパターンをもっと絞り込めば 1~2ファイルだけを対象にしたり簡単にできます。

2-2. ファイルをコピーする

同じディスク内の移動ならともかく、別ディスクだとコピー自体にも結構な時間がかかります。
その間にプログラムに補足されてアクセスされてしまうと色々問題が出そうなので、
 ・pool 以外のディレクトリにコピーして完了後に mv する
 ・拡張子を変更してコピー完了後に mv する
とかで回避します。

どっちのやり方でもいいんだけど、今回は拡張子を変更する方法にしました。
というか最初は別ディレクトリ方式にしてたけど、チェック中ディレクトリを色々見なきゃいけなくてめんどくなった(笑)

転送元のファイルも、どれを処理しているのかわかるように変更するようにしましょう。

for f in $files
do
  mv ${f} ${f}.moving

  echo -n "Moving '$f' to $DST ... "
  cp ${f}.moving "${DSTDISK}/"

  mv ${f}.moving ${f}.moved
  mv "${DSTDISK}/${f}.moving" "${DSTDISK}/${f}"
done

クォートのアンバランスは気にしない方向で…

2-3. コピー後に比較する

Windows でコピーしていたとき、時々コピー後にファイルが破損していることがありました。
そのため、Windows でのコピー時には FastCopy を使うようになった(遅い)のだけど、当然 Linux 上にはありません。
まぁ、探せばあるのかもしれんけど。

しかし、QTS 上の Linux さんには md5sum / sha1sum / sha256sum というファイルのチェックサムを生成してくれるプログラムが入っています。
どれも、実行すると

[/] # md5sum /etc/fstab
af376dd26979a742556bf37e5582d7a5  /etc/fstab
[/] # sha1sum /etc/fstab
e040e4c9b3faca6babbef9b0572e367d824c2c43  /etc/fstab
[/] # sha256sum /etc/fstab
506c24d3fbd486d21d24679ba6f0751a2054e10a0d7ba92a31903ff51b9886a3  /etc/fstab

みたいな感じで
チェックサム ファイル名
という出力をしてくれます。

今回は改ざんチェックではなくコピー失敗のチェックなので、MD5 でよかろってことにします。

echo -n "checking ... "
cs=(`md5sum ${f}.moving`)
ds=(`md5sum ${DSTDISK}/${f}.moving`)
if [ X"${cs[0]}" = X"${ds[0]}" ]; then
  echo "OK"
else
  echo "NG"
fi

とりあえず動いているみたい。
違うファイルを指定すると簡単に失敗を試せるのが良いところ。

これを使って失敗した場合の処理を考えますが、
リトライを書くのも面倒なので、元ファイルを元に戻し、コピー先を削除したうえで「なかったこと」にして次のタイミングに再度処理してもらうことにします。

2-4. コピー先を自動選択する

現在、NAS には 8T の USB-HDD が5台繋がっています。
これらにコピーしていくわけだけど、どれを選ぶかを必要に応じて書き変えるというのは、大した手間じゃないとはいえエレガントではありません
自動化したメリットも半減です。

なので、コピー先も自動で選択してもらうことにします。

DSTS="NAS2-U1 NAS2-U2 NAS2-U3 NAS2-U4 NAS2-U5"

DST=""
CNT=10000
for d in $DSTS
do
  # Current Files
  c=`ls /share/$d/ | wc -l`

  # Least Files Check
  if [ $c -lt $CNT ]; then
    CNT=$c
    DST=$d
  fi
done

DSTDISK="/share/$DST"

今回は負荷を分散する目的で「できるだけ各ディスクの Plot 数が同じになるように」設定しました。
ここは
・指定した順番に
・ディスクを埋めるため、残り容量の少ないものから
・容量差があっても、同じ割合になるように
などいろいろ考えられると思います。

ついでにコピーできる最大数もチェックできるようにしましょう。
各容量の HDD に保存できる Plots 数は経験でわかっているのでファイル数をチェックすれば良いだけです。

4T : 36個
6T :  55個
8T :  73個
12T : 110個
14T : 128個

他の容量は知らない。

容量の指定方法が必要だけど、今回は共有名の末尾に :数 とすることにします。

DSTS="NAS2-U1:73 NAS2-U2:73 NAS2-U3:73 NAS2-U4:73 NAS2-U5:73"

for dm in $DSTS
do
  # GET DSTDir & MaxFiles
  DM=(${dm//:/ })
  d=${DM[0]}
  m=${DM[1]}

  # Current Files
  c=`ls /share/$d/ | wc -l`

  # Max Files Check
  if [ $(($c + 1)) -ge $m ]; then continue; fi

 :
  :
done

また、最大容量のチェックがあると「全てのディスクが埋まっている」可能性が検知できるのでそのチェックを追加します。

# No Space...
if [ X"$DST" = X"" ]; then
  echo "No space to move."
  for f in $files
  do
    if [ -e "${f}.${pf}" ]; then mv ${f}.${pf} ${f}; fi
  done
  exit
fi

まぁ、そんなに難しいことはしていないです。
注意するのは「予約中のファイルが残ってたら元に戻す」ことだけですね。

放置してたらどうせ次も空き容量なしで失敗するんですが…

2-5. 同時実行性を高める

なんかの拍子に同時に実行しちゃって、同じファイルをコピーしようとしたりするとトラブルになる可能性が高い為、抑制します。

mutex とかちゃんとやるって手もあるけど、使うの自分だけで事故対策なので雑な方法でやります。

そういや全然関係ないけど、昔の「プログラム言語C」は critical section を「危険な領域」と訳してて、「危険な領域に入る」とかなんかドキドキする言い回しがあったことを思い出した。
他にも「回るこまどり(round robin)」とか名言多数だった。
今どうなってるんだろ?

要は対象ファイルとして抽出されなければいいので、対象として認識した瞬間に「対象のファイル名パターン」から外れるファイル名に変更してしまえばいいのです。

pid=$$
pf="prepare.${pid}"

# reserve
for f in $files
do
 mv ${f} ${f}.${pf}
done

ついでなので、動作中のスクリプトの PID もわかるようにしておきます。
わかるだけでなく、「自分が処理しているファイル」を探すのにも使えます。

変数がひどいけど気にしない。
何故コメントは reserve なのに ファイル名は prepare なのかとかも気にしない。

一応、前処理の一瞬の間に複数起動されてしまうことも考えて、処理前に

if [ ! -e "${f}.${pf}" ]; then continue; fi

することで、「自分以外が何かしちゃったのかも」としてスキップが可能になりました。

2-6. 最終的なスクリプト

というわけで、最終的にはこんな感じになりました。

#! /bin/sh

# Target ( SRC / DST:MaxFiles )
SRC=NAS2-1
DSTS="NAS2-U1:73 NAS2-U2:73 NAS2-U3:73 NAS2-U4:73 NAS2-U5:73"

# directories
SRCDISK="/share/$SRC"
NewDir="New"
MovedDir="Moved"

pid=$$
pf="prepare.${pid}"

#
# Get plots to move
#

cd "$SRCDISK/$NewDir/"

targetPtn="plot-*.plot"
files=`echo $targetPtn`

# No targets?
if [ X"$files" = X"$targetPtn" ]; then exit; fi

fc=`echo "$files" | wc -w`
echo `date +"[%Y-%m-%d %H:%M:%S]"` "Found $fc new files."

# reserve
for f in $files
do
  mv ${f} ${f}.${pf}
done

# each files
for f in $files
do
if [ ! -e "${f}.${pf}" ]; then continue; fi

#
# Search destination
#

DST=""
CNT=10000
for dm in $DSTS
do
  # GET DSTDir & MaxFiles
  DM=(${dm//:/ })
  d=${DM[0]}
  m=${DM[1]}

  # Current Files
  c=`ls /share/$d/ | wc -l`

  # Max Files Check
  if [ $(($c + 1)) -ge $m ]; then continue; fi

  # Least Files Check
  if [ $c -lt $CNT ]; then
    CNT=$c
    DST=$d
  fi
done

# No Space...
if [ X"$DST" = X"" ]; then
  echo "No space to move."
  for f in $files
  do
    if [ -e "${f}.${pf}" ]; then mv ${f}.${pf} ${f}; fi
  done
  exit
fi

DSTDISK="/share/$DST"

#
# Move plot
#

SECONDS=0

mv ${f}.${pf} ${f}.moving

echo -n "Moving '$f' to $DST ... "
cp ${f}.moving "${DSTDISK}/"

echo -n "checking ... "
cs=(`md5sum ${f}.moving`)
ds=(`md5sum ${DSTDISK}/${f}.moving`)

if [ X"${cs[0]}" = X"${ds[0]}" ]; then
  # OK (Remove original) / TEST: Move original to $Moved Dir
  rm ${f}.moving
  #mv ${f}.moving "${SRCDISK}/${MovedDir}/${f}"
  mv "${DSTDISK}/${f}.moving" "${DSTDISK}/${f}"
  echo "done. (${SECONDS} sec)"
else
  # NG (Restore original to $NewDir)
  mv ${f}.moving ${f}
  rm "${DSTDISK}/${f}.moving"
  echo "error."
fi

done

echo `date +"[%Y-%m-%d %H:%M:%S]"` "done."
exit

なんかちぐはぐなのは気にしない:)

3. 自動で起動する

スクリプトはできたので自動で起動させます。
crontab の末尾に登録します。

[/] crontab -e
--
#
*/30 * * * * (cd /share/NAS2-1/.bin; sh ./movePlots.sh >>moved.log 2>>error.log )
--
[/] # crontab -l
# m h dom m dow cmd
0 3 * * * /usr/local/sbin/ImR_all -soft /Qmultimedia
0 2 * * * /sbin/qfstrim
  :
 (略)
  :
0 1 * * * (source /etc/init.d/nc.sh dummy; check_mariadb) >/dev/null 2>&1
04 16 * * * /mnt/ext/opt/QcloudSSLCertificate/bin/ssl_agent_cli
#
*/30 * * * * (cd /share/NAS2-1/.bin; sh ./movePlots.sh >>moved.log 2>>error.log )
[/]

30分に1回起動します。
今、平均すると1時間に1個くらい生成してるけどムラがあるので、30分なら多くても一度で捕捉されるのは 3-4個くらいかな。
まぁそんなもんでいいでしょう。

いつもならログの出力は () の外に書く(サブシェルの出力全体をログりたい)んだけど、ディレクトリを重複して書かなきゃいけないのでやめた。

4. 確認する

翌日あたりに確認してみます。

画像3

テストとかで適当に転送してバラバラのファイル数だったのが気付くと揃っています。いい感じ。

ログもみて問題ないことを確認します。

[2021-07-XX XX:00:00] Found 1 new files.
Moving 'plot-k32-....plot' to NAS2-U5 ... checking ... done. (1624 sec)
[2021-07-XX XX:27:04] done.
[2021-07-XX XX:30:00] Found 2 new files.
Moving 'plot-k32-....plot' to NAS2-U1 ... checking ... done. (1634 sec)
Moving 'plot-k32-....plot' to NAS2-U2 ... checking ... done. (1594 sec)
[2021-07-XX XX:23:48] done.
[2021-07-XX XX:00:00] Found 2 new files.
Moving 'plot-k32-....plot' to NAS2-U3 ... checking ... done. (1650 sec)
Moving 'plot-k32-....plot' to NAS2-U4 ... checking ... done. (1750 sec)
[2021-07-XX XX:56:40] done.
[2021-07-XX XX:00:00] Found 1 new files.
Moving 'plot-k32-....plot' to NAS2-U5 ... checking ... done. (1729 sec)
[2021-07-XX XX:28:49] done.
[2021-07-XX XX:30:00] Found 1 new files.
Moving 'plot-k32-....plot' to NAS2-U1 ... checking ... done. (1681 sec)
[2021-07-XX XX:58:01] done.な

なんかたまたまギリギリで終わってるけど、処理が重なるとログが混在して見づらいんだよね。処理中から出力してるから仕方ないんだけど。

5. 転送速度

ログを見ると 1ファイル概ね 1600-1700秒くらいで終わっているようです。
全行程には
・コピー(RAID0 からの読込&HDDへの書込)
・内蔵HDD RAID0 の MD5(読込)
・USB-HDD の MD5(読込)
がかかります。

転送先の HDD はただの USB3 の HDD です(USB3.2 Gen1 で繋がってるらしい)
なので、転送速度はほぼ HDD 本体の速度が上限で、まぁ 250MB/s くらいと見ましょうか。
そうすると、1GB に 4秒なので、100GB に 400秒 かかる計算になります。

ソースになる RAID0 はもっとずっと速いので(10GbE 経由で 1GB/s の上限値出る)、理想的には 1000秒くらいで終わってもよさそうなものですが、かなりのオーバーヘッドがあるようです。

で、どこが時間かかってるのか気になったので、1回、各フェーズの数字も出してみました。
同時に動いてる Plot の処理とかの関係でも変わってきちゃうので参考程度に。

 コピー: 595秒
 RAID0 の MD5: 299秒
 USB の MD5: 723秒

USB-HDD へのアクセスが遅い気もするけど、それ以上に MD5 の計算が遅い…?
どうせなので、openssl を使った場合や、SHA-1 や SHA-256 の場合も試してみましょうか。同じファイルを使うとキャッシュの影響受けそうなので、毎回違うファイルを使います。

[/] openssl dgst -md5 ...
MD5(...)= ...

real    5m22.227s
user    2m41.430s
sys     0m44.921s

[/] openssl dgst -sha1 ...
SHA1(...)= ...

real    5m54.351s
user    2m18.179s
sys     0m45.763s

[/] openssl dgst -sha256 ...
SHA256(...)= ...

real    11m55.843s
user    5m16.946s
sys     0m56.915s

[/] md5sum ...
... ...

real    7m58.355s
user    4m1.858s
sys     0m52.303s

[/] sha1sum ...
... ...

real    12m54.304s
user    11m24.623s
sys     0m54.795s

[/] sha256sum ...
... ...

real    9m44.613s
user    8m31.385s
sys     0m50.459s

なんか全体の時間がブレブレなんだけど、重要なのは user の部分。

[openssl] MD5: 161秒 / SHA1: 138秒 / SHA256: 316秒
[単体コマンド] MD5: 241秒 / SHA1: 684秒 / SHA256: 510秒

うーん、リアルタイムでディスク暗号化できるくらいなんだからもう少し速くてもよさそうなもんなんだが。ハッシュ値計算にも AES-NI 使えるみたいなこと読んだ気もするんだけど違うのかな。
どちらにしても、単体コマンドは遅すぎる。

ということで、openssl の sha1 を使うことにしましょう。
結果の出力形式が違うので、そこも調整。

あ、速度しか違わないので、↑ のスクリプトには変更は反映されてませんよ。

これで、一週間くらいやってみようと思います。

この記事が気に入ったらサポートをしてみませんか?