すべてのプロダクト
Search
ドキュメントセンター

File Storage NAS:Robocopy を使用したデータ移行

最終更新日:Jul 30, 2026

Robocopy を使用して、File Storage NAS の SMB ファイルシステム間でデータを移行します。

前提条件

ソースデータは、VPC 内にマウントポイントを持つ SMB ファイルシステムに存在する必要があります。

背景情報

Robocopy は、重複するファイルをコピーせずにディレクトリ構造をミラーリングする、Windows に組み込まれたコマンドラインツールです。日付やタイムスタンプなどのファイルメタデータを保持します。

課金

NAS ファイルシステム間のデータ移行には、以下の料金が発生する場合があります:

  • 中継用の Elastic Compute Service (ECS) インスタンスは、その構成に基づいて課金されます。詳細については、「課金概要」をご参照ください。

  • ストレージコストは両方のファイルシステムに適用されます。コストを削減するために、リソースプランを購入してください。詳細については、「課金概要」をご参照ください。

  • Cloud Enterprise Network (CEN) の料金は、トランジットルーターとリージョン間接続に適用されます。詳細については、「課金」をご参照ください。

事前準備

中継用の ECS インスタンスは、両方のファイルシステムにアクセスできる必要があります。両方のファイルシステムが同じ VPC から到達可能であることを確認してください。

  1. ソースファイルシステムのマウントポイント情報を表示します。

    データを移行する前に、ソースファイルシステムのマウントポイントと VPC 情報を記録してください。詳細については、「マウントポイントの管理」をご参照ください。

    説明

    ご利用のファイルシステムにクラシックネットワークのマウントポイントしかない場合は、VPC 内にマウントポイントを作成する必要があります。詳細については、「マウントポイントの追加」をご参照ください。

  2. 宛先ファイルシステムのマウントポイントを構成します。

    • ファイルシステムが同じリージョンにある場合

      • ソースと宛先のファイルシステムのマウントポイントが同じ VPC 内にある場合は、宛先マウントポイントの詳細を取得し、「操作手順」セクションに進んでデータを移行します。

      • ソースと宛先のファイルシステムのマウントポイントが同じ VPC 内にない場合は、以下のいずれかの方法でマウントポイントを準備します:

    • ファイルシステムが異なるアカウントまたはリージョンにある場合

      ソースと宛先のファイルシステムが異なるアカウントまたはリージョンにある場合は、CEN を使用してそれらの VPC を接続します。詳細については、「CEN を使用してアカウントとリージョンをまたいで NAS ファイルシステムをマウントする」をご参照ください。

操作手順

マウントポイントの準備が完了したら、中継用の ECS インスタンスを作成し、両方の SMB ファイルシステムをマウントして、Robocopy を使用してデータを移行します。

  1. ソースと宛先のファイルシステムをマウントします。

    重要

    移行には専用の一時的な 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
  2. データを移行します。

    次のコマンドを実行して、ソースファイルシステム (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 ファイルシステムへのデータ移行を高速化する方法」をご参照ください。

  3. 移行を検証します。

    移行後、次のコマンドを実行して、ソースと宛先の一貫性を検証します:

    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 ファイルシステムをマウントする

    1. net use を実行して、現在の NAS マウント情報を記録します。NAS ファイルシステムがマウントされているローカルのドライブ文字をメモします。

    2. 次のコマンドを実行して、元のファイルシステムをアンマウントします。

      net use Z: /delete

      コマンドの Z: を実際のドライブ文字に置き換えてください。

      説明
      • net use * /delete コマンドを実行して、Windows でマウントされているすべてのファイルシステムを手動でアンマウントします。

      • net use * /delete /y コマンドを実行して、Windows でマウントされているすべてのファイルシステムを自動的にアンマウントします。

    3. 新しいファイルシステムを元のドライブ文字にマウントします。詳細については、「SMB ファイルシステムのマウント」をご参照ください。

    4. NAS ファイルシステムにアクセスするプロセスを開始し、読み取りおよび書き込み操作が成功することを確認します。

    5. auto_mount.bat ファイルの自動マウント情報を変更し、古いマウントポイントを新しいものに置き換えます。

  • Windows コンテナに NAS ファイルシステムをマウントする

    1. 既存の YAML 設定ファイルを変更して、元のマウントポイントを新しいものに置き換えます。

    2. 変更した設定ファイルを使用して新しい Pod を作成します。新しいファイルシステムが正常にマウントされ、読み取りおよび書き込み操作が正常であることを確認します。

    3. 元のファイルシステムを使用するすべての Pod をリサイクルします。

重要

ワークロードを切り替えた後、偶発的な削除や同期エラーによるデータ損失を防ぐため、元のファイルシステムのデータは少なくとも 1 週間保持してください。

よくある質問

SMB ファイルシステムへのデータ移行を高速化する方法

同じ SMB ファイルシステムにワークロードが書き込みを行っている間に、大規模な移行 (例えば、それぞれ約 100 KB の数億個の小さなファイルで合計 10 TB 以上) を高速化するには、Windows ECS インスタンスに Python をインストールし、以下の移行スクリプトを実行します。

  1. 最新バージョンの Python をダウンロードしてインストールします。

  2. 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
  3. 以下の 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:])
  4. データを移行します。コマンドは次のフォーマットを使用します: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.txtignored.txt という名前のファイルを除外します。

    説明

    デフォルトでは、スクリプトはすべてのサブディレクトリに対して順番に Robocopy を実行し、その後ルートレベルのファイルをコピーします。移行を高速化するには、複数のクライアントで一意のサブディレクトリ範囲を指定してスクリプトを並行して実行します。例えば、最初のクライアントは -r 0:9999 を使用し、2 番目のクライアントは -r 10000:19999 を使用する、といった具合です。

    例えば、ソース Z:\ から宛先 Y:\ にデータを移行するには、次のコマンドを実行します:

    python ./migration.py -s Z:\ -d Y:\

関連ドキュメント