OpenMediaVault7 (OMV7) で作る PC1台 54TB RAID5 システム【Part 2】

これまで、OpenMediaVault 5 (以後 OMV5) 、OpenMediaVault 6 (以後 OMV6) を使って RAID Z 、RAID Z2 を実現し、使ってまいりましたが、ディスクの使用容量が増えるにしたがって、動作に問題が生じて来ました。読み出し時に一瞬止まるのです。主に動画で再生時に詰まった様な動作になるのです。一時間の再生動画で 1-2 回以上は一瞬止まります。RAID Z, RAID Z2 はメモリー食いなのでメモリー不足なのかも知れません。それに、大容量のディスク装置も結局は殆ど NAS として使っているだけなので、今一 RAID Z, RAID Z2 の機能が生かしきれていません。・・で、ディスクの容量増大に伴って、軽いシステムである RAID5, RAID6 を OpenMedia 7 (以後 OMV7) で実現、全面的に移行します。

さて、【Part 2】では、簡単な 運用時のメンテナンス、運用時のコピーツール等を紹介した後に、いざと言う時のディスクの取り換え等について備忘録的に書いておきます。

運用時のメンテナンス

運用時のメンテナンスと言っても、実際にやるのは 2種類でしょう。一つは、RAID 自体のメンテナンスとして RAIDシステムのスクラビング、もう一つは、ファイルシステム メンテナンスのファイルシステムのデフラグ でしょう。

RAIDスクラビング

スクラビングという言葉を聞きなれない人もいると思いますが ( 私もその一人です (^0^) )。グーグル先生曰く、RAID5/6で構築されたRAIDグループの全データを読み込み、読み取り不可ブロックやパリティ異常を検出した場合その修正を試みRAIDグループ上のデータの整合性を回復させます。との事です。要するに、ディスクをフルスキャンしてRAIDシステム上のパリティの不整合を( できる範囲で ) 修正して回復させる操作です。

スクラビングは “check” を “sync_action” に書き込む事で始まります。

# echo check > /sys/block/md0/md/sync_action

進行具合は cat /proc/mdstat とステータスを見る事で確認する事ができます。安全にストップするには、同様に “idle” を書き込む事でストップできます。

# echo idle > /sys/block/md0/md/sync_action

スクラブが完了したら、(不良セクタがあった場合) いくつのブロックが不良として判断されたか “mismatch_cnt” を読み出して、確認することができます

# cat /sys/block/md0/md/mismatch_cnt

一寸、やってみます。(対象は 2TB x 3 = RAID5) です。

な感じで進められそうですね。

ファイルシステムのデフラグ

デフラグは WinPC でもよくやります。WinPC の場合はグラフィカルインターフェースが一般的ですが、OMV7 ( = Linux system ) では ext4 フォーマットの場合は e4defrag を走らせます。

# e4defrag [オプション] 対象 となります。

オプションは

  -c : 現在の状態を確認する (デフラグは実行しない)
  -v : 状況を詳しく表示する

ですので、使うのは難しくないでしょう。まず、最小 -c オプションを付けて、現状を確認します。その時に ( 数値で ) デフラグが必要かどうか教えてくれます。

使う時に気をつけるのは USB メモリをデフラグすると痛みますので、マウントされているハードディスクをデフラグするようします。例えば

# e4defrag -v /

とすると / の存在している媒体 (=USBメモリ) を対象としますので、メモリが痛みますし、またデフラグの必要もないでょう。

# e4defrag -v /array-0/RAID5-0

とすれば、RAID5-0 の存在する媒体はハードディスクとなりハードディスクをデフラグする事になります。

実行の頻度は..

実行の頻度は適当ですが、まあ多くともスクラビングは 1回 / 1月 程度に収めるのが良いでしょう。あまり頻繁にやるとディスクを痛めますので本末転倒です。( 私は半年に一回程度にしています。)

デフラグは -c オプションがありますので、時々調べてみてシステムのお勧めにしたがうのが良いと思います。こちらも頻繁に実行するとディスクを痛めます。RAID ではなく通常のディスクの場合ですが、”3日に一回デフラグを実行していた場合は1年でディスクが壊れた” なんて例があるとかないとか。

運用時のツール

次に運用時に便利に使えるツールを作りました。OMV6( Linux system ) → OMV7( Linux system ) で多量のデータ移動 ( copy 又は move ) が必要になります。また私はファイル名に日本語を多用していますので、日本語を含んだフォルダ間で便利に使える RemoteSync suport スクリプト を作りました。

Nfs プロトコルで、共有フォルダーをマウントする。

cp, mv, rsync 等 Linux のコマンドは、別サーバーの共有フォルダをシステムにマウントして使います。Nfs プロトコルを使って他の Linux system のフォルダを この Linux system のフォルダにマウントしてみましょう。192.168.11.21 の RAID Z2 ( OMV6 ) のフォルダーをマウントします。まず最初に 192.168.11.21 OMV6 の管理画面に入って、Nfs でマウントされる許可を設定します。

サービス → NFS → 共有 → ⊕(作成) で入った画面に以下の設定をします。

次に、クライアント側 ( =この Linux systemです ^o^ ) の設定です。

こちらは、例えば /array-1 にマウントさせるには ( この場合 root 同士でマウントして、password も同じとしています )

# mount -t nfs 192.168.11.21:/ /array-1

と打ちます。私はこのコマンドの書式を頻繁に(?) 忘れてしまうので、備忘録的に NfsSet.sh なるスクリプトを作りました。あくまで備忘録ですので、みなさんは直接コマンド打ってくださいね。マウント先も /array-n に決めています。

#!/bin/bash

# サーバー側の共有設定はサーバーのStartUptime後に実行
# サーバー側で Nfs サービスの共有を先に行う事

# NfsSet.sh ( Nfs protocol Set program )

if [ $# != 2 ]; then
    echo ""
    echo " (例) NfsSet.sh <From IP> <array-No> "
    echo " NfsSet.sh 192.168.11.21 1 → mount -t nfs 192.168.11.21:/ /array-1"
    echo ""
fi

if [ $# = 2 ]; then
    echo "# mount -t nfs $1:/ /array-$2"
    mount -t nfs $1:/ /array-$2
fi

マウント解除は 普通のマウント同様に # umount /array-n で出来ます。一寸、やってみます。(先にサーバー側の共有設定は実行しています。)

rsync補助 プロトコル

rsync を日本語、スペース、交じりのフォルダー等の場合に便利に使える補助プロトコル RemoteSync.sh を作りました。主に日本語交じりフォルダーを扱いやすくするものです。少し長い説明になりますが、役に立つと思いますので、ご覧ください。

最初におおまかな動作を説明します。[ ] 内は フォルダ名を表します(スペースも含みます) 。 array-1 に続くフォルダ [北海道 海] .. [北海道 川] は その下にさらに複数のファイル、フォルダーを保持しているとします。これを / array-0 に続くフォルダーに [北海道 海] .. [北海道 山] までを下図のイメージでコピーする事を考えます。

RemoteSync.sh は 3 つの主レジスタをもちます。このレジスタは /var/log … の下に配置してありますので、RAM領域になります。Shutdown 時に正規の手順を踏めば USBメモリーに書き込まれるので、次の Power-on 時にも内容が再現されます。

$RS_SOR(=/var/log/installer/Remote_sor) には ソース側 (コピー元) のベースDIR格納領域です。上図では [ array-1 / RAID2Z-0 / 日本の景色] までを記録しておきます。RemoteSync.sh は $RS_SOR の最初の1行のみ参照します。2行目以降は有っても、無くても動作に変わりありません。2行目以降に複数のベースDIRを記録しておき、動作前にエディタで入れ替えて使う事もできます。

$RS_LST(=/var/log/installer/Remote_lst) は ソース側 (コピー元) の最後尾のDIRをリストとして記録します。RemoteSync.sh は $RS_LST を読み出しリストが無い行に行き当たるまで実行を続けます。上図の例を実行するには [北海道 山] [北海道 川] [北海道 湖] と記録してあれば、この3つのDIRをコピーします。同様に [北海道 山] [北海道 川] [北海道 湖] [ ] [北海道 海] と記録してあればリストが無い行で止まるので最初の3つのDIRをコピーします。上図の例とは異なりますが、例えば [ ] [北海道 山] [北海道 川] [北海道 湖] [北海道 海] と記録してあれば最初のリストが無い行で止まるので何もコピーしません。リストの配置で動作を変えられるので、最初に全てのリストを記録しておき、エディタでリストを編集する事で所望の動作をさせます。ソース側 (コピー元) のディレクトりは$RS_LSTの行毎に $RS_SOR + $RS_LSTの合成で作成されます。

$RS_DST(=/var/log/installer/Remote_dst) はディストネーション側 (コピー先)のベースDIR格納領域です。上図では [ array-0 / RAID5-0 / 日本の景色] までを記録しています。RemoteSync.sh は $RS_DST の最初の1行のみ参照します。2行目以降は有っても、無くても動作に変わりありません。2行目以降に複数のベースDIRを記録しておき、動作前にエディタで入れ替えて使う事もできます。

rsync はデフォルトではコピー完了をファイルの 日付け、byte数 確認で行っています。checksum を確認する方法もあります。(checksum確認の方法は時間が掛かる) RemoteSync.sh ではパラメータに c 又は C を付けると checksum での確認が選べます。

rsync -av –info=progress2  コピー元の合成DIR コピー先のベースDIR   ( c パラメータ無し)

rsync -avc –info=progress2  コピー元の合成DIR コピー先のベースDIR         ( c パラメータ有り)

大体の動作の雰囲気は分かったとおもいますので、細かく説明していきます。以下に RemoteSync.sh のリストを示します。実行フラグを忘れないで下さい。なお、このリストは再コピペして一応の動作確認をして有ります。

#!/bin/bash

# RemoteSync.sh ( RemoteSync suport program )

# export RS_SOR=/var/log/installer/Remote_sor
# export RS_LST=/var/log/installer/Remote_lst
# export RS_DST=/var/log/installer/Remote_dst

DEF_SOR="/array-1/RAIDZ2-0/日本の景色"
DEF_DST="/array-0/RAID5-0/日本の景色"
DEF_LST="北海道 海"

if [ $# != 1 ]; then

    echo ""
    echo "  cd to RemoteSync_SOuRce dir      → pwd > \$RS_SOR "
    echo "   add RemoteSync_source LiST      → ls > \$RS_LST "
    echo "              & edit \$RS_LiST      → nano \$RS_LST "
    echo "  cd to RemoteSync_DiSTination dir → pwd > \$RS_DST "
    echo ""
    echo "   (例) # RemoteSync.sh c or other"
    echo ""
    exit 0
fi

if [ $# = 1 ]; then
    RMODE=-av
    if [ $1 = c ]; then
        RMODE=-avc
    elif [ $1 = C ]; then
        RMODE=-avc
    fi
fi

# Exist check for RS_SOR
if [ -e $RS_SOR ]; then
    read SOR_0 < $RS_SOR
fi
# Zero check for SOR_0
if [ ${#SOR_0} = 0 ]; then
    echo $DEF_SOR > $RS_SOR
fi
read SOR_0 < $RS_SOR

# Exist check for RS_DST
if [ -e $RS_DST ]; then
    read DST_0 < $RS_DST
fi
# Zero check for DST_0
if [ ${#DST_0} = 0 ]; then
    echo $DEF_DST > $RS_DST
fi
read DST_0 < $RS_DST

ZERO=1
# Exits check for RS_LST
if [ -e $RS_LST ]; then
    # Not_Zero check for SOR_1
    while read SOR_1; do
        if [ ${#SOR_1} != 0 ]; then
            ZERO=0
        fi
    done < $RS_LST
fi
if [ $ZERO = 1 ]; then
    echo $DEF_LST > $RS_LST
fi
read SOR_1 < $RS_LST

echo ""
echo "# rsync $RMODE --info=progress2 <From dir> <To dir>"

while read SOR_1; do
    if [ ${#SOR_1} = 0 ]; then
        break
    fi
    echo ""
    echo "From : $SOR_0/$SOR_1"
    echo "To : $DST_0/$SOR_1"
done < $RS_LST

echo ""
echo -n "よろしいですか? [Y/n]: "

read ANS
case $ANS in

    Y )
        # Path to RemoteSync Start!!!
    ;;

    y )
        # Path to RemoteSync Start!!!
    ;;

    * )
        echo ""
        echo "# RemoteSync Not Started !!!"
        echo -n "# "; date;
        echo ""
        exit 0
    ;;
esac

echo "# RemoteSync Start!!!"
echo -n "# "; date;
echo ""

while read SOR_1; do
    if [ ${#SOR_1} = 0 ]; then
        break
    fi
    echo ""; date
    echo "From : $SOR_0/$SOR_1"
    echo "To   : $DST_0/$SOR_1"
    echo ""
    rsync $RMODE --info=progress2 "$SOR_0"/"$SOR_1" "$DST_0"
done < $RS_LST

echo ""
echo "# RemoteSync Finish (^o^)"
echo -n "# "; date;
echo ""

RemoteSync.sh を使用する前に幾つか準備をします。まず環境変数を三つ導入します。以下を実行すれば良いのですが、自動で実行できるよう、~# .profile の最後に3行追加します。これで SSH 端末を開くたびに $RS_SOR, $RS_LST, $RS_DST が環境変数として設定されます。

export RS_SOR=/var/log/installer/Remote_sor
export RS_LST=/var/log/installer/Remote_lst
export RS_DST=/var/log/installer/Remote_dst
                              を ~# .profile に追加する。

コピー元DIR に移動します。上図の例で言うと  /array-1/RAIDZ2-0/日本の景色 に移動して pwd > $RS_SOR と入力、これは pwd > /var/log/installer/Remote_sor と同じなのですが、環境変数を導入してあるので、簡単に入力できます。これで、コピー元 ベースDIR が設定されました。もし、2行目、3行目に予備の ベースDIR を設定しておきたいならば、そのDIR に移動してから pwd >> $RS_SOR と入力すれば2行目以降に追加で設定できます。次にそのDIR のままで (移動しないで )  ls > $RS_LST と入力すると コピー元最後尾のDIRリスト がすべて入力されます。これをエディットして 必要なリストにすれば良いので nano(又は適当なエディタ) $RS_LST でエディット できます。上図の例で言うと [北海道 海][北海道 湖][北海道 山][北海道 川] → [北海道 海][北海道 湖][北海道 山][ ][北海道 川] とエディットします。コピー先も同じです。上図の例で言うと /array-0/RAID5-0/日本の景色 に移動して pwd > $RS_DST と入力します。つまり

コピー元DIRに移動 → pwd > $RS_SOR
                  → ls > $RS_LST  → nano $RS_LST (必要なエディットを行う)
コピー先DIRに移動 → pwd > $RS_DST

で準備ができます。

所で、これらのレジスタを設定しなかったらどうなるのでしょうか。実は RemoteSync.sh が補完してくれます。コピー元DIRのベースとコピー先DIRのベースは メモリー領域が存在しないか、または 一行目になにもかかれていない場合は(2行目があってもなかっても)、RemoteSync.sh が自動的に DEF_SOR, または DEF_DST に置き換えます。つまり “/array-1/RAIDZ2-0/日本の景色”, /array-0/RAID5-0/日本の景色” となります。コピー元最後尾のDIRリストについては 領域が存在しないか、または、メモリー領域を全て ( = 全行 ) 調べて何も書かれていない場合にDEF_LST, つまり “北海道 海” に置き換えます。

さて、準備ができたら実行しましょう。 RemoteSync.sh は必ずパラメータを 一つ付けます。パラメータは c 又は C か それ以外の適当な文字列です。パラメータ無し又は 2つ以上の場合は実行されず、help的な画面がでます。 c パラメータは checksum で確認するか デフォルトで確認するか です。後は使っていけば分かると思います。では、上図の例を実行してみましょう。

ちょっと長いので最初に設定を確認します。内容はコマンドがならんでいるだけですので、見れば解るでしょう。

それでは実行します。

ディスクの交換

ディスク故障時のシュミレーション

RAID ディスク故障時の挙動については今一経験が少ないのですが、読み書きが極端に遅くなるとかで分かるようです。RAIDの状態を詳細に知るコマンド

# mdadm --detail /dev/md0

で出力に degraded (=劣化) の文字があれば、ハードディスクに障害が発生しています。また

# cat /proc/mdstat

でも知る事ができます。この2つのコマンドでRAID の状態を知る事ができます。いざという時の為にディスク故障のシュミレーションをしましょう。今 sdc が故障したと仮定します。故障自体は前述2つのコマンドで知るとして、取り換える手順は

# mdadm --fail /dev/md0 /dev/sdc     ← 故障マークを付けてRAIDに故障をしらせる
# mdadm --remove /dev/md0 /dev/sdc   ← 故障した sdc をRAID から(論理的に)はずす。

ここで、電源を切って故障ディスクを入れ替えます。以下でシュミレーションをします。

故障ディスクを入れ替えて、power-on 後に、sdc をスワイプしておきます。

# mdadm --add /dev/md0 /dev/sdc      ← RAIDに 入れ替えたDISKを追加します。

途中 RAID状態を確認しながら進めます。以下で power-on 後のシュミレーションをします。

てな感じでディスク交換できるみたいです。

PC1台 54TB RAID5 システム

それでは、最期に 2TB Disk から 18TB Disk に切り替えて、54TB RAID5 システムを作成します。と言っても取り立てて変わる所は在りません。 2TB Disk でやった事を再度また繰り返します。Timeout Mismatch対策 を追加します。Timeout Mismatch に関しては HP MicroServer Gen8 2台で 48TB RAID Z2 を実現【Part 3】  を参考にして下さい。StartUptime.sh に追加します。後 StartUptime.sh を整備して 立ち上がり時のエラー等の log が /var/log/installer/StartUptime_log に残るようにしました。

#!/bin/bash

# StartUptime.sh ( StartUp timing program )

PATH=/usr/sbin:/usr/bin:/sbin:/bin

DISK0=$(_DiskId.sh 0)
DISK1=$(_DiskId.sh 1)
DISK2=$(_DiskId.sh 2)
DISK3=$(_DiskId.sh 3)

LOG_SAVE=/var/log/installer/StartUptime_log
LOG_DUST=/var/log/installer/StartUptime_dst

date > $LOG_SAVE

echo "" >> $LOG_SAVE
echo "# mdadm -As /dev/md0 \$DISK0 \$DISK1 \$DISK2 \$DISK3" >> $LOG_SAVE
mdadm -As /dev/md0 $DISK0 $DISK1 $DISK2 $DISK3 >> $LOG_SAVE

MOUNT01=/srv/dev-disk-by-uuid-6ef464aa-d2e4-424a-9267-736ddd521b69
echo "" >> $LOG_SAVE
echo "# mount /dev/md0 $MOUNT01" >> $LOG_SAVE
mount /dev/md0 $MOUNT01 >> $LOG_SAVE

echo "" >> $LOG_SAVE
echo "# mount /dev/md0 /array-0" >> $LOG_SAVE
mount /dev/md0 /array-0 >> $LOG_SAVE

echo "" >> $LOG_SAVE
echo "# smartctl -l scterc,70,70 $DISK0" >> $LOG_SAVE
smartctl -l scterc,70,70 $DISK0 >> $LOG_SAVE

echo "" >> $LOG_SAVE
echo "# smartctl -l scterc,70,70 $DISK1" >> $LOG_SAVE
smartctl -l scterc,70,70 $DISK1 >> $LOG_SAVE

echo "" >> $LOG_SAVE
echo "# smartctl -l scterc,70,70 $DISK2" >> $LOG_SAVE
smartctl -l scterc,70,70 $DISK2 >> $LOG_SAVE

echo "" >> $LOG_SAVE
echo "# smartctl -l scterc,70,70 $DISK3" >> $LOG_SAVE
smartctl -l scterc,70,70 $DISK3 >> $LOG_SAVE

以上です。

 

タイトルとURLをコピーしました