Robocopy を使用して、File Storage NAS SMB ファイルシステム間でデータを移行します。
前提条件
ソースデータは、Virtual Private Cloud (VPC) 内にマウントターゲットがある SMB ファイルシステム上に存在する必要があります。
背景情報
Robocopy は、重複するファイルをコピーせずにディレクトリ構造をミラーリングする Windows の組み込みコマンドラインツールです。日付やタイムスタンプなどのファイルメタデータを保持します。
課金
File Storage NAS ファイルシステム間のデータ移行には、以下の料金が発生する場合があります:
事前準備
中継 ECS インスタンスは、両方のファイルシステムにアクセスできる必要があります。両方が同じ VPC からアクセスできることを確認してください。
-
ソースマウントポイントの情報を確認してください。
移行を開始する前に、ソースファイルシステムのマウントポイントと関連付けられた VPC の詳細を記録してください。詳細については、「マウントポイントの確認」をご参照ください。
説明ご利用のファイルシステムにクラシックネットワーク内のマウントポイントしか存在しない場合は、VPC 内に新しいマウントポイントを作成する必要があります。手順については、「マウントポイントの作成」をご参照ください。
-
移行先ファイルシステムのマウントターゲットを設定します。
-
ファイルシステムが同じリージョンにある場合
-
ソースと移行先のファイルシステムのマウントターゲットが同じ VPC にある場合は、移行先のマウントターゲットの詳細を取得し、手順 セクションに進んでデータを移行します。
-
ソースと移行先のファイルシステムのマウントターゲットが同じ VPC にない場合は、次のいずれかの方法でマウントターゲットを準備します:
-
移行先のリージョンとゾーンにファイルシステムを作成します。マウントターゲットは自動的に作成されます。詳細については、「コンソールでの汎用 NAS ファイルシステムの作成」をご参照ください。
説明従量課金の汎用 NAS (Capacity, Performance, または Advanced) SMB ファイルシステムを購入する際は、ソースのマウントターゲットと同じ VPC と vSwitch を選択してください。これにより、移行先のマウントターゲットが自動的に生成されます。その後、リソースプランを購入してコストを削減できます。
-
既存のファイルシステムにマウントターゲットを作成します。詳細については、「マウントターゲットの追加」をご参照ください。
-
CEN を使用して VPC を接続します。詳細については、「CEN を使用して同一リージョン内の VPC 間で NAS ファイルシステムをマウントする」をご参照ください。
-
-
-
ファイルシステムが異なるアカウントまたはリージョンにある場合
ソースと宛先のファイルシステムが異なるアカウントまたはリージョンにある場合は、CEN を使用して VPC を接続します。CEN を使用してアカウントおよびリージョン間で NAS ファイルシステムをマウントする。
-
操作手順
マウントターゲットを準備した後、中継 ECS インスタンスを作成し、両方の SMB ファイルシステムをマウントして、Robocopy を使用してデータを移行します。
-
ソースと移行先のファイルシステムをマウントします。
重要移行には専用の一時的な ECS インスタンスを使用してください。既存のインスタンスを共有すると、実行中のワークロードと CPU およびネットワークの競合が発生します。
ECS コンソールにログインし、インスタンスの作成 をクリックして、次の主要なパラメーターを設定してください:
-
リージョン: ソースファイルシステムが存在するリージョンを選択してください。
-
ネットワークとゾーン: ソースファイルシステムの VPC、ゾーン、vSwitch を選択してください。
-
インスタンスタイプ: 通常、最小のインスタンスタイプで十分です。
-
イメージ: Windows Server のバージョンを選択してください。Windows Server 2019 を選択することを推奨します。
説明Windows Server 2025 を使用する場合、File Storage NAS ファイルシステムをマウントする前に SMB 署名を無効にする必要があります。管理者として PowerShell で次のコマンドを実行し、インスタンスを再起動してください:
reg add "HKLM\SYSTEM\CurrentControlSet\Services\LanmanWorkstation\Parameters" /v RequireSecuritySignature /t REG_DWORD /d 0 /f -
ストレージ: [Elastic Ephemeral Disk | File Storage NAS | Dedicated Block Storage Cluster (Optional)] セクションで、[ファイルシステムの追加] をクリックし、設定を構成してください。例については、次の図をご参照ください。
説明-
ソースと移行先のマウントターゲットが同じ VPC にある場合、ECS 購入ページで NAS マウント情報を設定できます。ECS インスタンスの起動後、ソースと移行先の NAS ファイルシステムは自動的にマウントされます。
-
マウントターゲットが同じ VPC、リージョン、またはアカウントにない場合は、ECS 購入ページでソースファイルシステムのみを設定してください。インスタンスの起動後、移行先ファイルシステムを手動でマウントしてください。詳細については、「SMB ファイルシステムのマウント」をご参照ください。
-
インスタンスが起動し、両方のファイルシステムがマウントされたら、マウントを確認してください:
net use成功した場合、出力には両方のマウントが表示されます。この例では、ソースは Z ドライブ、移行先は Y ドライブです。
Status Local Remote Network ------------------------------------------------------------------------------ OK Y: \\29e9c24****-eab13.cn-wulanchabu.nas.aliyuncs.com\myshare MicrosoftWindowgNetwork OK Z: \\29fe7f4****-txr31.cn-wulanchabu.nas.aliyuncs.com\myshare MicrosoftWindowgNetwork -
-
データを移行します。
次のコマンドを実行して、ソースファイルシステム (ドライブ Z) から宛先ファイルシステム (ドライブ Y) にデータを移行します。
robocopy Z:\ Y:\ /e /w:5 /z /mt:32説明このコマンドは、指定されたディレクトリ内のデータのみを移行し、ディレクトリ自体は移行しません。
以下の表は、主なパラメーターの説明です。実際の要件に基づいて置き換えてください。
パラメーター
説明
/mt
並行スレッド数を指定します。デフォルト値は 8 です。
値は 1 ~ 128 の整数である必要があります。
この例では、マルチスレッドコピーのために 32 スレッドを使用しています。
/w
エラー発生後の再試行間隔(秒単位)を設定します。
/z
再開可能なモードでファイルをコピーします。
/e
空のディレクトリを含むサブディレクトリをコピーします。
/copyall
以下のすべてのファイル情報をコピーします。
-
データ
-
属性
-
タイムスタンプ
-
アクセス制御リスト (ACL)
-
オーナー情報
-
監査情報
説明10 TB を超える数百億もの小規模ファイルなど、膨大な量のデータを移行する際には、Windows ECS インスタンスに最新バージョンの Python をインストールして移行を高速化できます。詳細については、「SMB ファイルシステムへのデータ移行の高速化」をご参照ください。
-
-
移行を検証します。
移行後、次のコマンドを実行して、ソースと移行先の一貫性を検証してください:
ROBOCOPY Z:\ Y:\ /e /l /ns /njs /njh /ndl /fp /log:reconcile.txt主要なパラメーター:
-
/e: すべてのサブディレクトリ (空のものを含む) をリストします。
-
/l: ファイルを変更またはコピーせずに差分をリストします。
-
/fp: ログにファイルのフルパスを含めます。このパラメーターは、/ndl を省略した場合にのみ必要です。
-
/ns: ログからファイルサイズを除外します。
-
/ndl: ログからフォルダー名を除外します。
-
/njs: ジョブの概要を除外します。
-
/njh: ジョブのヘッダーを除外します。
-
/log:reconcile.txt: 結果を reconcile.txt ログファイルに書き込みます。ファイルが既に存在する場合、上書きされます。
-
ワークロードの新しいファイルシステムへの切り替え
移行後、関連するすべての ECS インスタンスとコンテナーで、元のファイルシステムをアンマウントし、新しいファイルシステムをマウントしてください。
-
NAS ファイルシステムを ECS インスタンスに直接マウントする
-
net useを実行して、現在の NAS マウント情報を記録してください。NAS ファイルシステムがマウントされているローカルのドライブ文字をメモしてください。 -
次のコマンドを実行して、元のファイルシステムをアンマウントしてください。
net use Z: /deleteコマンドの
Z:を実際のドライブ文字に置き換えてください。説明-
net use * /delete コマンドを実行して、Windows でマウントされているすべてのファイルシステムを手動でアンマウントします。
-
net use * /delete /y コマンドを実行し、Windows でマウントされているすべてのファイルシステムを自動的にアンマウントします。
-
-
新しいファイルシステムを元のドライブ文字にマウントしてください。詳細については、「SMB ファイルシステムのマウント」をご参照ください。
-
NAS ファイルシステムにアクセスするプロセスを開始し、読み取りおよび書き込み操作が成功することを確認してください。
-
auto_mount.batファイルの自動マウント情報を変更し、古いマウントターゲットを新しいものに置き換えてください。
-
-
Windows コンテナーに NAS ファイルシステムをマウントする
-
既存の YAML 設定ファイルを変更して、元のマウントターゲットを新しいものに置き換えてください。
-
変更した設定ファイルを使用して新しいポッドを作成してください。新しいファイルシステムが正常にマウントされ、読み取りおよび書き込み操作が正常であることを確認してください。
-
元のファイルシステムを使用するすべてのポッドを置き換えてください。
-
ワークロードを切り替えた後、誤った削除や同期エラーによるデータ損失を防ぐため、元のファイルシステムのデータを少なくとも 1 週間は保持してください。
よくある質問
SMB ファイルシステムへのデータ移行を高速化する方法
ワークロードが同じ SMB ファイルシステムに書き込みを行っている間に、大規模な移行 (例:100 KB 程度の数億の小さなファイルで 10 TB を超える場合) を高速化するには、Windows ECS インスタンスに Python をインストールし、次の移行スクリプトを実行してください。
-
ダウンロードして、最新バージョンの Python をインストールしてください。
-
PATH 環境変数に Python の実行可能パス (例:C:\Python27) を追加してください。
set PATH=%PATH%;C:\python27where pythonコマンドを実行して、Python のインストールパスを確認することもできます。次の図を参照してください。
-
以下の migration.py スクリプトを、ECS インスタンス上の C:\ などのローカルディレクトリにコピーします。
#!/usr/bin/python # -*- coding: UTF-8 -*- import os import random import string import sys, getopt import datetime import time def execute_cmd(cmd): print('\tコマンドを実行中: %s' % cmd) count = 0 rc = 0 while (count < 3*60): rc = os.system(cmd) if (rc != 0): count += 1 time.sleep(1) continue else: break if rc != 0: print('\tコマンドの実行に失敗しました: %s. rc:%d' %(cmd, rc)) return def migrate_subdirs(srcPath, dstPath, rangeBegin, rangeEnd, ignoreFile): currTimeStr = datetime.datetime.now().strftime("%Y-%m-%d_%H:%M:%S") print('%s から %s へのサブディレクトリ範囲 [%s, %s] の移行を開始します (%s)。\n' %(srcPath, dstPath, rangeBegin, rangeEnd, currTimeStr)) index = 0 for entry in os.listdir(srcPath): if os.path.isdir(os.path.join(srcPath, entry)): if index >= rangeBegin and index <= rangeEnd: srcSubDir = srcPath + "\\" + entry dstSubDir = dstPath + "\\" + entry print('\t%d 番目のディレクトリ %s から %s への移行を開始します。' %(index, srcSubDir, dstSubDir)) cmd = "robocopy \"" + srcSubDir + "\" \"" + dstSubDir + "\" /e /w:5 /z /mt:32" if ignoreFile.strip(): cmd += " /XF \"" + ignoreFile + "\"" cmd += " >> robocopy.log" execute_cmd(cmd) print('\t%s から %s への移行が完了しました。\n' %(srcSubDir, dstSubDir)) index += 1 print('%s から %s へのサブディレクトリ範囲 [%s, %s] の移行が完了しました (%s)。\n' %(srcPath, dstPath, rangeBegin, rangeEnd, datetime.datetime.now().strftime("%Y-%m-%d_%H:%M:%S"))) def migrate_regfiles(srcPath, dstPath, ignoreFile): currTimeStr = datetime.datetime.now().strftime("%Y-%m-%d_%H:%M:%S") print('%s から %s への通常ファイルの移行を開始します (%s)。\n' %(srcPath, dstPath, currTimeStr)) for entry in os.listdir(srcPath): if os.path.isfile(os.path.join(srcPath, entry)): print('\t%s の %s から %s への移行を開始します。\n' %(entry, srcPath, dstPath)) cmd = "attrib -R \"" + dstPath + "\\\\" + entry + "\"" execute_cmd(cmd) cmd = "copy \"" + srcPath + "\\\\" + entry + "\" \"" + dstPath + "\" /Y" if ignoreFile.strip(): cmd += " /XF \"" + ignoreFile + "\"" cmd += " >> robocopy.log" execute_cmd(cmd) print('\t%s の %s から %s への移行が完了しました。' %(entry, srcPath, dstPath)) print('%s から %s への通常ファイルの移行が完了しました (%s)。\n' %(srcPath, dstPath, datetime.datetime.now().strftime("%Y-%m-%d_%H:%M:%S"))) def main(argv): srcPath = '' dstPath = '' range = '' ignoreFile = '' try: opts, args = getopt.getopt(argv,"hs:d:r:i:f",["srcPath=","dstPath=","range=","ignore="]) except getopt.GetoptError: print('migration.py -s <ソースパス> -d <移行先パス> [-r 開始インデックス:終了インデックス | -f] [-i 無視するファイル]') print('例: migration.py -s x:\\pic -d z:\\pic [-r 0:100]') sys.exit(2) subdironly = False fileonly = False for opt, arg in opts: if opt == '-h': print('migration.py -s <ソースパス> -d <移行先パス> [-r 開始インデックス:終了インデックス | -f] [-i 無視するファイル]') sys.exit() elif opt in ("-s", "--srcPath"): srcPath = arg elif opt in ("-d", "--dstPath"): dstPath = arg elif opt in ("-r", "--range"): range = arg subdironly = True elif opt in ("-f", "--file"): fileonly = True elif opt in ("-i", "--ignore"): ignoreFile = arg if not srcPath.strip() or not dstPath.strip(): print('migration.py -s <ソースパス> -d <移行先パス> [-r 開始インデックス:終了インデックス | -f] [-i 無視するファイル]') sys.exit() if subdironly and fileonly: print('migration.py -s <ソースパス> -d <移行先パス> [-r 開始インデックス:終了インデックス | -f] [-i 無視するファイル]') sys.exit() if not fileonly: if not range.strip(): rangeBegin = 0 rangeEnd = sys.maxsize-1 else: rangeBegin, rangeEnd = (int(x) for x in range.split(":")) if rangeBegin < 0 or rangeEnd >= sys.maxsize or rangeEnd < rangeBegin: print('migration.py -s <ソースパス> -d <移行先パス> [-r 開始インデックス:終了インデックス | -f] [-i 無視するファイル]') print('例: migration.py -s x:\\pic -d z:\\pic -r 0:99') sys.exit() migrate_subdirs(srcPath, dstPath, rangeBegin, rangeEnd, ignoreFile) if not subdironly: migrate_regfiles(srcPath, dstPath, ignoreFile) if __name__ == "__main__": main(sys.argv[1:]) -
データを移行してください。コマンドは次の形式を使用してください:
python ./migration.py -s <ソースパス> -d <移行先パス> [-r 開始インデックス:終了インデックス | -f] [-i 無視するファイル]次の表に、コマンドの主要なパラメーターを示します。
パラメーター
説明
-s <ソースパス>
ソースディレクトリのパスを指定します。たとえば、
-s Z:\は Z ドライブのルートディレクトリを指定します。-d <移行先パス>
宛先ディレクトリへのパスを指定します。たとえば、
-d Y:\は Y ドライブのルートディレクトリを指定します。-r 開始インデックス:終了インデックス
移行するサブディレクトリの範囲を
BeginIndexからEndIndexまで指定します。たとえば、-r 1:100はサブディレクトリ 1 から 100 までを移行します。-f
ソースディレクトリのトップレベルにある通常のファイルのみを移行します。
ソースファイルシステムディレクトリ内のすべてのファイルを、スコープ制限を無視して移行します。
-i 無視するファイル
移行から除外するソースディレクトリ内のファイルを指定します。たとえば、
-i ignored.txtは、ignored.txtという名前のファイルを除外します。説明デフォルトでは、スクリプトはすべてのサブディレクトリに対して Robocopy を順次実行してから、ルートレベルのファイルをコピーします。移行を高速化するには、複数のクライアントで重複しないサブディレクトリ範囲を指定して、スクリプトを並行して実行します。たとえば、最初のクライアントでは
-r 0:9999を、2 番目のクライアントでは-r 10000:19999を使用する、といった具合です。たとえば、ソース Z:\ から宛先 Y:\ にデータを移行するには、次のコマンドを実行します。
python ./migration.py -s Z:\ -d Y:\