こんにちは
某SIerでソリューションアーキテクトをしております、たくまです。
Lambdaなどの処理で実行するパラメータ等の情報はどこに格納していますか?
SSMパラメータストア?S3?DynamoDB?
色々なサービスがあると思いますが、それぞれの性能観点。主にレイテンシーを考えた時に各サービスに違いはあるのか?という事が気になり検証してみました。
比較したサービスは、以下サービスです。
- AWS Systems Manager Parameter Store (以降SSMパラメータストア)
- AWS Systems Manager Parameter Store KMSを有効にした場合
- AWS Secrets Manager
- Amazon S3(以降S3)
- DynamoDB
それぞれのサービスでの性能に関わるマニュアルは以下辺りです。
AWS Systems Manager Parameter Store
特に上限についての記載は見当たりませんでしたが、スループットの引き上げが可能な様です。
Parameter Store のスループットを引き上げる
AWS Secrets Manager
5,000/秒の読み込みが上限の様です。
AWS Secrets Manager quotas
S3
5,500/Sが GETリクエストの上限の様です。
Best practices design patterns: optimizing Amazon S3 performance
DynamoDB
40,000 read request unitsが上限の様です。
Amazon DynamoDB のサービス、アカウント、およびテーブルのクォータ
AWS Key Management Service
KMS辺りの許可50,000/秒が上限のようです。
AWS Key Management Serviceリソースクォータ
検証結果1
それぞれ、「Value=AWS」というパラメータを登録し、Lambdaから実行させました。
Lambda側の性能もある為、メモリの割り当ては128MBと1769MBで比較しました。(3回実行し平均をとっています)
※Lambdaのメモリを1769Mにしてる理由は、こちらの記事Lambdaが6vCPUまで拡張されたので性能検証してみました
を参照してください。
AWSサービス | Lambda 128M | Lambda 1769M | 備考 |
---|---|---|---|
SSM パラメータストア | 41.08ms | 25.24ms | |
SSM パラメータストアKMS有 | 53.67ms | 44.38ms | KMS利用で1割ぐらいお遅くなる |
SecretsManager | 41.59ms | 31.10ms | |
S3 | 161.93ms | 29.53ms | 遅かったが、Lambdaメモリを上げると普通ぐらいに |
DynamoDB | 40.01ms | 4.07ms | Lamndaメメモリを上げると爆速 |
Lambdaのメモリの割り当てが少ないとS3は異様に遅かったですが、それ以外のサービスはそれほど大きな差はありませんでした。
KMSを使うと2割程度遅くなるようです。
Lambdaのメモリ割り当てを増やすと早くなりましたがサービスによって改善具合に差がありました。
DynamoDBやS3はLambdaの割り当を増やすとレイテンシーも大きく改善しました。
検証結果2
性能に関わるパラメータを変更させて比較しました。(Lambdaのメモリは、1769MBとしています。)
AWSサービス | Lambda 1769M | 設定変更時 | 設定変更の内容 |
---|---|---|---|
SSM パラメータストア | 25.24ms | 27.89ms | スループットの引き上げ設定 |
SSM パラメータストアKMS有 | 44.38ms | 43.91 | スループットの引き上げ設定 |
S3 | 29.53ms | 57.97ms | KMS利用しバケットキー無効 |
S3 | 29.53ms | 41.26 | KMSを利用しバケットキー有効化 |
DynamoDB | 4.07ms | 5.44 | RCを1→100に変更 |
性能の上限をあげたとしても、レイテンシーにはあまり違いはなさそうでした。
こちらの結果からもKMSを利用するとレイテンシーが上がるようです。その為、S3は理由が無い限りはバケットキーも有効にして運用する方がよさそうです。
※S3のバケットキーについてはAmazonS3バケットキーを使用したSSE-KMSのコストの削減を参照ください。
最後に
Lambdaに適切なメモリを割り当てて上げた場合は、DynamoDB以外はどのサービスもレイテンシーに大きく違いはなく、レイテンシーという観点では使いやすいサービスを選択すればよさそうです。
ただし、秒間リクエスト数の上限はあるのでリンクした上限を確認しリクエストに耐えられるか、減らす方法は無いか確認が必要となると思います。
検証したpythonコード
import time
import boto3
ssm = boto3.client('ssm')
secretsmanager = boto3.client('secretsmanager')
s3 = boto3.resource('s3')
bucket = s3.Bucket("<S3バケット名>")
obj = bucket.Object("parameter")
dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table('parameter')
def lambda_handler(event, context):
loop_num=100
#SSM パラメータストア
start_unixtime = time.time()
for counter in range(loop_num):
response = ssm.get_parameters(
Names=[
'parameter',
],
WithDecryption=True
)
end_unixtime = time.time()
execuete_time =end_unixtime - start_unixtime
print("SSM パラメータストア:" , execuete_time) #実行時間出力
#SSM パラメータストアKMS利用
start_unixtime = time.time()
for counter in range(loop_num):
response = ssm.get_parameters(
Names=[
'parameterkms',
],
WithDecryption=True
)
end_unixtime = time.time()
execuete_time =end_unixtime - start_unixtime
print("SSM パラメータストアKMS利用:" , execuete_time) #実行時間出力
#SecretsManager
start_unixtime = time.time()
for counter in range(loop_num):
response = secretsmanager.get_secret_value(
SecretId="parameter"
)
end_unixtime = time.time()
execuete_time =end_unixtime - start_unixtime
print("SecretsManager:" , execuete_time) #実行時間出力
#S3 resource
start_unixtime = time.time()
for counter in range(loop_num):
response = obj.get()
end_unixtime = time.time()
execuete_time =end_unixtime - start_unixtime
print("S3:" , execuete_time) #実行時間出力
#DynamoDB
start_unixtime = time.time()
for counter in range(loop_num):
response = table.get_item(Key={'id': '0'})
end_unixtime = time.time()
execuete_time =end_unixtime - start_unixtime
print("DynamoDB:" , execuete_time) #実行時間出力
return 0