📈

AWS CDK の BucketDeployment が遅くなったらヤルべきこと

2024/05/14に公開

お困りポイント

AWS CDKにはS3にファイルをアップロードしてくれるBucketDeploymentという便利なクラスがあります。ローカルで生成したHTMLやCSSなどの静的なファイルを配信するためにS3 Bucketへアップロードするようなユースケースで、非常に重宝するクラスです。
https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_s3_deployment.BucketDeployment.html

しかし、このクラスによるファイルのアップロードがどうにも遅いと感じることが少なからずあり、そこが非常に不満だったのです。

まずは結論

前段で引用しているドキュメントにちゃんと書いてありました。

「大きなファイルをデプロイするつもりなら、それに応じて数字を増やす必要があるぞ」とハッキリと書いてあります。要するにそーゆーことです。というわけで、以下のような感じでmemoryLimitの値を明示的に指定すれば万事OK、というオチでした。

        new BucketDeployment(webContents, 'Deployment', {
            destinationBucket: webContents,
            destinationKeyPrefix: 'public',
            sources: [Source.asset(`${__dirname}/../../webapp/.output/public`)],
            extract: true,
            prune: true,
            retainOnDelete: false,
            memoryLimit: 256,
            logGroup: new LogGroup(webContents, 'DeploymentLogGroup', {
                retention: RetentionDays.ONE_DAY,
                removalPolicy: RemovalPolicy.DESTROY,
            }),
        });

でもね、「大きなファイル」って書いてありますけども、実はそんなに大きくないファイルでも利用可能なメモリ量の上限を増やす必要がある、ってのが落とし穴です。

設定変更の効果

参考までに、規定値である128MBから値を増やすことでどのぐらいの効果があるのか、全く同じファイルを3回ずつデプロイすることで計測してみました。今回の検証でデプロイしたファイルの内訳は以下になります。

合計サイズ ファイル数 平均サイズ
173.6KB 15 11.6KB

アップロードの性能比較するには随分と規模が小さいように見えますが、この規模なのにアップロードに数十秒もかかるのがイライラの原因だったりするワケなのです。

128MB (規定値)

まずは、何も指定しなかった場合です。実行時間が40秒超えてます。遅すぎです。

Duration: 46007.21 ms Billed Duration: 46008 ms Memory Size: 128 MB Max Memory Used: 124 MB
Duration: 44723.82 ms Billed Duration: 44724 ms Memory Size: 128 MB Max Memory Used: 124 MB
Duration: 44003.59 ms Billed Duration: 44004 ms Memory Size: 128 MB Max Memory Used: 128 MB

利用可能なメモリ量に利用されたメモリ量が張り付いているようです。明らかにメモリ不足の状態に陥っているものと推測できます。しかし、今回の検証は小さなファイルしかアップロードしていないのに、既定値の128MBでメモリが足りていないとは思いもよらなかったです。

256MB

規定値の2倍にしてみました。実行時間が23秒程度と既定値だった時の半分になりました。効果テキメンです。

Duration: 23216.60 ms Billed Duration: 23217 ms	Memory Size: 256 MB Max Memory Used: 143 MB	
Duration: 22583.36 ms Billed Duration: 22584 ms	Memory Size: 256 MB Max Memory Used: 141 MB
Duration: 23539.87 ms Billed Duration: 23540 ms	Memory Size: 256 MB Max Memory Used: 147 MB

メモリ利用量は利用可能なメモリ量の上限を超えてないので、適切な値のように見えますね。

512MB

念のため4倍も試してみました。実行時間はさらに短くなって11秒程度です。まさかの再び効果テキメンという結果です。

Duration: 11659.00 ms Billed Duration: 11659 ms Memory Size: 512 MB Max Memory Used: 145 MB
Duration: 10760.58 ms Billed Duration: 10761 ms Memory Size: 512 MB Max Memory Used: 146 MB
Duration: 10499.78 ms Billed Duration: 10500 ms Memory Size: 512 MB Max Memory Used: 148 MB

BucketDeploymentクラスの処理性能はメモリ量だけではなくCPUパワーにも大きく依存していることが原因だと推測しましたが、真相はわかりません。現時点では「早くなる!」という事実だけわかれば十分なので、深追いはしないことにしました。

最適な設定値は?

ということで、今は以下の理由で512MBを選択しています。

  • 一番早い!
  • 今回のケースだと、128MB, 256MB, 512MB, どれも利用料は同じ。

もちろん、上記は私のケースでしかないので、どの値を選ぶかは各自の責任でお願いしますね。

Discussion