使用AWS DataSync SDK將S3檔案複製到EFS
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也行
Task
同步任務設定
主要為設定兩個Location(Source及Destination)
Task execution configuration
Verify data建議使用Verify only the data transferred
也就是僅驗證要傳輸的那個檔案
若用其他選項若Source或Destination檔案過多
將會造成驗證時間過長(長到甚至數小時都有可能)
Data transfer configuration
要注意進階設定的Copy permissions選項
若複製到EFS的Location是重複使用且權限不同於S3 Location的權限(例如S3檔案為private, EFS目錄權限為777)
將會造成每次同步之後Destination目錄一直被重複修改
Logging
若不使用CloudWatch可直接設定為"Do not send logs to CloudWatch"
TaskExecution
由Task啟動的執行項目(官方文件中文稱為任務執行)
TaskExecution狀態
TaskExecution有許多狀態
可參考此官方文件
https://docs.aws.amazon.com/zh_tw/datasync/latest/userguide/understand-task-execution-statuses.html
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建立
<?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
特別是的VerifyMode及PosixPermissions的使用
<?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
使用前面建立的Task ARN即可啟動Task
<?php
public function startTask($taskArn)
{
$result = $this->client->startTaskExecution([
'TaskArn' => $taskArn,
]);
return $result->toArray();
}
取得任務執行資訊
透過前面建立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即可