🙌

AWS S3レプリケーション世界大会 in 東京 〜最速リージョンはどこだ?〜

2024/02/27に公開

概要

以下の結果を受けて、レプリケーション元を東京リージョン(ap-northeast-1)のS3バケットとした場合、より短い時間でレプリケートできるのはどのリージョンのS3バケットか検証してみました。

https://zenn.dev/tatsuto/articles/s3-replication-time

検証環境

  • レプリケーション元のS3バケット

    • 東京リージョン(ap-northeast-1)
    • 削除マーカーのレプリケーションは Enabled です
  • レプリケーション先のS3バケット

    構築先のリージョンとバケット料金等は以下の通りです

    リージョン 地理的距離
    (km)
    ストレージ料金
    最初の50TB/月
    (USD/GB)
    PUT, COPY, POST, LIST
    (USD/1000リクエスト)
    GET, SELECT, 他全て
    (USD/1000リクエスト)
    東京リージョンS3からのデータ転送
    (USD/GB)
    備考
    アジアパシフィック(大阪)
    ap-northeast-3
    400 0.025 0.0047 0.00037 0.09 開催国枠、優勝本命
    アジアパシフィック(ソウル)
    ap-northeast-2
    1160 0.025 0.0045 0.00035 0.09 アジア代表
    アジアパシフィック(シドニー)
    ap-southeast-2
    7810 0.025 0.0055 0.00044 0.09 オセアニア代表
    欧州(フランクフルト)
    eu-central-1
    9360 0.0245 0.0054 0.00043 0.09 欧州代表
    米国東部(バージニア北部)
    us-east-1
    10000 0.023 0.005 0.0004 0.09 北中米カリブ海代表、AWSの総本山
    アフリカ(ケープタウン)
    af-south-1
    14740 0.0274 0.006 0.0004 0.09 アフリカ代表
    南米(サンパウロ)
    sa-east-1
    18540 0.0405 0.007 0.00056 0.09 南米代表

    *料金はS3 標準のもの

  • レプリケーションのログ取得と確認

    • CloudTrail, S3バケット, Athena を使用し、いずれも us-east-1(バージニア北部) に構築
  • 各リソースの詳細な設定値は以下のCloudFormationテンプレートの通りです

    レプリケーション元(一部抜粋)
    {
      "Resources": {
        "S3ReplicationBucket": {
          "Type": "AWS::S3::Bucket",
          "Properties": {
            "BucketName": "trials3replicationsrcstaceplicationbucket",
            "ReplicationConfiguration": {
              "Role": {
                "Fn::GetAtt": [
                  "S3ReplicationRole",
                  "Arn"
                ]
              },
              "Rules": [
                {
                  "DeleteMarkerReplication": {
                    "Status": "Enabled"
                  },
                  "Destination": {
                    "Bucket": "arn:aws:s3:::trials3replicationdest1stdest1stackbucket"
                  },
                  "Filter": {},
                  "Id": "Rule1",
                  "Priority": 0,
                  "Status": "Enabled"
                },
                {
                  "DeleteMarkerReplication": {
                    "Status": "Enabled"
                  },
                  "Destination": {
                    "Bucket": "arn:aws:s3:::trials3replicationdest2stdest2stackbucket"
                  },
                  "Filter": {},
                  "Id": "Rule2",
                  "Priority": 1,
                  "Status": "Enabled"
                },
                {
                  "DeleteMarkerReplication": {
                    "Status": "Enabled"
                  },
                  "Destination": {
                    "Bucket": "arn:aws:s3:::trials3replicationdest3stdest3stackbucket"
                  },
                  "Filter": {},
                  "Id": "Rule3",
                  "Priority": 2,
                  "Status": "Enabled"
                },
                {
                  "DeleteMarkerReplication": {
                    "Status": "Enabled"
                  },
                  "Destination": {
                    "Bucket": "arn:aws:s3:::trials3replicationdest4stdest4stackbucket"
                  },
                  "Filter": {},
                  "Id": "Rule4",
                  "Priority": 3,
                  "Status": "Enabled"
                },
                {
                  "DeleteMarkerReplication": {
                    "Status": "Enabled"
                  },
                  "Destination": {
                    "Bucket": "arn:aws:s3:::trials3replicationdest5stdest5stackbucket"
                  },
                  "Filter": {},
                  "Id": "Rule5",
                  "Priority": 4,
                  "Status": "Enabled"
                },
                {
                  "DeleteMarkerReplication": {
                    "Status": "Enabled"
                  },
                  "Destination": {
                    "Bucket": "arn:aws:s3:::trials3replicationdest6stdest6stackbucket"
                  },
                  "Filter": {},
                  "Id": "Rule6",
                  "Priority": 5,
                  "Status": "Enabled"
                },
                {
                  "DeleteMarkerReplication": {
                    "Status": "Enabled"
                  },
                  "Destination": {
                    "Bucket": "arn:aws:s3:::trials3replicationdest7stdest7stackbucket"
                  },
                  "Filter": {},
                  "Id": "Rule7",
                  "Priority": 6,
                  "Status": "Enabled"
                }
              ]
            },
            "Tags": [
              {
                "Key": "aws-cdk:auto-delete-objects",
                "Value": "true"
              }
            ],
            "VersioningConfiguration": {
              "Status": "Enabled"
            }
          },
          "UpdateReplacePolicy": "Delete",
          "DeletionPolicy": "Delete",
          "Metadata": {
            "aws:cdk:path": "TrialS3ReplicationSrcStack/S3Replication/Bucket/Resource"
          }
        },
        "S3ReplicationRole": {
          "Type": "AWS::IAM::Role",
          "Properties": {
            "AssumeRolePolicyDocument": {
              "Statement": [
                {
                  "Action": "sts:AssumeRole",
                  "Effect": "Allow",
                  "Principal": {
                    "Service": "s3.amazonaws.com"
                  }
                }
              ],
              "Version": "2012-10-17"
            }
          },
          "Metadata": {
            "aws:cdk:path": "TrialS3ReplicationSrcStack/S3Replication/Role/Resource"
          }
        },
        "S3ReplicationRoleDefaultPolicy": {
          "Type": "AWS::IAM::Policy",
          "Properties": {
            "PolicyDocument": {
              "Statement": [
                {
                  "Action": [
                    "s3:GetReplicationConfiguration",
                    "s3:ListBucket"
                  ],
                  "Effect": "Allow",
                  "Resource": {
                    "Fn::GetAtt": [
                      "S3ReplicationBucket",
                      "Arn"
                    ]
                  }
                },
                {
                "Action": [
                  "s3:GetObjectVersionAcl",
                  "s3:GetObjectVersionForReplication",
                  "s3:GetObjectVersionTagging"
                ],
                "Effect": "Allow",
                "Resource": {
                  "Fn::Join": [
                    "",
                    [
                      {
                        "Fn::GetAtt": [
                          "S3ReplicationBucket",
                          "Arn"
                        ]
                      },
                      "/*"
                    ]
                  ]
                }
                },
                {
                  "Action": [
                    "s3:ReplicateDelete",
                    "s3:ReplicateObject",
                    "s3:ReplicateTags"
                  ],
                  "Effect": "Allow",
                  "Resource": [
                    "arn:aws:s3:::trials3replicationdest1stdest1stackbucket/*",
                    "arn:aws:s3:::trials3replicationdest2stdest2stackbucket/*",
                    "arn:aws:s3:::trials3replicationdest3stdest3stackbucket/*",
                    "arn:aws:s3:::trials3replicationdest4stdest4stackbucket/*",
                    "arn:aws:s3:::trials3replicationdest5stdest5stackbucket/*",
                    "arn:aws:s3:::trials3replicationdest6stdest6stackbucket/*",
                    "arn:aws:s3:::trials3replicationdest7stdest7stackbucket/*"
                  ]
                }
              ],
              "Version": "2012-10-17"
            },
            "PolicyName": "S3ReplicationRoleDefaultPolicy",
            "Roles": [
              {
                "Ref": "S3ReplicationRole"
              }
            ]
          },
          "Metadata": {
            "aws:cdk:path": "TrialS3ReplicationSrcStack/S3Replication/Role/DefaultPolicy/Resource"
          }
        }
      }
    }
    
    レプリケーション先(一部抜粋)
    {
      "Resources": {
        "Bucket": {
          "Type": "AWS::S3::Bucket",
          "Properties": {
            "BucketName": "trials3replicationdest1stdest1stackbucket",
            "Tags": [
              {
                "Key": "aws-cdk:auto-delete-objects",
                "Value": "true"
              }
            ],
            "VersioningConfiguration": {
              "Status": "Enabled"
            }
          },
          "UpdateReplacePolicy": "Delete",
          "DeletionPolicy": "Delete",
          "Metadata": {
            "aws:cdk:path": "TrialS3ReplicationDest1Stack/Bucket/Resource"
          }
        }
      }
    }
    

方法

  1. 1KBのテキストファイルをレプリケーション元のバケットに PutObject する
  2. レプリケーション先の全バケットにファイルがレプリケーションされたらレプリケーション元のファイルを DeleteObject する
  3. レプケーション先の全バケットからファイルが削除されたら再度 1 から同じ手順を10回繰り返す
  4. 5MBのバイナリファイルをレプリケーション元のバケットに PutObject する
  5. レプリケーション先の全バケットにファイルがレプリケーションされたらレプリケーション元のファイルを DeleteObject する
  6. レプケーション先の全バケットからファイルが削除されたら再度 4 から同じ手順を10回繰り返す

結果

  • PutObject

    • レプリケーション開始まで大方20秒かかるところを、大阪、ソウル、バージニア北部では60秒以上かかることがあった。
    • ファイルサイズが5MBの時、大方1,2秒でレプケート先にPutObjectするところをフランクフルト、ケープタウン、サンパウロでは3,4秒かかっていた。

    1KBの時

    Region 1 2 3 4 5 6 7 8 9 10 AVE MIN MAX
    Osaka(秒) ~GetObjectAcl 22 21 22 26 23 22 22 217 23 22 42 21 217
    ~GetObject 0 0 0 0 0 0 0 0 0 0 0 0 0
    ~PutObject 0 0 1 0 0 0 0 0 0 0 0 0 1
    合計 22 21 23 26 23 22 22 217 23 22 42 21 217
    Seoul(秒) ~GetObjectAcl 22 22 22 42 23 22 40 23 43 71 33 22 71
    ~GetObject 0 0 0 0 0 0 0 0 0 0 0 0 0
    ~PutObject 0 0 0 0 0 0 0 0 1 0 0 0 1
    合計 22 22 22 42 23 22 40 23 44 71 33 22 71
    Sydney(秒) ~GetObjectAcl 22 24 23 23 23 22 22 23 23 23 23 22 24
    ~GetObject 0 0 0 0 0 0 0 0 0 0 0 0 0
    ~PutObject 0 0 0 0 0 0 0 0 0 0 0 0 0
    合計 22 24 23 23 23 22 22 23 23 23 23 22 24
    Frankfurt(秒) ~GetObjectAcl 22 21 22 22 23 22 34 28 26 23 24 21 34
    ~GetObject 0 1 0 0 0 0 0 0 0 0 0 0 1
    ~PutObject 1 1 0 1 1 0 0 1 1 1 1 0 1
    合計 23 23 22 23 24 22 34 29 27 24 25 22 34
    N.Virginia(秒) ~GetObjectAcl 22 21 22 22 23 33 128 22 22 88 40 21 128
    ~GetObject 0 0 0 0 0 0 0 0 0 0 0 0 0
    ~PutObject 0 0 0 0 0 0 1 0 1 0 0 0 1
    合計 22 21 22 22 23 33 129 22 23 88 41 21 129
    CapeTown(秒) ~GetObjectAcl 23 24 24 23 25 25 26 24 23 25 24 23 26
    ~GetObject 0 0 0 0 0 0 0 0 0 0 0 0 0
    ~PutObject 2 1 1 2 1 1 2 2 2 1 2 1 2
    合計 25 25 25 25 26 26 28 26 25 26 26 25 28
    SaoPaulo(秒) ~GetObjectAcl 26 25 25 25 26 22 22 23 27 23 24 22 27
    ~GetObject 0 0 0 0 0 0 0 0 0 0 0 0 0
    ~PutObject 1 2 2 1 1 1 1 1 1 2 1 1 2
    合計 27 27 27 26 27 23 23 24 28 25 26 23 28

    5MBの時

    リージョン 1 2 3 4 5 6 7 8 9 10 AVE MIN MAX
    Osaka(秒) ~GetObjectAcl 22 29 31 27 22 22 22 27 23 22 25 22 31
    ~GetObject 0 0 0 1 0 0 0 0 0 0 0 0 1
    ~PutObject 0 0 0 1 0 1 0 0 1 0 0 0 1
    合計 22 29 31 29 22 23 22 27 24 22 25 22 31
    Seoul(秒) ~GetObjectAcl 23 63 251 22 24 22 22 23 43 24 52 22 251
    ~GetObject 0 0 0 0 0 0 0 0 0 1 0 0 1
    ~PutObject 0 1 0 0 0 0 1 0 4 0 1 0 4
    合計 23 64 251 22 24 22 23 23 47 25 52 22 251
    Sydney(秒) ~GetObjectAcl 22 23 22 21 22 23 23 22 22 23 22 21 23
    ~GetObject 0 0 0 0 0 0 0 0 0 0 0 0 0
    ~PutObject 1 2 1 2 1 1 1 1 1 1 1 1 2
    合計 23 25 23 23 23 24 24 23 23 24 24 23 25
    Frankfurt(秒) ~GetObjectAcl 24 37 22 22 38 22 22 22 27 22 26 22 38
    ~GetObject 0 0 0 0 1 0 0 0 1 0 0 0 1
    ~PutObject 3 3 3 3 2 2 2 3 2 2 3 2 3
    合計 27 40 25 25 41 24 24 25 30 24 29 24 41
    N.Virginia(秒) ~GetObjectAcl 22 23 22 25 22 22 22 21 22 22 22 21 25
    ~GetObject 0 0 0 0 0 0 0 1 1 0 0 0 1
    ~PutObject 1 1 1 1 2 1 2 1 1 2 1 1 2
    合計 23 24 23 26 24 23 24 23 24 24 24 23 26
    CapeTown(秒) ~GetObjectAcl 25 27 25 22 23 25 24 25 25 25 25 22 27
    ~GetObject 0 0 0 0 0 0 0 0 0 0 0 0 0
    ~PutObject 3 3 4 3 4 4 4 4 4 4 4 3 4
    合計 28 30 29 25 27 29 28 29 29 29 28 25 30
    SaoPaulo(秒) ~GetObjectAcl 25 23 24 23 23 25 23 26 26 25 24 23 26
    ~GetObject 0 0 0 0 0 0 1 0 0 0 0 0 1
    ~PutObject 4 3 4 3 4 3 3 3 3 3 3 3 4
    合計 29 26 28 26 27 28 27 29 29 28 28 26 29
  • DeleteObject

    • レプリケーション開始まで大方20秒かかるところを、大阪、ソウル、バージニア北部では60秒以上かかることがあった。
    • どのリージョンもレプリケーション先でDeleteObjectするのは0〜1秒で収まっているが、ケープタウン、サンパウロでは必ず1秒かかっていた。

    1KBの時

    リージョン 1 2 3 4 5 6 7 8 9 10 AVE MIN MAX
    Osaka(秒) HeadObject 22 22 23 22 29 22 22 107 22 30 32 22 107
    DeleteObject 0 0 0 0 1 0 0 0 0 0 0 0 1
    合計 22 22 23 22 30 22 22 107 22 30 32 22 107
    Seoul(秒) HeadObject 23 41 22 24 22 23 22 23 22 113 34 22 113
    DeleteObject 0 1 0 1 0 0 0 0 0 0 0 0 1
    合計 23 42 22 25 22 23 22 23 22 113 34 22 113
    Sydney(秒) HeadObject 22 22 22 22 23 22 23 22 23 22 22 22 23
    DeleteObject 0 0 0 0 1 0 0 0 0 1 0 0 1
    合計 22 22 22 22 24 22 23 22 23 23 23 22 24
    Frankfurt(秒) HeadObject 22 22 22 31 22 22 22 22 23 22 23 22 31
    DeleteObject 0 0 0 0 0 0 0 0 1 0 0 0 1
    合計 22 22 22 31 22 22 22 22 24 22 23 22 31
    N.Virginia(秒) HeadObject 22 21 22 22 22 35 108 22 22 30 33 21 108
    DeleteObject 0 0 0 0 0 0 0 0 0 0 0 0 0
    合計 22 21 22 22 22 35 108 22 22 30 33 21 108
    CapeTown(秒) HeadObject 26 23 27 25 25 28 25 26 24 25 25 23 28
    DeleteObject 1 1 1 1 1 1 1 1 1 1 1 1 1
    合計 27 24 28 26 26 29 26 27 25 26 26 24 29
    SaoPaulo(秒) HeadObject 23 24 23 26 27 28 24 24 28 23 25 23 28
    DeleteObject 1 1 1 1 1 1 1 1 1 1 1 1 1
    合計 24 25 24 27 28 29 25 25 29 24 26 24 29

    5MBの時

    リージョン 1 2 3 4 5 6 7 8 9 10 AVE MIN MAX
    Osaka(秒) HeadObject 21 30 28 23 23 22 22 23 21 22 24 21 30
    DeleteObject 0 0 0 0 0 0 0 0 0 1 0 0 1
    合計 21 30 28 23 23 22 22 23 21 23 24 21 30
    Seoul(秒) HeadObject 27 22 78 30 23 22 22 23 39 22 31 22 78
    DeleteObject 0 0 0 0 0 0 0 0 0 0 0 0 0
    合計 27 22 78 30 23 22 22 23 39 22 31 22 78
    Sydney(秒) HeadObject 22 22 21 23 23 21 22 23 22 22 22 21 23
    DeleteObject 0 0 0 0 0 0 0 0 0 0 0 0 0
    合計 22 22 21 23 23 21 22 23 22 22 22 21 23
    Frankfurt(秒) HeadObject 23 21 23 23 23 21 23 31 22 29 24 21 31
    DeleteObject 1 0 1 0 0 0 1 0 1 0 0 0 1
    合計 24 21 24 23 23 21 24 31 23 29 24 21 31
    N.Virginia(秒) HeadObject 22 21 89 23 23 21 22 23 22 56 32 21 89
    DeleteObject 0 0 1 0 0 0 0 0 0 1 0 0 1
    合計 22 21 90 23 23 21 22 23 22 57 32 21 90
    CapeTown(秒) HeadObject 25 25 26 25 28 22 25 28 26 23 25 22 28
    DeleteObject 1 1 1 1 1 1 1 1 1 1 1 1 1
    合計 26 26 27 26 29 23 26 29 27 24 26 23 29
    SaoPaulo(秒) HeadObject 26 25 24 25 28 22 26 24 24 27 25 22 28
    DeleteObject 1 1 1 1 1 1 1 1 1 1 1 1 1
    合計 27 26 25 26 29 23 27 25 25 28 26 23 29

所感

  • ファイルサイズが数MB程度の場合、レプケーション時間の大半は開始されるまでの時間にあるように伺えます。
  • 直ぐにレプリケーション開始とならない点については、レプリケーションジョブがキューイング状態であるか、単にジョブスケジュールのタイミングを外しただけかあたりが想定されますが、キューイング状態であれば、時間が不安定だった大阪、ソウル、バージニア北部は混みやすいリージョンなのかもしれません(比較的S3料金が安いからかレプリケーション先に選ばれやすい?)。
  • どのリージョンであれレプリケーションされるまで20秒を切ることはなさそうです。
  • 5MBのPutObjectレプケーションで遠方のリージョンだとレプリケート先にPutObjectするのに数秒かかっていたことを鑑みるに、大容量ファイルになると遠方リージョンのレプリケート時間は顕著に増加すると思われます。(ただバージニア北部のネットワーク速度が悪くないのは意外!?)

Discussion