1. 程式人生 > >AWS S3(物件儲存)基本操作

AWS S3(物件儲存)基本操作

平臺:linux
語言:node

1 AWS S3物件儲存

Amazon Simple Storage Service (Amazon S3) 是一種面向 Internet 的儲存服務。您可以通過 Amazon S3 隨時在 Web 上的任何位置儲存和檢索的任意大小的資料。

1.1 基本概念

Amazon S3將資料作為物件儲存在儲存區中。一個物件由一個檔案和可選的描述該檔案的任何元資料組成。

1.1.1 儲存桶(bucket)

我們的資料都是儲存在AWS 的儲存桶中,我們可以把桶理解為磁碟分割槽,不過它是由一個桶名(字串)唯一標識,即你不能建立別人已經建立過的桶。

1.1.2 物件

(1)物件鍵 (或鍵名稱) 在儲存桶中唯一地標識物件。(Key)
(2)物件元資料是一組名稱值對。您可以在上傳物件元資料時對其進行設定。上傳物件後,您將無法修改物件元資料。修改物件元資料的唯一方式是建立物件的副本並設定元資料。物件元資料又分為系統元資料和使用者自定義元資料。
(3) 資料

1.1.3 物件標籤(tag)

使用儲存物件打標籤對儲存進行分類。每個標籤都是一個鍵-值對。
您可以將標籤新增到新物件 (當您上傳新物件時),也可以將標籤新增到現有物件。請注意以下幾點:

  • 您最多可以將 10 個標籤與物件關聯。與物件關聯的標籤必須具有唯一的標籤鍵。
  • 標籤鍵的長度最大可以為 128 個 Unicode 字元,標籤值的長度最大可以為 256 個 Unicode 字元。
  • 鍵和值區分大小寫。

標籤對於物件管理相當好用所以重點說明
利用標籤,您現在獲得了另一個維度。如果您希望 photo1 屬於專案 x 類別,則可以相應地標記該物件。除了資料分類之外,標籤還提供其他好處。例如:

  • 物件標籤支援許可權的精細訪問控制。例如,您可以向一個 IAM 使用者授予僅讀取帶有特定標籤的物件的許可權。
  • 物件標籤支援精細的物件生命週期管理,在其中,除了在生命週期規則中指定鍵名稱字首之外,還可以指定基於標籤的篩選條件。
  • 使用 Amazon S3 分析時,您可以配置篩選條件,以便按物件標籤、鍵名稱字首或字首和標籤的組合對物件進行分組以進行分析。
  • 您還可以自定義 Amazon CloudWatch 指標以按特定標籤篩選條件顯示資訊。以下各節提供了詳細資訊。

1.2 S3儲存型別

Amazon S3 中的每個物件都有與之關聯的儲存類別
這裡寫圖片描述
對於經常訪問的儲存類均為STANDARD,我們預設也是該儲存類

建立物件時,要指定鍵名稱(Key),它在儲存桶中唯一地標識該物件。可以理解為儲存檔案相對於當前桶的路徑。

2 使用

2.1 安裝AWS SDK

新建立一個資料夾,並下載AWS SDK

npm install aws-sdk

2.2 編寫基礎配置檔案

var AWS = require('aws-sdk');
AWS.config.loadFromPath('./config/models/aws_config.json');
//載入訪問密匙 密匙在AWS後臺使用者管理中得到
var s3 = new AWS.S3({signatureVersion: 'v4', region:'ap-northeast-2'});
//初始化SDK S3操作物件
//關於AWS服務區可參見:https://blog.csdn.net/m0_37263637/article/details/79226121
let targetBucket = "xxxxxbucket";
let targetKey =  "test/files/da123cadfeadfe/helloworld.jpg";
letbitmap = fs.readFileSync('./helloworld.jpg');

3 基礎功能

下面的程式碼均基於2.2中程式碼

3.1 桶操作

3.1.1 建立桶

一個賬戶最多可以建立100個儲存桶

var bucketParams = {
    Bucket: "xxxxtestbucket", //待建立的桶名
    CreateBucketConfiguration: {
     LocationConstraint: "ap-northeast-2"//桶所在服務區
    }
   };
s3.createBucket(bucketParams, function(err, data) {
    if (err) console.log(err, err.stack); // an error occurred
    else     console.log(data);           // successful response
});

3.1.2 桶的生命週期

往往實際應用中存在這樣一種需求,我們希望雲物件儲存能自動管理一些檔案,比如定時過期刪除一些檔案,或者將儲存型別轉換成更便宜的型別。
AWS 儲存桶提供了生命週期這個功能。生命週期是針對儲存桶而言的。
一個生命週期配置最多可以有 1000 個規則。 元素唯一地標識規則。ID 長度最多為 255 個字元。

下面程式碼只是針對過期操作

var lifecycleparams = {
    Bucket: targetBucket, //要配置生命週期的桶名
    LifecycleConfiguration: {
     Rules: [//規則組
        {
            Expiration: {
                Days:10//過期時間
            }, 
            Filter: {
                Prefix: "test/files/da123cadfeadfe/",//篩選器 針對該路徑下的物件有效 該介面也提供tag 作為標識, 如果Prefix為空 為所有引數均有效
          /*              
         Tag: {//以標籤精確管理過期時間
                          Key: 'STRING_VALUE', /* required */
                          Value: 'STRING_VALUE' /* required */
                  }*/
            }, 
            ID: "TestOnly", 
            Status: "Enabled", 
        }
     ]
    }
};
s3.putBucketLifecycleConfiguration(lifecycleparams, function(err, data) {
    console.info(data);
    if (err) console.log(err, err.stack); // an error occurred
    else   console.log(data);           // successful response
});

關於Filter引數,支援3種 ,但三種只能存在一種

  • Prefix:路徑字首
  • Tag:物件標籤
  • And: 混合條件,即字首標籤均支援

And的形式為:

And: {
            Prefix: 'STRING_VALUE',
            Tags: [
              {
                Key: 'STRING_VALUE', /* required */
                Value: 'STRING_VALUE' /* required */
              },
              /* more items */
            ]
        },

同樣s3 提供getBucketLifecycleConfiguration檢視桶生命週期配置,deleteBucketLifecycle API刪除桶生命週期配置。

3.1.3 刪除桶

var deleteBucketParams = {
    Bucket: targetBucket
};

s3.deleteBucket(deleteBucketParams, function(err, data) {
    if (err) console.log(err, err.stack); // an error occurred
    else     console.log(data);           // successful response
});

桶不為空 SDK會報錯

3.2 物件操作

3.2.1 上傳物件

let putParams = {
    Bucket: targetBucket, 
    Key: targetKey, 
    Body: bitmap
};
s3.putObject(putParams, function(err, data) {
    if (err){
        console.error("put object error");
    }
    console.info(data);
});

3.2.2 獲取物件

let getParams = {
    Bucket: targetBucket, 
    Key: targetKey
};

s3.getObject(getParams, function(err, data) {
    if (err){
        console.error("put object error");
    }
    console.info(data);
});

以http形式獲取物件內容,返回為:

{ AcceptRanges: 'bytes',
  Expiration: 'expiry-date="Sun, 24 Jun 2018 00:00:00 GMT", rule-id="TestOnly"',
  LastModified: 2018-06-13T06:35:41.000Z,
  ContentLength: 94156,
  ETag: '"ec79ec01697b7a7f9e423108089c7c6f"',
  ContentType: 'application/octet-stream',
  Metadata: {},
  TagCount: 2,
  Body: <Buffer ff d8 ff e1 9b 2c 45 78 69 66 00 00 49 49 2a 00 08 00 00 00 0b 00 0f 01 02 00 06 00 00 00 92 00 00 00 10 01 02 00 1a 00 00 00 98 00 00 00 12 01 03 00 ... > }
}

3.2.3 複製物件

var copyParams = {
    Bucket: "xxx", //複製目標桶
    CopySource: "/xxx/test/files", //待複製資源位置:  /原桶/原桶物件鍵形式組成
    Key: "xxx"//複製目標物件鍵
};

s3.copyObject(copyParams, function(err, data) {
    if (err){
        console.info(err);
        console.error("put object error");
    }
    console.info(data);
});

3.2.4 刪除物件

var deleteparams = {
    Bucket: targetBucket, 
    Key: targetKey
   };
   s3.deleteObject(deleteparams, function(err, data) {
     if (err) console.log(err, err.stack); // an error occurred
     else     console.log(data);           // successful response
});

3.3 標籤

3.3.1 為物件新增標籤

var tagParams = {
    Bucket: targetBucket, 
    Key: targetKey, 
    Tagging: {
     TagSet: [
        {
       Key: "user", 
       Value: "testuser"
      }, 
        {
       Key: "vip", 
       Value: "Value4"
      }
     ]
    }
   };
   s3.putObjectTagging(tagParams, function(err, data) {
     if (err) console.log(err, err.stack); // an error occurred
     else     console.log(data);           // successful response
   });

3.3.2 獲取物件標籤內容

{ 
TagSet:
   [ { Key: 'vip', Value: 'Value4' },
     { Key: 'user', Value: 'testuser' } ]
 }

3.3.3 刪除標籤
 var deletTagparams = {
    Bucket: targetBucket, 
    Key: targetKey, 
   };
   s3.deleteObjectTagging(deletTagparams, function(err, data) {
     if (err) console.log(err, err.stack); // an error occurred
     else     console.log(data);           // successful response
   });

3.4 預簽名分享儲存物件

如果要將物件短時間分享出去我們可以使用預簽名,

let getSignedparams = {Bucket: targetBucket, Key: targetKey, Expires:60*30};//30 min
s3.getSignedUrl('getObject', getSignedparams, function(err, url){
    console.info(url);
});

返回為一個URL ,可以直接用瀏覽器通過訪問這個URL下載儲存物件。
雖然也可以通過這個API獲取到putObject 的URL 但V4版簽名需要在http header新增很多引數校驗,不建議直接使用restful API 的方式操作。

4 使用中遇到的問題:

4.1 關於簽名版本不正確的報錯

The authorization mechanism you have provided is not supported. Please use AWS4-HMAC-SHA256.
因為SDK預設 還使用的是V2版簽名,所以需要手動配置V4簽名
var s3 = new AWS.S3({signatureVersion: ‘v4’, });

4.2 關於使用S3服務區配置錯誤的報錯

Error parsing the X-Amz-Credential parameter; the region ‘us-east-1’ is wrong; expecting ‘ap-northeast-2’
新建的桶在首爾 而不是在美國,所以我們也應該配置地區為首爾。
var s3 = new AWS.S3({signatureVersion: ‘v4’, region:’ap-northeast-2’});