【AWS】Webサービスのユーザ行動ログを捌く時のサービス比較(Lambda・Kinesis Data Firehose・SQS)
# aws # 環境構築
AWSは便利だし、大量データを捌くポテンシャル半端ないし、固定費用のないサービスも多かったりと(お金を払えば)至れり尽くせりですが、あまりにも多種多様なサービスがあるし、特徴も似てるしで検討が大変な部分がありました。
自分の備忘録と同じようなことをやろうとする誰かのために記録しておこうと思います。
やりたいこと
Webサイトの行動ログ(ページ表示・クリック等)をリアルタイムに収集し、その結果に基づいてコンテンツを出し分けたかったんです。 そのために、s3への全データの保存とDynamoDBでリアルタイムのデータ更新をいい感じに出来るようにするという事を目的としました。
なお、データが厳密に正確である必要はないため、多少データが間違っても問題ないくらいの想定です。
Google Analytics使えばよいのでは?という話もあるかと思いますが、無料版だと反映までにラグがあったり全量データの解析ではなくサンプリングデータになったりという避けがたい制約があったため、AWSを使用してデータを収集することにしています。
とはいえ、データの柔軟な可視化という意味では、Google Analyticsが協力である事には疑いの余地はありません(基本無料だし、ノウハウ大量ですし)。
方針
・コストと作業工数をいい感じのバランスで最小化する。 コスト最適化するために死ぬ気で構築やるのは人件費もかかって本末転倒な部分なのと、楽をしたいのが理由ですね。
・普段想定していないようなアクセスが集中的にくる場合にも対処できるようにする。 Webサービスあるあるですが、突発的にアクセスが通常時の100倍みたいなことは良くあります。
という事を考慮し
- 出来るだけこちら側での設定の手間が少ないAWSのマネージドサービス利用
- サーバレス構成でログを収集する(今となれば割と普通な気もしますが…)
という方針としました。
検討したサービス達の紹介
Webからのリクエストをベースとするため、API Gatewayを使用してエンドポイントを作成し、各種のAWSのサービスの起点とします。
そのため、以下のサービスの手前にAPI Gatewayを使用し、API GatewayからLambda等にリクエストをする形となります。
Lambda
言わずと知れたサーバーレスと言えばこれ。 関数を作成することで、ユーザーはサーバー等の設定の必要なくWebAPIが作れてしまう優れものです。
お?サーバー等の設定がいらない?負荷はどうなるのと思うと
自動スケーリング
AWS Lambda は必要なときだけコードを実行し、リクエスト受信の回数に合わせて自動的にスケールします。お客様は何も設定する必要がありません。コードが処理できるリクエスト数に上限はありません。AWS Lambda は基本的にイベントの発生からミリ秒単位でコードを実行します。また Lambda は自動的にスケールするため、イベントの頻度が上昇しても一貫して高いパフォーマンスを維持できます。コードがステートレスなので、Lambda は時間のかかるデプロイや設定によって遅れが出ることなく必要な数だけインスタンスを実行できます。 https://aws.amazon.com/jp/lambda/features/
こんなことが書いてあるのです。すげぇ。これでいいのではと思いました。はい。 だって並列稼働した数とか関係なく、処理時間によってのみ(ちょっと違うけど)料金決まるならこれで良いのではって感じです。
SQS(Simple Queue Service) + lambda
SQS(Simple Queue Service)はAWSが提供しているキューサービスです。SQSタスクをため、貯められたタスクをlambdaが好きなタイミングで取得・実行する形になります。
スタンダード キューと、FIFO キューという2種類のキューがありますが、そのうちのスタンダード キューについては、以下のような記載があります。
無制限のスループット – スタンダード キューは、API アクション (SendMessage、ReceiveMessage、または DeleteMessage) あたり、ほぼ無制限の数の 1 秒あたりのトランザクション (TPS) をサポートできます。
いやなんすかそれどれだけアクセス来ても平気って事っすか半端ねえ。 (FIFO キューの場合でも秒間3,000件までサポートされてます。十分すぎる)
Kinesis Data Firehose(+ lambda)
Kinesis Data Firehoseはストリーミングデータの保存(加工)を目的としたサービスです。
柔軟性に欠ける部分はある(送信先が制限されているなど)らしいですが、自動でS3へやRedShift等へデータの転送を行ってくれるサービスです。強い。
しかも、
いったん起動されると自動的にスケーリングされ、1 秒あたり数ギガバイトを超える入力データレートにも対応し、データレイテンシーはお客様がストリームに指定したレベルに維持されます。手作業での介入やメンテナンスは不要です。
1秒あたり数ギガバイトはもうちょっと意味が分からない単位です。便利そうだけど、ちょっとやりすぎな気もする。 料金例が1 秒あたり 1,000 件のストリーミングデータとかほんと桁が違う気がする…。
データを加工するためにFirehoseに入ってきたデータに対してlambdaを実行可能です。 単純にlambdaが実行できるので、そこでDynamoDBに書き込み等を行うことが出来ます。
機能と料金の比較
前提
-
やろうと思えばどの組み合わせでも機能は実現可能です。今の時代そんなものばかりだと思いますが。
-
SQSはFIFOキューを使わないと普通に同じデータが何回も読み込まれるとのことなので、重複のないFIFOキューを使用します。 (重複制御のコードとか絶対書きたくない…)
-
総費用ではなくサービスの比較をしたいため、S3の保存容量・API Gatewayの使用量など、どのサービスを使用しても変わりなく費用が発生すると思われる部分については省略しています。
-
あくまでざっくりとした比較だけしたいので、サンプルのある米国東部 (バージニア北部) リージョンで算出しています。
-
30,000,000 回のログ格納が発生する(lambdaの料金計算がやや複雑なため、公式で公開されているlambdaの料金例に他の物を合わせます。)
-
比較的シンプルなログかつ複雑な加工は行わない(計算簡易化のため、毎回のログのサイズは1KBとします。) なお、以下で236byteなのでそれなりに大きめに見積もっています。
192.168.11.3 - - [09/Sep/2015:01:47:22 +0900] "GET /css-combinators/ HTTP/1.1" 200 7974 "http://webllica.com/feed-icon-by-html-css/" "Mozilla/5.0 (Windows NT 6.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.85 Safari/537.36"
-
実際にログ取得用にサービス運用をしたわけではなく、皮算用ですので参考までに…
料金と機能の比較
サービス | 同時実行の制限 | s3へのバックアップにかかる手間 | DynamoDBへのデータ保存にかかる手間 | 金額 |
lambda | 同時実行1,000件 ※上限突破時は破棄 ※リージョンによって異なる ※サポートに連絡して緩和可能 | 自前で保存する関数を用意 ※s3に保存するログは基本1行ずつ? | 自前で保存する関数を用意 | 5.83USD |
SQS + lambda | 1 秒あたり最大 3,000 件 ※サポートに連絡して緩和可能 | 自前で保存する関数を用意 ※s3に保存するログは基本1行ずつ? | 自前で保存する関数を用意 | 7USD(5.83USD+1.17USD) |
Kinesis Data Firehose+ lambda | 無制限 (1 秒あたり数ギガバイトは余裕らしい) | 画面からポチポチ設定するだけ ※自動である程度まとめてくれる。 | 自前で保存する関数を用意 (ある程度データがまとまってから処理) | 6.24USD(5.83USD+0.41USD) |
※lambdaの料金計算…関数に 128 MB のメモリ量を割り当てて 30,000,000 回実行し、毎回の実行時間が 200 ミリ秒間だった場合です。計算がやや複雑なので公式のサンプルを流用。
関数に 128 MB のメモリ量を割り当てて 30,000,000 回実行し、毎回の実行時間が 200 ミリ秒間だった場合、料金は以下のようになります。
1 か月のコンピューティング料金
1 か月のコンピューティング価格は 1 GB-秒につき 0.00001667 USD で、無料利用枠は 400,000 GB-秒です。
合計コンピューティング (秒) = 30,000,000 × (0.2 秒) = 6,000,000 秒
合計コンピューティング (GB-秒) = 6,000,000 × 128 MB ÷ 1024 = 750,000 GB-秒
合計コンピューティング – 無料利用枠 = 1 か月の請求コンピューティング秒
750,000 GB-秒 – 400,000 GB-秒の無料利用枠 = 350,000 GB-秒
1 か月のコンピューティング料金 = 350,000 × 0.00001667 USD = 5.83 USD
※SQSの料金計算補足 課金対象のリクエスト数 = (3,000,000件 - 1,000,000件(無料枠))= 2,000,000万件(1,000,000リクエスト当たり0.5USD) 課金対象のデータ転送量 = (3,000,000件 - 1,000,000件(無料枠)) × 1KB = 約2.86GB (1GBあたり0.09USD) 合計:1.17USD
※Kinesis Data Firehoseの料金計算補足 課金対象のデータ転送量 = 3,000,000件× 5KB = 約14.31GB(1GBあたり0.029USD) 転送量は5KB単位の切り上げでの算出となります。 合計:0.41USD
結論:Kinesis Data Firehose+ lambdaで運用する!
圧倒的にKinesis Data Firehoseが優秀に感じます。 IoTのようなデータ量を想定しているため、Webのログ程度なら料金もさほどかからんし。 このクラスのサービスで完全にオンデマンドの使用量なのは本当にすごい。
殆ど手間をかけることなくs3にデータを流してくれる機能があまりにも強力です。 SQSやlambda単体だと、楽をしようとするとs3に1行ずつログを格納するはめになりそうですが、 (ちゃんとやるならデータ集約用のサーバーを作るのが基本) 細かいことはAWSに任せて、10分単位等でログをまとめて更に圧縮までしてくれるという至れり尽くせり…。
入ってきたデータに対してlambdaで好き放題出来るようなので、拡張性もありますし。
そもそもSQSは大量データを捌くことも出来ますが、適した処理は重い処理を順次実行するものではないでしょうか。
Kinesis系はWebのクリックログ等にも使えると使用例に載っているので当然の結果かもしれませんが、サービスへの理解が深まったのでよしとします。
参考
Gnosyさんめっちゃ参考にさせてもらいました。 これだけ情報公開してくれているのは非常にありがたいです…。
https://logmi.jp/tech/articles/304737
https://www.slideshare.net/AmazonWebServicesJapan/amazon-kinesis-family-118299242
https://www.slideshare.net/shunsukekozawa5/gunosy-152302982
その他
いつの日かこのレベルの本をちゃんと読んで理解を深めたい。