Robocopy を使用して、File Storage NAS の SMB ファイルシステム間でデータを移行します。
前提条件
ソースデータは、VPC 内にマウントポイントを持つ SMB ファイルシステムに存在する必要があります。
背景情報
Robocopy は、重複するファイルをコピーせずにディレクトリ構造をミラーリングする、Windows に組み込まれたコマンドラインツールです。日付やタイムスタンプなどのファイルメタデータを保持します。
課金
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 | 専用ブロックストレージクラスター (オプション) セクションで、[ファイルシステムの追加] をクリックし、設定を構成します。
説明-
ソースと宛先のマウントポイントが同じ 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 プログラムをインストールして移行を実行できます。詳細については、「Apsara File Storage NAS の 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 インスタンスとコンテナで元のファイルシステムをアンマウントし、新しいファイルシステムをマウントします。
-
ECS インスタンスに直接 NAS ファイルシステムをマウントする
-
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 設定ファイルを変更して、元のマウントポイントを新しいものに置き換えます。
-
変更した設定ファイルを使用して新しい Pod を作成します。新しいファイルシステムが正常にマウントされ、読み取りおよび書き込み操作が正常であることを確認します。
-
元のファイルシステムを使用するすべての Pod をリサイクルします。
-
ワークロードを切り替えた後、偶発的な削除や同期エラーによるデータ損失を防ぐため、元のファイルシステムのデータは少なくとも 1 週間保持してください。
よくある質問
SMB ファイルシステムへのデータ移行を高速化する方法
同じ SMB ファイルシステムにワークロードが書き込みを行っている間に、大規模な移行 (例えば、それぞれ約 100 KB の数億個の小さなファイルで合計 10 TB 以上) を高速化するには、Windows ECS インスタンスに Python をインストールし、以下の移行スクリプトを実行します。
-
最新バージョンの Python をダウンロードしてインストールします。
-
Python の実行可能ファイルのパスを PATH 環境変数に追加します (例:C:\Python27)。
set PATH=%PATH%;C:\python27また、
where pythonコマンドを実行して、以下のように Python のインストールパスを確認することもできます。C:\Users\Administrator\Desktop>set PATH=%PATH%;C:\python27 C:\Users\Administrator\Desktop>where python C:\Python27\python.exe C:\Users\Administrator\Desktop>path PATH=C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\python27 -
以下の migration.py スクリプトを、ECS インスタンスのローカルディレクトリ (例:C:\) にコピーします。
#!/usr/bin/python import os import random import string import sys, getopt import datetime import time def execute_cmd(cmd): print('\tExecuting cmd: %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('\tFailed to execute cmd: %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('Start to migrate from %s to %s for subdir range[%s, %s] at %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('\tBegin of migrating from the %d th dir %s to %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('\tEnd of migrating from %s to %s.\n' %(srcSubDir, dstSubDir)) index += 1 print('Finish to migrate from %s to %s for subdir range[%s, %s] at %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('Start to migrate from %s to %s for regular files at %s.\n' %(srcPath, dstPath, currTimeStr)) for entry in os.listdir(srcPath): if os.path.isfile(os.path.join(srcPath, entry)): print('\tBegin of migrating %s from %s to %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('\tEnd of migrating %s from %s to %s' %(entry, srcPath, dstPath)) print('Finish to migrate from %s to %s for regular files at %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 <source path> -d <destination path> [-r BeginIndex:EndIndex | -f] [-i ignoredFile]') print('example: 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 <source path> -d <destination path> [-r BeginIndex:EndIndex | -f] [-i ignoredFile]') 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 <source path> -d <destination path> [-r BeginIndex:EndIndex | -f] [-i ignoredFile]') sys.exit() if subdironly and fileonly: print('migration.py -s <source path> -d <destination path> [-r BeginIndex:EndIndex | -f] [-i ignoredFile]') 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 <source path> -d <destination path> [-r BeginIndex:EndIndex | -f] [-i ignoredFile]') print('example: 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 <source path> -d <destination path> [-r BeginIndex:EndIndex | -f] [-i ignoredFile]。次の表に、コマンドの主要なパラメーターを示します。
パラメーター
説明
-s <source path>
ソースディレクトリのパスを指定します。例えば、
-s Z:\は Z ドライブのルートディレクトリを指定します。-d <destination path>
宛先ディレクトリのパスを指定します。例えば、
-d Y:\は Y ドライブのルートディレクトリを指定します。-r BeginIndex:EndIndex
移行するサブディレクトリの範囲を
BeginIndexからEndIndexまで指定します。例えば、-r 1:100は 1 番目から 100 番目までのサブディレクトリを移行します。-f
ソースディレクトリのトップレベルにある通常のファイルのみを移行します。
範囲の制限を無視して、ソースファイルシステムディレクトリ内のすべてのファイルを移行します。
-i ignoredFile
移行から除外するソースディレクトリ内のファイルを指定します。例えば、
-i ignored.txtはignored.txtという名前のファイルを除外します。説明デフォルトでは、スクリプトはすべてのサブディレクトリに対して順番に Robocopy を実行し、その後ルートレベルのファイルをコピーします。移行を高速化するには、複数のクライアントで一意のサブディレクトリ範囲を指定してスクリプトを並行して実行します。例えば、最初のクライアントは
-r 0:9999を使用し、2 番目のクライアントは-r 10000:19999を使用する、といった具合です。例えば、ソース Z:\ から宛先 Y:\ にデータを移行するには、次のコマンドを実行します:
python ./migration.py -s Z:\ -d Y:\