概要
FluentdでS3にログ転送している場合で、以下の条件に当てはまると無駄なS3のGETリクエストを消費することがあります
S3のGETリクエスト単価($0.0037/10,000リクエスト
)は安いので、なかなか無駄に気づかないことが多い
私も気づくまでに1年かかりましたw
ただ、無駄なものは無駄なのできちんと設定して無駄を無くしましょう!
正しい設定
-
check_object
をfalse -
%{index}
を利用せずに出力するファイル名が必ず一意になるようにs3_object_key_format
を指定する
ファイル名に秒まで含めるのが良いでしょう
※fluent-plugin-s3のリファレンス
※時間フォーマットの詳しい設定はこちらを参照
<match pattern>
@type s3
path logs/
# 存在確認を無効
check_object false
# hms_sliceは時間
s3_object_key_format %{path}%{time_slice}_%{hms_slice}.log
# 日時(2020-02-18)
time_slice_format %Y-%m-%d
</match>
※なお、バージョンによっては副作用として上記のs3_object_key_format
とcheck_object
を併用するとfluentdログにWARN
が記録されます
なぜ
前述の条件によりS3に同一ファイル名が存在する場合は、自動的に枝番を付与してくれます
ただし、枝番を採番する際に都度GETリクエストを発行して枝番ごとにファイルの存在確認していく処理になっている
実際にCloudTrialログを添えて、流れを追っていきます
-
S3に
2020-02-19.log_0
と2020-02-19.log_1
がある前提 -
さらに同名のログ(
2020-02-19.log
)をPUTする -
2020-02-19.log_0
をGETリクエスト(HeadObject)する -
エラーがなかったので、存在すると判定し、
2020-02-19.log_1
でGETリクエストするCloudTrialログ{ "eventVersion": "1.06", "eventTime": "2020-02-19T09:12:01Z", "eventSource": "s3.amazonaws.com", "eventName": "HeadObject", "awsRegion": "ap-northeast-1", "requestParameters": { "bucketName": "hogehoge", "Host": "hogehoge.s3.ap-northeast-1.amazonaws.com", "key": "logs/2020-02-19_0.log" }, "responseElements": null, "readOnly": true, "resources": [ { "type": "AWS::S3::Object", "ARN": "arn:aws:s3:::hogehoge/logs/2020-02-19_0.log" }, { "type": "AWS::S3::Bucket", "ARN": "arn:aws:s3:::hogehoge" } ], "eventType": "AwsApiCall", "managementEvent": false }
-
同様にエラーがなかったので、存在すると判定し、
2020-02-19.log_2
でGETリクエストするCloudTrialログ{ "eventVersion": "1.06", "eventTime": "2020-02-19T09:12:01Z", "eventSource": "s3.amazonaws.com", "eventName": "HeadObject", "awsRegion": "ap-northeast-1", "requestParameters": { "bucketName": "hogehoge", "Host": "hogehoge.s3.ap-northeast-1.amazonaws.com", "key": "logs/2020-02-19_1.log" }, "responseElements": null, "readOnly": true, "resources": [ { "type": "AWS::S3::Object", "ARN": "arn:aws:s3:::hogehoge/logs/2020-02-19_1.log" }, { "type": "AWS::S3::Bucket", "ARN": "arn:aws:s3:::hogehoge" } ], "eventType": "AwsApiCall", "managementEvent": false }
-
エラー(
"errorCode": "NoSuchKey"
)が発生したので、存在しないと判定し、2020-02-19.log_2
でPUTリクエストするCloudTrialログ{ "eventVersion": "1.06", "eventTime": "2020-02-19T09:12:02Z", "eventSource": "s3.amazonaws.com", "eventName": "HeadObject", "awsRegion": "ap-northeast-1", "errorCode": "NoSuchKey", "errorMessage": "The specified key does not exist.", "requestParameters": { "bucketName": "hogehoge", "Host": "hogehoge.s3.ap-northeast-1.amazonaws.com", "key": "logs/2020-02-19_2.log" }, "responseElements": null, "readOnly": true, "resources": [ { "type": "AWS::S3::Object", "ARN": "arn:aws:s3:::hogehoge/logs/2020-02-19_2.log" }, { "type": "AWS::S3::Bucket", "ARN": "arn:aws:s3:::hogehoge" } ], "eventType": "AwsApiCall", "managementEvent": false }, { "eventVersion": "1.06", "eventTime": "2020-02-19T09:12:02Z", "eventSource": "s3.amazonaws.com", "eventName": "PutObject", "awsRegion": "ap-northeast-1", "requestParameters": { "bucketName": "hogehoge", "Host": "hogehoge.s3.ap-northeast-1.amazonaws.com", "key": "logs/2020-02-19_2.log" }, "readOnly": false, "resources": [ { "type": "AWS::S3::Object", "ARN": "arn:aws:s3:::hogehoge/logs/2020-02-19_2.log" }, { "type": "AWS::S3::Bucket", "ARN": "arn:aws:s3:::hogehoge" } ], "eventType": "AwsApiCall", "managementEvent": false }
という流れになっています
なので枝番が増えれば増えるほどGETリクエスト数も1+2+3+4+5・・・
と増えていきます
ファイル名が被らなくてもcheck_object
が有効な場合は、必ず1回はGETリクエストが発生するので、falseを検討してもよいかもしれない
万が一に上書きの心配があるならば念のために有効のままにしておくのもいいかもしれない
ちなみに自社のS3の請求欄です
S3にはログしか保存していないのにもかかわらず、GETリクエストがPUTの25倍もある
幸い単価が安いので助かっています( ;∀;)
検証用
検証用にサンプルコードを作成したので、そちらで簡単に動作確認ができるかと思います
手順はReadmeを参照ください
https://github.com/comefigo/fluentd-s3
CloudTrial以外にもバケットのメトリックス(CloudWatchの有料メトリックス)でリクエスト数の確認もできますので、必要であればご確認ください