使用AWS DataSync SDK將S3檔案複製到EFS

2022/01/28

AWS DataSync

可以在AWS上多個服務間移轉檔案

本篇紀錄如何從S3搬移檔案至EFF上

 

名詞

以下為AWS DataSync的一些專用名詞

 

Location

可分為來源(Source)及目標(Destination)

Location Type可選擇AWS服務類型(例如: S3或EFS)

並且要設定該服務要同步的位置(Folder/Path)

 

另外還要額外設定一個IAM role

這個IAM role要有可存取該S3 Bucket的完整權限

或是直接用autogerenate按鈕自動產生IAM ROLE也行

datasync-location.png

 

Task

同步任務設定

主要為設定兩個Location(Source及Destination)

 

Task execution configuration

Verify data建議使用Verify only the data transferred

也就是僅驗證要傳輸的那個檔案

若用其他選項若Source或Destination檔案過多

將會造成驗證時間過長(長到甚至數小時都有可能)

task-execution.png

 

Data transfer configuration

要注意進階設定的Copy permissions選項

若複製到EFS的Location是重複使用且權限不同於S3 Location的權限(例如S3檔案為private, EFS目錄權限為777)

將會造成每次同步之後Destination目錄一直被重複修改

 

Logging

若不使用CloudWatch可直接設定為"Do not send logs to CloudWatch"

logging.png

 

TaskExecution

由Task啟動的執行項目(官方文件中文稱為任務執行)

 

TaskExecution狀態

TaskExecution有許多狀態

可參考此官方文件

https://docs.aws.amazon.com/zh_tw/datasync/latest/userguide/understand-task-execution-statuses.html

 

PHP SDK使用範例

AWS PHP SDK

 

授權

<?php

use \Aws\DataSync\DataSyncClient;
protected $client;
public function __construct()
{
    $this->client = new DataSyncClient([
        'version'     => '2018-11-09',
        'region'      => 'your-region',
        'credentials' => [
            'key'    => 'iam-key',
            'secret' => 'iam-secret',
        ]
    ]);
}

 

建立S3 Location

我的使用情境是每次都從新S3指定目錄內上傳一個檔案

再發起DataSync同步到EFS某個目錄(每次都是同個EFS目錄)

因次Source Location等於是動態用PHP SDK建立

 

參考官方文件(CreateLocationS3)

<?php

public function createS3Location()
{

    $result = $this->client->createLocationS3([
        'S3BucketArn' => 'S3 Bucket ARN',
        'S3Config' => [
            'BucketAccessRoleArn' => '設定前面提到的IAM ROLE ARN',
        ],
        'Subdirectory' => '/path/to/source',
    ]);
    return $result->toArray();
}

 

建立Task

參考官方文件(createTask)

特別是的VerifyModePosixPermissions的使用

<?php

public function createTask($sourceArn)
{
    $task = $this->client->createTask([
        'SourceLocationArn' => $sourceArn, // 前面建立的S3 Location ARN
        'DestinationLocationArn' => 'DestinationLocationArn', // Destination Location ARN(EFS)
        'Options' => [
            'VerifyMode' => 'ONLY_FILES_TRANSFERRED', // 只驗證要傳輸(異動)的檔案
            'PosixPermissions' => 'NONE', // 不複製目錄權限
        ],
    ]);
    $taskArn = $task->toArray();
    return $taskArn;
}

 

啟動Task

參考官方文件(StartTaskExecution)

使用前面建立的Task ARN即可啟動Task

<?php

public function startTask($taskArn)
{
    $result = $this->client->startTaskExecution([
        'TaskArn' => $taskArn,
    ]);
    return $result->toArray();
}

 

取得任務執行資訊

參考官方文件(describeTaskExecution)

透過前面建立TaskExecution的ARN即可取得執行任務的資訊

例如狀態等資訊可能會需要顯示在UI上

<?php

public function getTaskExecution($taskExecutionArn)
{
    $result = $this->client->describeTaskExecution([
        'TaskExecutionArn' => $taskExecutionArn
    ]);

    return $result->toArray();
}

 

 

規劃注意事項

 

避免重複搬檔案造成資源浪費

由於DataSync的Source Location是複製整個目錄

因此如果專案的複製工作是可能會有多個Task同時進行

而不是排程一段時間進行一次的話

最好是在S3上將每個要複製的檔案放在自己獨立的目錄

並且動態發API為每個要複製的檔案目錄建立S3 Location

這樣才不會遇到搬到已經複製好的檔案的問題

檔案複製完成後

再發API砍掉清除完成的Location即可