爆イケぴえん。 【Serverless】写真のアップロード速度を爆速にした話

岸優太[King&Prince] X 爆イケ

爆イケぴえん

この記事はうるる 17日目の記事です。 はじめに この記事では、私が働いている会社、で運営しているサービス幼稚園・保育園向け写真販売サービス において、写真アップロードの速度を爆速にするためにAWSのServerlessアーキテクチャを導入したお話をします。 サービスの内容や、導入に至った経緯などもお話ししたいところですが 話がとても長くなってしまいそうなので、アーキテクチャ導入にあたって考えたことや、細かい処理の説明にのみフォーカスし、記事を書きたいと思います。 対象の読者• 画像のアップロード速度に困っている人• 画像を扱うサービスの開発を担当している人 注意点 かなり長めの記事です。 読み切るのに根気がいるかと思いますが、 いいねやストックをすることで数回に分けて読むことをお勧めします。 システム構成 一部 当アプリケーションは Laravel5系で構築されており、インフラ IaaS は主にAWSで構成されています。 webサーバーはで管理しているEC2インスタンスです。 写真の保存ストレージは、写真のサムネイルの作成は開発時にはすでにLambdaを用いて処理させていました。 DBはを使用しています。 また今回のアーキテクチャには深く関わりませんが、当サービスでは、顔写真の検索にを用いております。 移行前のアーキテクチャと構成 処理の流れ• クライアントサイドでアップロード処理を実行すると、サーバーへ写真や紐付けなどの情報がPOSTされます。 Laravel上で受け取った写真の拡張子やサイズなどが、制限内に収まっているかどうかをチェックします。 写真が正しいものと判定されたら、写真に関するデータをRDSに保存します。 写真名とか、リレーションIDとかそんな奴らです• DBへの保存後、s3へ写真をPUTします。 この際はLaravel上でS3のAPIを使用します。 S3へ写真が上がると、次はLambdaが起動します• Lambdaは、 写真のトリミングと サムネイルの作成のファンクションが順番に起動します。 移行前の課題 移行前の構成における問題点は、画像のチェックやDBへのデータ保存、S3への写真転送など、一通りの処理が終わった後にクライアントへレスポンスが返るスタイルでした。 一枚の写真だけであれば対して問題は起きませんが、流石に1日に何千何万枚という写真がアップロードされ、サーバー上でその写真の処理をしていくと、いくつか問題が発生します。 そのうちの1つが、レイテンシーの発生でした。 真ん中より左側が、サーバーレス移行前のレイテンシーです。 日常的にもそうですが、瞬間的に負荷が上がるタイミングなどでは特にめちゃくちゃ飛び出ます。 サーバー台数を増やしたり、EC2のインスタンスサイズをあげたりすればこの負荷はもう少し分散することができますが サーバーレスであれば瞬間的なアップロードにも対応でき、なおかつそれぞれの処理も速い状態を維持できるというメリットがあったので、サーバーレスの導入を検討しました。 何よりもサーバーレスを使いたかったのです。 (笑) サーバーレス化の後のレイテンシは見ての通りです。 効果は抜群でした。 新アーキテクチャ決定までにやったこと 当初、考案したアーキテクチャ まず、やりたかったことは以下です。 EC2サーバーを一切介さないというのが最大の目標として考えていました。 写真は一枚一枚が重いですし 数MB 、事業拡大とともに扱う写真枚数も右肩上がりになります。 事業拡大に負けないくらいのシステムするというのも今回の目標でしたので、 スケーラブルという魅力のあるサーバーレスに写真の処理を全任せすることを目指しました。 しかし、いくつかの障害にぶつかることとなります。 API Gatewayの問題点• 当初、API GatewayからLambdaを呼び出すことにより、サムネイルの処理を行うことを想定した。 クライアントから直接API経由で画像を送信し、そのままLambdaで処理するスタイル しかし、Lambdaの呼び出しペイロード制限 6MBに直面しました... 画像の送信サイズは20MBまであげたかったので、この方法は採用できませんでした。 DynamoDBの断念• Rekognition 顔認証 のデータ• 顔認証のデータが大量にあり、RDSのストレージを圧迫する原因となっている• Dynamo使いたい• ライブラリにより、ORMなどをDynamoでもサポートするようにはできる• 不可能ではない。 というか多分できる。 開発期間が足りない• Step FunctionとかAPIGatewayとかAuroraとか、不確定要素が多い中で 一人で進めるプロジェクト• リリース時期の目標がある中で、Dynamoの検証を進める時間が足りなそうだった 開発期間3ヶ月くらい• 何よりも優先度が低かった DynamoDBについては、完全に 使いたい欲が先行していました。 本来であれば、アプリケーション全体をサーバーレスへ対応させるため、MySQLを丸っとDynamoDBへ移行したかったですが 流石に検証期間が短すぎるため、一部だけ移行という方法を考えましたが それでも今回は優先度が低かったため、見送りになりました。 Aurora Serverlessの検討 DynamoDBは、RDS+Lambdaの相性の悪さから考えた案でしたが その次にを検討しました。 DataAPI このDataAPIという、サーバーレスにとって最高の機能を使えば大体の問題は解決すると考えました。 ただし、大問題が... ユースケース 公式ドキュメント抜粋• 使用頻度の低いアプリケーション• 新規アプリケーション• 可変ワークロード• 予測不可能なワークロード• 開発およびテスト用データベース• マルチテナントアプリケーション 開発およびテスト用データベース だと... 本番環境向きではないと、公式が示しています。 これはあかんと思い、AWSのサポートに直接聞いてみました。 すると以下のような回答が返ってきました。 本番アプリケーションの要件に合致してたら使っていいよ。 でもちゃんとテストしてね! なるほど... テストしてみて使えそうだったら使ってもいいのか。 そう思い、早速検証に入りました。 AuroraとAuroraServerlessの検証 AuroraとAuroraServerlessを対象に、サーバーレスに耐久できるかどうか検証をしました。 検証内容については本記事とテーマが少しずれてしまうため、また別の記事で紹介させてください。 結果は、 AuroraServerlessの圧勝という結果でした。 Auroraってだけあり、パフォーマンスもそれなりに高く、安定して動いてくれました。 本番環境でも問題なく動かせるのではないかという結果を導くことにも成功しました。 しかし、ここでも大きな問題が発生しました... Aurora Serverlessの開発環境 開発環境でAuroraServerlessを使おうとする際の方法は以下2つでした。 実際のAWSリソースを準備しローカルからアクセスする• Dockerコンテナで仮想的にAuroraServerlessを構築する AuroraServerlessは割と新しいサービスで、コンテナはかなり難易度が高かったため、実際のリソースを使うことにしました。 しかし、AuroraServerlessの制限でAuroraにパブリックIPを割り当てることができませんでした... 開発環境からAuroraServerlessにアクセスするには、パブリックIPを割り当てる必要があったため、これは大打撃です。 時間をかけAuroraServerlessを検証し、やっと使える!というところまできたところでこれはかなりショッキングな制限でした。 ショックすぎて、AWSサポートに問い合わせてどうにかならないか聞きましたが、ドキュメント以上のことは返ってきませんでした... そりゃそうだ、、、 AuroraServerless自体、新しいのでAWS側でも細かいところまでは回答ができないみたいだ。 Aurora Serverlessの断念 DataAPIという強力な機能のためにいろんなものを犠牲にしようとしました。 AWS新サービス特有の情報の少なさ、ユースケース外の使用、問題が発生した時はマンパワーで頑張るという覚悟。 しかし、開発環境を整えることができないという問題により選択肢から除外せざるを得ませんでした。 結果的には、特にDBのようなアプリケーションの基盤となるようなものに関しては、ナレッジの少ない選択肢を選ぶのにはリスクが非常に高いので、採用しなくて正解だったとも言えます。 この当時、精神的に色々やられましたがなんとか諦めをつけることができました。 まさに、失恋した気分でした。 というかこれで行くしかない Auroraへの移行も考えましたが、社内事情などもありながら、とりあえず現状通りRDSMySQLでトライしてみることにしました。 では実際にどのくらいの瞬間風速で同時起動数が跳ね上がるのかを検証してみました。 結果は以下でした。 現状のサービス規模であれば、コネクション問題を回避することが可能であるということが検証により明らかになりました。 このように、紆余曲折を経てアーキテクチャの決定までこぎつけることができました。 新アーキテクチャと構成 以下の画像が新アーキテクチャです。 どうでしょうか。 大まかに説明します。 まずクライアントから S3に直接写真を突っ込み、それに反応し、の ステートマシンが起動します。 ステートマシン内で、それぞれの処理をするLambdaファンクションが順々に実行されていき、DBへのデータ登録やサムネイルなどが作成され終了です。 アーキテクチャを以下の様に分解して、説明します。 長すぎて忘れてしまっていたらすみません... 実はこの部分こそが、写真のアップロード速度を爆速にできた要因となっています。 写真のアップロード速度は、ブラウザ上でsubmitしてから、レスポンスが返ってくるまでの時間です。 移行前の構成では、レスポンスを返すまでに色々な処理が走ったため、待ち時間が発生してしまっていました。 ですので、これをシンプルに S3に写真を保存したら即レスポンスにするのが理論上、最も速いです。 写真を保存するだけなら、サーバー経由でもできますが、それは最速ではないです。 S3に直接 これが最速です。 速くするからには最速にこだわりました。 速いは正義です。 ですが、S3に直接送信するためには、セキュリティの問題が存在しました。 当初などの認証サービスを使用することでセキュリティを担保することを考えましたが、このためだけに認証サービスを入れるのはお金も時間もコストがかかりすぎました。 そこで見つけたのが S3の署名付きURLでした。 参考: この署名付きURLを用いてアップロードを行うことで、セキュリティを担保しながらS3への直接アップロードを実現しました。 基本的にはSDKの使い方そのままなので非常に簡単でした。 us - east - 1. amazonaws. 詳しくは公式ドキュメントに記載してありますので割愛させていただきます。 StepFunctionsについては、色々な入門的な記事があるので、そちらを参考にしてみてください 基本的には、LambdaやDynamoDB、SQSなどのAWS各種サービスを使い、ワークフローを構築できるというサービスです。 並行処理や条件分岐、失敗時のリトライや、エラーをCatchしての処理などの機能が備わっています。 移行前のアーキテクチャでは、LambdaをS3トリガーで単一的使っていました。 そこには、エラー時に捕捉できず、失敗したらそのままにするしかない、などというサーバーレス特有の問題がありました。 StepFunctionsを使うことで、自由にリトライさせることもできますし、並列処理を用いて、サムネイルを数パターン作らせるとか、Rekognitionも同時に実行することなど、色々な処理を構築することができることが魅力的です。 ステートマシンの定義 今回は、割と単純な構成です。 各種データのDBへの保存、トリミング、サムネイル 失敗時には、レコードをエラーステータスに更新する。 といった処理を行っています。 ステートマシン定義の一部 今回構築したワークフローは比較的単純なので、最初の部分のみステートマシンの定義方法を紹介します。 ポイントは Retryの部分です。 待機時間に関しては、図中の説明の通りですが、今回のアーキテクチャ特有のエラーハンドリングが2つあります。 Lambda. TooManyRequestsException これは、急激に大量のLambdaを起動した際に発生するエラーになります。 瞬間的な負荷にも耐えなければいけないですが、こちらはAWSが制限を設けているので、ある程度仕方ないエラーです。 この場合は、ちょっとだけ時間をあけてリトライさせて回避しています。 Lambda. ENILimitReachedException こちらは、VPCのの制限です。 しかも、このENIはLambdaコンテナが消えても一定時間残り続けるので、短い時間に大量のLambdaが起動してしまうとENIが爆増し、制限に達してしまいエラーとなります。 ENIの消滅に時間がかかるので、待機時間も長めにとっています。 ただこちらは、ちょうどリリースする直前にAWSが改善してくれました。 この発表には飛び跳ねました。 このように、エラーに対して適切なハンドリングを設定できたのがStepFunctionsの魅力です。 失敗するとレコード中のエラーステータスを更新するようにしておりますが、エラーの種類によって実行Functionを切り替えて、ステータスコードを別のものにするなどもできた方がデバッグに役立ったかもしれません。 エラー内容をfunctionへ受け渡すこともできたような記憶も... CICD さて、上記で写真を爆速でアップロードするための仕組みが整いました。 ここからはCICDの仕組みの構築です。 我々エンジニアは、作ればOKという世界でありませんよね。 作ったものを安全に正確にデプロイ 世の中へ供給 する必要があります。 ServerlessFrameworkによるサーバーレスデプロイ StepFunctionsやLambdaのデプロイにはを使用しています。 サーバーレスであるLambdaはもちろんGCP、AzureなどのサービスをCLIからデプロイできるツールです。 こちらも細かい使い方は省きますが、設定ファイルである serverless. ymlの設定をご紹介します。 参考: Lambdaの定義 ここでは1つのFunctionを紹介します。 functions : storePhotoData : handler : storePhotoData. reservedConcurrency. これは、ServerlessFrameworkの機能であるカスタム変数を利用し、各デプロイ環境ごとに値をセットしています。 参考: 実際に以下のように設定しています。 db・・・RDSの接続情報• VPC・・・セキュリティグループとサブネットの情報 実は、弊社ではえんフォトと同様、写真販売サービスというのも運営しており、基本的な構成はえんフォトと同じなので、同時にデプロイできるようにしています。 えんフォトとクラプリ、本番・ステージング・開発環境でそれぞれ別の値をセットしたいため、カスタム変数を使っています。 都度、OS上の環境を読み込むため、基本的にはCircleCIの環境変数に事前にセットしておくことでデプロイします。 また、 tracing: Active にも注目です。 後述の監視で紹介しますが、を有効にするための設定です。 StepFunctionsの定義 Serverless FrameworkはデフォルトでStepFunctionsが使えないので以下のプラグインを入れることで対応します。 stepFunctions : stateMachines : enphotoSpica : events : - cloudwatchEvent : event : source : - aws. s3 detail-type : - AWS API Call via CloudTrail detail : eventSource : - s3. amazonaws. TooManyRequestsException 呼び出し頻度のエラー IntervalSeconds : 5 MaxAttempts : 5 - ErrorEquals : - Lambda. ENILimitReachedException ENIの制限エラー IntervalSeconds : 30 MaxAttempts : 2 - ErrorEquals : - States. ALL IntervalSeconds : 1 MaxAttempts : 3 Catch : - ErrorEquals : - States. error Next : updatePhotoDataToError Next : Trimming 基本的には、ステートファイルの定義をyaml形式に変えたものになります。 CircleCIによる自動デプロイ ServerlessFrameworkの準備ができたら、CircleCIで自動デプロイをするようにします。 0 cd. デプロイは以下のように行います。 CircleCIの適切な場所でコマンドを実行してください。 監視 さて、サーバーレスの実行、そして自動デプロイまで整いCIのための基盤は整いました。 ここからは、それを正しく運用するための監視基盤を紹介します。 それほど大したものではありませんが AWS X-Ray LambdaにX-Rayを簡単に導入できるため、お試しの意味も込めて導入しました。 Lambdaのエラーなどを可視化することができます。 単純な絵ですね... 画像は全部緑ですが 失敗したりしていると色が変わってくれます。 また、実行時間のアベレージも表示してくれて便利です。 エラーログのSlack通知 StepFunctionは基本的に大量実行に向いていないようで、ログがあまり充実していないです。 コンソールから見ることができるログも1000回までで、それ以前のログは遡れないです。 そのため、エラーが発生した時にはSlackに通知し、できるだけ早く調査対応を行えるようにしました。 クラスメソッドさんのこちらの記事を参考にさせていただきました。 Lambdaのソースコードは以下です。 Request url req. read こんな感じに通知が来ます。 最後に いかがでしたでしょうか。 割と長めの記事を書いたので、書くのも疲れましたが、最後まで読んでいただいた方々も疲れたと思います。 読んでいただきありがとうございました。 アップロード速度 肝心のアップロード速度がどうなったか気になりますよね。 こんな感じです!どーん 特定の写真で実際に計測した結果ですが、4倍速という結果になりました! 元々が少し遅めだったということもありますが、お客様には非常に好評をいただいております。 嬉しいですね。 AWS サポートの大切さ プロジェクト開始時、最初は色々と自力でなんとかしようと踏ん張っていた時期がありました。 ですが、どうしても答えが見つからなかったり、ベストプラクティス的な問題にぶち当たったり、色々な困難がある中で、勇気を出してAWSサポートへ問い合わせをしてみた結果 とても参考になるアドバイスをくれることが結構ありました。 AWSの中の人が書いた記事などのリンクまで張ってきてアドバイスをくれたり、とても親切に対応してくださいました。 さすが天下のAWSさま。 これはやばい、いち早く導入して、不安要素を取り除きたいと思います! まとめ 自己紹介が遅れましたが、私は新卒3年目の中堅? 二歩?手前の エンジニアです。 サービス成長のために、自らサーバーレスによる改善を提案し、実行させていただきました。 AWSに関する書籍や、ネット記事、AWSカンファレンスなどにも参加し、サーバーレスについてほとんど何も知らない状態から色々な情報をインプットし、成し遂げることができました。 情報取集を含めると最初に動き始めてからは半年くらいの時間をこのプロジェクトに捧げました。 実際の稼働は3、4ヶ月ほどです。 その間には、特に社内のインフラエンジニアの先輩方には非常にお世話になりました。 リリース1ヶ月前くらいからは毎日終電前まで残業に付き合ってくださいました。 この場を借りてお礼申し上げます。 また、最後まで読んでいただいた皆さま、ありがとうございます。 ぜひ少しでもお役に立てた場合は いいねを押してください!! 終わり Advent Calendar 17日目でした。 明日18日目は ryuichi fukudaさんによる記事を乞うご期待!.

次の

【Serverless】写真のアップロード速度を爆速にした話

爆イケぴえん

この記事はうるる 17日目の記事です。 はじめに この記事では、私が働いている会社、で運営しているサービス幼稚園・保育園向け写真販売サービス において、写真アップロードの速度を爆速にするためにAWSのServerlessアーキテクチャを導入したお話をします。 サービスの内容や、導入に至った経緯などもお話ししたいところですが 話がとても長くなってしまいそうなので、アーキテクチャ導入にあたって考えたことや、細かい処理の説明にのみフォーカスし、記事を書きたいと思います。 対象の読者• 画像のアップロード速度に困っている人• 画像を扱うサービスの開発を担当している人 注意点 かなり長めの記事です。 読み切るのに根気がいるかと思いますが、 いいねやストックをすることで数回に分けて読むことをお勧めします。 システム構成 一部 当アプリケーションは Laravel5系で構築されており、インフラ IaaS は主にAWSで構成されています。 webサーバーはで管理しているEC2インスタンスです。 写真の保存ストレージは、写真のサムネイルの作成は開発時にはすでにLambdaを用いて処理させていました。 DBはを使用しています。 また今回のアーキテクチャには深く関わりませんが、当サービスでは、顔写真の検索にを用いております。 移行前のアーキテクチャと構成 処理の流れ• クライアントサイドでアップロード処理を実行すると、サーバーへ写真や紐付けなどの情報がPOSTされます。 Laravel上で受け取った写真の拡張子やサイズなどが、制限内に収まっているかどうかをチェックします。 写真が正しいものと判定されたら、写真に関するデータをRDSに保存します。 写真名とか、リレーションIDとかそんな奴らです• DBへの保存後、s3へ写真をPUTします。 この際はLaravel上でS3のAPIを使用します。 S3へ写真が上がると、次はLambdaが起動します• Lambdaは、 写真のトリミングと サムネイルの作成のファンクションが順番に起動します。 移行前の課題 移行前の構成における問題点は、画像のチェックやDBへのデータ保存、S3への写真転送など、一通りの処理が終わった後にクライアントへレスポンスが返るスタイルでした。 一枚の写真だけであれば対して問題は起きませんが、流石に1日に何千何万枚という写真がアップロードされ、サーバー上でその写真の処理をしていくと、いくつか問題が発生します。 そのうちの1つが、レイテンシーの発生でした。 真ん中より左側が、サーバーレス移行前のレイテンシーです。 日常的にもそうですが、瞬間的に負荷が上がるタイミングなどでは特にめちゃくちゃ飛び出ます。 サーバー台数を増やしたり、EC2のインスタンスサイズをあげたりすればこの負荷はもう少し分散することができますが サーバーレスであれば瞬間的なアップロードにも対応でき、なおかつそれぞれの処理も速い状態を維持できるというメリットがあったので、サーバーレスの導入を検討しました。 何よりもサーバーレスを使いたかったのです。 (笑) サーバーレス化の後のレイテンシは見ての通りです。 効果は抜群でした。 新アーキテクチャ決定までにやったこと 当初、考案したアーキテクチャ まず、やりたかったことは以下です。 EC2サーバーを一切介さないというのが最大の目標として考えていました。 写真は一枚一枚が重いですし 数MB 、事業拡大とともに扱う写真枚数も右肩上がりになります。 事業拡大に負けないくらいのシステムするというのも今回の目標でしたので、 スケーラブルという魅力のあるサーバーレスに写真の処理を全任せすることを目指しました。 しかし、いくつかの障害にぶつかることとなります。 API Gatewayの問題点• 当初、API GatewayからLambdaを呼び出すことにより、サムネイルの処理を行うことを想定した。 クライアントから直接API経由で画像を送信し、そのままLambdaで処理するスタイル しかし、Lambdaの呼び出しペイロード制限 6MBに直面しました... 画像の送信サイズは20MBまであげたかったので、この方法は採用できませんでした。 DynamoDBの断念• Rekognition 顔認証 のデータ• 顔認証のデータが大量にあり、RDSのストレージを圧迫する原因となっている• Dynamo使いたい• ライブラリにより、ORMなどをDynamoでもサポートするようにはできる• 不可能ではない。 というか多分できる。 開発期間が足りない• Step FunctionとかAPIGatewayとかAuroraとか、不確定要素が多い中で 一人で進めるプロジェクト• リリース時期の目標がある中で、Dynamoの検証を進める時間が足りなそうだった 開発期間3ヶ月くらい• 何よりも優先度が低かった DynamoDBについては、完全に 使いたい欲が先行していました。 本来であれば、アプリケーション全体をサーバーレスへ対応させるため、MySQLを丸っとDynamoDBへ移行したかったですが 流石に検証期間が短すぎるため、一部だけ移行という方法を考えましたが それでも今回は優先度が低かったため、見送りになりました。 Aurora Serverlessの検討 DynamoDBは、RDS+Lambdaの相性の悪さから考えた案でしたが その次にを検討しました。 DataAPI このDataAPIという、サーバーレスにとって最高の機能を使えば大体の問題は解決すると考えました。 ただし、大問題が... ユースケース 公式ドキュメント抜粋• 使用頻度の低いアプリケーション• 新規アプリケーション• 可変ワークロード• 予測不可能なワークロード• 開発およびテスト用データベース• マルチテナントアプリケーション 開発およびテスト用データベース だと... 本番環境向きではないと、公式が示しています。 これはあかんと思い、AWSのサポートに直接聞いてみました。 すると以下のような回答が返ってきました。 本番アプリケーションの要件に合致してたら使っていいよ。 でもちゃんとテストしてね! なるほど... テストしてみて使えそうだったら使ってもいいのか。 そう思い、早速検証に入りました。 AuroraとAuroraServerlessの検証 AuroraとAuroraServerlessを対象に、サーバーレスに耐久できるかどうか検証をしました。 検証内容については本記事とテーマが少しずれてしまうため、また別の記事で紹介させてください。 結果は、 AuroraServerlessの圧勝という結果でした。 Auroraってだけあり、パフォーマンスもそれなりに高く、安定して動いてくれました。 本番環境でも問題なく動かせるのではないかという結果を導くことにも成功しました。 しかし、ここでも大きな問題が発生しました... Aurora Serverlessの開発環境 開発環境でAuroraServerlessを使おうとする際の方法は以下2つでした。 実際のAWSリソースを準備しローカルからアクセスする• Dockerコンテナで仮想的にAuroraServerlessを構築する AuroraServerlessは割と新しいサービスで、コンテナはかなり難易度が高かったため、実際のリソースを使うことにしました。 しかし、AuroraServerlessの制限でAuroraにパブリックIPを割り当てることができませんでした... 開発環境からAuroraServerlessにアクセスするには、パブリックIPを割り当てる必要があったため、これは大打撃です。 時間をかけAuroraServerlessを検証し、やっと使える!というところまできたところでこれはかなりショッキングな制限でした。 ショックすぎて、AWSサポートに問い合わせてどうにかならないか聞きましたが、ドキュメント以上のことは返ってきませんでした... そりゃそうだ、、、 AuroraServerless自体、新しいのでAWS側でも細かいところまでは回答ができないみたいだ。 Aurora Serverlessの断念 DataAPIという強力な機能のためにいろんなものを犠牲にしようとしました。 AWS新サービス特有の情報の少なさ、ユースケース外の使用、問題が発生した時はマンパワーで頑張るという覚悟。 しかし、開発環境を整えることができないという問題により選択肢から除外せざるを得ませんでした。 結果的には、特にDBのようなアプリケーションの基盤となるようなものに関しては、ナレッジの少ない選択肢を選ぶのにはリスクが非常に高いので、採用しなくて正解だったとも言えます。 この当時、精神的に色々やられましたがなんとか諦めをつけることができました。 まさに、失恋した気分でした。 というかこれで行くしかない Auroraへの移行も考えましたが、社内事情などもありながら、とりあえず現状通りRDSMySQLでトライしてみることにしました。 では実際にどのくらいの瞬間風速で同時起動数が跳ね上がるのかを検証してみました。 結果は以下でした。 現状のサービス規模であれば、コネクション問題を回避することが可能であるということが検証により明らかになりました。 このように、紆余曲折を経てアーキテクチャの決定までこぎつけることができました。 新アーキテクチャと構成 以下の画像が新アーキテクチャです。 どうでしょうか。 大まかに説明します。 まずクライアントから S3に直接写真を突っ込み、それに反応し、の ステートマシンが起動します。 ステートマシン内で、それぞれの処理をするLambdaファンクションが順々に実行されていき、DBへのデータ登録やサムネイルなどが作成され終了です。 アーキテクチャを以下の様に分解して、説明します。 長すぎて忘れてしまっていたらすみません... 実はこの部分こそが、写真のアップロード速度を爆速にできた要因となっています。 写真のアップロード速度は、ブラウザ上でsubmitしてから、レスポンスが返ってくるまでの時間です。 移行前の構成では、レスポンスを返すまでに色々な処理が走ったため、待ち時間が発生してしまっていました。 ですので、これをシンプルに S3に写真を保存したら即レスポンスにするのが理論上、最も速いです。 写真を保存するだけなら、サーバー経由でもできますが、それは最速ではないです。 S3に直接 これが最速です。 速くするからには最速にこだわりました。 速いは正義です。 ですが、S3に直接送信するためには、セキュリティの問題が存在しました。 当初などの認証サービスを使用することでセキュリティを担保することを考えましたが、このためだけに認証サービスを入れるのはお金も時間もコストがかかりすぎました。 そこで見つけたのが S3の署名付きURLでした。 参考: この署名付きURLを用いてアップロードを行うことで、セキュリティを担保しながらS3への直接アップロードを実現しました。 基本的にはSDKの使い方そのままなので非常に簡単でした。 us - east - 1. amazonaws. 詳しくは公式ドキュメントに記載してありますので割愛させていただきます。 StepFunctionsについては、色々な入門的な記事があるので、そちらを参考にしてみてください 基本的には、LambdaやDynamoDB、SQSなどのAWS各種サービスを使い、ワークフローを構築できるというサービスです。 並行処理や条件分岐、失敗時のリトライや、エラーをCatchしての処理などの機能が備わっています。 移行前のアーキテクチャでは、LambdaをS3トリガーで単一的使っていました。 そこには、エラー時に捕捉できず、失敗したらそのままにするしかない、などというサーバーレス特有の問題がありました。 StepFunctionsを使うことで、自由にリトライさせることもできますし、並列処理を用いて、サムネイルを数パターン作らせるとか、Rekognitionも同時に実行することなど、色々な処理を構築することができることが魅力的です。 ステートマシンの定義 今回は、割と単純な構成です。 各種データのDBへの保存、トリミング、サムネイル 失敗時には、レコードをエラーステータスに更新する。 といった処理を行っています。 ステートマシン定義の一部 今回構築したワークフローは比較的単純なので、最初の部分のみステートマシンの定義方法を紹介します。 ポイントは Retryの部分です。 待機時間に関しては、図中の説明の通りですが、今回のアーキテクチャ特有のエラーハンドリングが2つあります。 Lambda. TooManyRequestsException これは、急激に大量のLambdaを起動した際に発生するエラーになります。 瞬間的な負荷にも耐えなければいけないですが、こちらはAWSが制限を設けているので、ある程度仕方ないエラーです。 この場合は、ちょっとだけ時間をあけてリトライさせて回避しています。 Lambda. ENILimitReachedException こちらは、VPCのの制限です。 しかも、このENIはLambdaコンテナが消えても一定時間残り続けるので、短い時間に大量のLambdaが起動してしまうとENIが爆増し、制限に達してしまいエラーとなります。 ENIの消滅に時間がかかるので、待機時間も長めにとっています。 ただこちらは、ちょうどリリースする直前にAWSが改善してくれました。 この発表には飛び跳ねました。 このように、エラーに対して適切なハンドリングを設定できたのがStepFunctionsの魅力です。 失敗するとレコード中のエラーステータスを更新するようにしておりますが、エラーの種類によって実行Functionを切り替えて、ステータスコードを別のものにするなどもできた方がデバッグに役立ったかもしれません。 エラー内容をfunctionへ受け渡すこともできたような記憶も... CICD さて、上記で写真を爆速でアップロードするための仕組みが整いました。 ここからはCICDの仕組みの構築です。 我々エンジニアは、作ればOKという世界でありませんよね。 作ったものを安全に正確にデプロイ 世の中へ供給 する必要があります。 ServerlessFrameworkによるサーバーレスデプロイ StepFunctionsやLambdaのデプロイにはを使用しています。 サーバーレスであるLambdaはもちろんGCP、AzureなどのサービスをCLIからデプロイできるツールです。 こちらも細かい使い方は省きますが、設定ファイルである serverless. ymlの設定をご紹介します。 参考: Lambdaの定義 ここでは1つのFunctionを紹介します。 functions : storePhotoData : handler : storePhotoData. reservedConcurrency. これは、ServerlessFrameworkの機能であるカスタム変数を利用し、各デプロイ環境ごとに値をセットしています。 参考: 実際に以下のように設定しています。 db・・・RDSの接続情報• VPC・・・セキュリティグループとサブネットの情報 実は、弊社ではえんフォトと同様、写真販売サービスというのも運営しており、基本的な構成はえんフォトと同じなので、同時にデプロイできるようにしています。 えんフォトとクラプリ、本番・ステージング・開発環境でそれぞれ別の値をセットしたいため、カスタム変数を使っています。 都度、OS上の環境を読み込むため、基本的にはCircleCIの環境変数に事前にセットしておくことでデプロイします。 また、 tracing: Active にも注目です。 後述の監視で紹介しますが、を有効にするための設定です。 StepFunctionsの定義 Serverless FrameworkはデフォルトでStepFunctionsが使えないので以下のプラグインを入れることで対応します。 stepFunctions : stateMachines : enphotoSpica : events : - cloudwatchEvent : event : source : - aws. s3 detail-type : - AWS API Call via CloudTrail detail : eventSource : - s3. amazonaws. TooManyRequestsException 呼び出し頻度のエラー IntervalSeconds : 5 MaxAttempts : 5 - ErrorEquals : - Lambda. ENILimitReachedException ENIの制限エラー IntervalSeconds : 30 MaxAttempts : 2 - ErrorEquals : - States. ALL IntervalSeconds : 1 MaxAttempts : 3 Catch : - ErrorEquals : - States. error Next : updatePhotoDataToError Next : Trimming 基本的には、ステートファイルの定義をyaml形式に変えたものになります。 CircleCIによる自動デプロイ ServerlessFrameworkの準備ができたら、CircleCIで自動デプロイをするようにします。 0 cd. デプロイは以下のように行います。 CircleCIの適切な場所でコマンドを実行してください。 監視 さて、サーバーレスの実行、そして自動デプロイまで整いCIのための基盤は整いました。 ここからは、それを正しく運用するための監視基盤を紹介します。 それほど大したものではありませんが AWS X-Ray LambdaにX-Rayを簡単に導入できるため、お試しの意味も込めて導入しました。 Lambdaのエラーなどを可視化することができます。 単純な絵ですね... 画像は全部緑ですが 失敗したりしていると色が変わってくれます。 また、実行時間のアベレージも表示してくれて便利です。 エラーログのSlack通知 StepFunctionは基本的に大量実行に向いていないようで、ログがあまり充実していないです。 コンソールから見ることができるログも1000回までで、それ以前のログは遡れないです。 そのため、エラーが発生した時にはSlackに通知し、できるだけ早く調査対応を行えるようにしました。 クラスメソッドさんのこちらの記事を参考にさせていただきました。 Lambdaのソースコードは以下です。 Request url req. read こんな感じに通知が来ます。 最後に いかがでしたでしょうか。 割と長めの記事を書いたので、書くのも疲れましたが、最後まで読んでいただいた方々も疲れたと思います。 読んでいただきありがとうございました。 アップロード速度 肝心のアップロード速度がどうなったか気になりますよね。 こんな感じです!どーん 特定の写真で実際に計測した結果ですが、4倍速という結果になりました! 元々が少し遅めだったということもありますが、お客様には非常に好評をいただいております。 嬉しいですね。 AWS サポートの大切さ プロジェクト開始時、最初は色々と自力でなんとかしようと踏ん張っていた時期がありました。 ですが、どうしても答えが見つからなかったり、ベストプラクティス的な問題にぶち当たったり、色々な困難がある中で、勇気を出してAWSサポートへ問い合わせをしてみた結果 とても参考になるアドバイスをくれることが結構ありました。 AWSの中の人が書いた記事などのリンクまで張ってきてアドバイスをくれたり、とても親切に対応してくださいました。 さすが天下のAWSさま。 これはやばい、いち早く導入して、不安要素を取り除きたいと思います! まとめ 自己紹介が遅れましたが、私は新卒3年目の中堅? 二歩?手前の エンジニアです。 サービス成長のために、自らサーバーレスによる改善を提案し、実行させていただきました。 AWSに関する書籍や、ネット記事、AWSカンファレンスなどにも参加し、サーバーレスについてほとんど何も知らない状態から色々な情報をインプットし、成し遂げることができました。 情報取集を含めると最初に動き始めてからは半年くらいの時間をこのプロジェクトに捧げました。 実際の稼働は3、4ヶ月ほどです。 その間には、特に社内のインフラエンジニアの先輩方には非常にお世話になりました。 リリース1ヶ月前くらいからは毎日終電前まで残業に付き合ってくださいました。 この場を借りてお礼申し上げます。 また、最後まで読んでいただいた皆さま、ありがとうございます。 ぜひ少しでもお役に立てた場合は いいねを押してください!! 終わり Advent Calendar 17日目でした。 明日18日目は ryuichi fukudaさんによる記事を乞うご期待!.

次の

岸優太[King&Prince] X 爆イケ

爆イケぴえん

この記事はうるる 17日目の記事です。 はじめに この記事では、私が働いている会社、で運営しているサービス幼稚園・保育園向け写真販売サービス において、写真アップロードの速度を爆速にするためにAWSのServerlessアーキテクチャを導入したお話をします。 サービスの内容や、導入に至った経緯などもお話ししたいところですが 話がとても長くなってしまいそうなので、アーキテクチャ導入にあたって考えたことや、細かい処理の説明にのみフォーカスし、記事を書きたいと思います。 対象の読者• 画像のアップロード速度に困っている人• 画像を扱うサービスの開発を担当している人 注意点 かなり長めの記事です。 読み切るのに根気がいるかと思いますが、 いいねやストックをすることで数回に分けて読むことをお勧めします。 システム構成 一部 当アプリケーションは Laravel5系で構築されており、インフラ IaaS は主にAWSで構成されています。 webサーバーはで管理しているEC2インスタンスです。 写真の保存ストレージは、写真のサムネイルの作成は開発時にはすでにLambdaを用いて処理させていました。 DBはを使用しています。 また今回のアーキテクチャには深く関わりませんが、当サービスでは、顔写真の検索にを用いております。 移行前のアーキテクチャと構成 処理の流れ• クライアントサイドでアップロード処理を実行すると、サーバーへ写真や紐付けなどの情報がPOSTされます。 Laravel上で受け取った写真の拡張子やサイズなどが、制限内に収まっているかどうかをチェックします。 写真が正しいものと判定されたら、写真に関するデータをRDSに保存します。 写真名とか、リレーションIDとかそんな奴らです• DBへの保存後、s3へ写真をPUTします。 この際はLaravel上でS3のAPIを使用します。 S3へ写真が上がると、次はLambdaが起動します• Lambdaは、 写真のトリミングと サムネイルの作成のファンクションが順番に起動します。 移行前の課題 移行前の構成における問題点は、画像のチェックやDBへのデータ保存、S3への写真転送など、一通りの処理が終わった後にクライアントへレスポンスが返るスタイルでした。 一枚の写真だけであれば対して問題は起きませんが、流石に1日に何千何万枚という写真がアップロードされ、サーバー上でその写真の処理をしていくと、いくつか問題が発生します。 そのうちの1つが、レイテンシーの発生でした。 真ん中より左側が、サーバーレス移行前のレイテンシーです。 日常的にもそうですが、瞬間的に負荷が上がるタイミングなどでは特にめちゃくちゃ飛び出ます。 サーバー台数を増やしたり、EC2のインスタンスサイズをあげたりすればこの負荷はもう少し分散することができますが サーバーレスであれば瞬間的なアップロードにも対応でき、なおかつそれぞれの処理も速い状態を維持できるというメリットがあったので、サーバーレスの導入を検討しました。 何よりもサーバーレスを使いたかったのです。 (笑) サーバーレス化の後のレイテンシは見ての通りです。 効果は抜群でした。 新アーキテクチャ決定までにやったこと 当初、考案したアーキテクチャ まず、やりたかったことは以下です。 EC2サーバーを一切介さないというのが最大の目標として考えていました。 写真は一枚一枚が重いですし 数MB 、事業拡大とともに扱う写真枚数も右肩上がりになります。 事業拡大に負けないくらいのシステムするというのも今回の目標でしたので、 スケーラブルという魅力のあるサーバーレスに写真の処理を全任せすることを目指しました。 しかし、いくつかの障害にぶつかることとなります。 API Gatewayの問題点• 当初、API GatewayからLambdaを呼び出すことにより、サムネイルの処理を行うことを想定した。 クライアントから直接API経由で画像を送信し、そのままLambdaで処理するスタイル しかし、Lambdaの呼び出しペイロード制限 6MBに直面しました... 画像の送信サイズは20MBまであげたかったので、この方法は採用できませんでした。 DynamoDBの断念• Rekognition 顔認証 のデータ• 顔認証のデータが大量にあり、RDSのストレージを圧迫する原因となっている• Dynamo使いたい• ライブラリにより、ORMなどをDynamoでもサポートするようにはできる• 不可能ではない。 というか多分できる。 開発期間が足りない• Step FunctionとかAPIGatewayとかAuroraとか、不確定要素が多い中で 一人で進めるプロジェクト• リリース時期の目標がある中で、Dynamoの検証を進める時間が足りなそうだった 開発期間3ヶ月くらい• 何よりも優先度が低かった DynamoDBについては、完全に 使いたい欲が先行していました。 本来であれば、アプリケーション全体をサーバーレスへ対応させるため、MySQLを丸っとDynamoDBへ移行したかったですが 流石に検証期間が短すぎるため、一部だけ移行という方法を考えましたが それでも今回は優先度が低かったため、見送りになりました。 Aurora Serverlessの検討 DynamoDBは、RDS+Lambdaの相性の悪さから考えた案でしたが その次にを検討しました。 DataAPI このDataAPIという、サーバーレスにとって最高の機能を使えば大体の問題は解決すると考えました。 ただし、大問題が... ユースケース 公式ドキュメント抜粋• 使用頻度の低いアプリケーション• 新規アプリケーション• 可変ワークロード• 予測不可能なワークロード• 開発およびテスト用データベース• マルチテナントアプリケーション 開発およびテスト用データベース だと... 本番環境向きではないと、公式が示しています。 これはあかんと思い、AWSのサポートに直接聞いてみました。 すると以下のような回答が返ってきました。 本番アプリケーションの要件に合致してたら使っていいよ。 でもちゃんとテストしてね! なるほど... テストしてみて使えそうだったら使ってもいいのか。 そう思い、早速検証に入りました。 AuroraとAuroraServerlessの検証 AuroraとAuroraServerlessを対象に、サーバーレスに耐久できるかどうか検証をしました。 検証内容については本記事とテーマが少しずれてしまうため、また別の記事で紹介させてください。 結果は、 AuroraServerlessの圧勝という結果でした。 Auroraってだけあり、パフォーマンスもそれなりに高く、安定して動いてくれました。 本番環境でも問題なく動かせるのではないかという結果を導くことにも成功しました。 しかし、ここでも大きな問題が発生しました... Aurora Serverlessの開発環境 開発環境でAuroraServerlessを使おうとする際の方法は以下2つでした。 実際のAWSリソースを準備しローカルからアクセスする• Dockerコンテナで仮想的にAuroraServerlessを構築する AuroraServerlessは割と新しいサービスで、コンテナはかなり難易度が高かったため、実際のリソースを使うことにしました。 しかし、AuroraServerlessの制限でAuroraにパブリックIPを割り当てることができませんでした... 開発環境からAuroraServerlessにアクセスするには、パブリックIPを割り当てる必要があったため、これは大打撃です。 時間をかけAuroraServerlessを検証し、やっと使える!というところまできたところでこれはかなりショッキングな制限でした。 ショックすぎて、AWSサポートに問い合わせてどうにかならないか聞きましたが、ドキュメント以上のことは返ってきませんでした... そりゃそうだ、、、 AuroraServerless自体、新しいのでAWS側でも細かいところまでは回答ができないみたいだ。 Aurora Serverlessの断念 DataAPIという強力な機能のためにいろんなものを犠牲にしようとしました。 AWS新サービス特有の情報の少なさ、ユースケース外の使用、問題が発生した時はマンパワーで頑張るという覚悟。 しかし、開発環境を整えることができないという問題により選択肢から除外せざるを得ませんでした。 結果的には、特にDBのようなアプリケーションの基盤となるようなものに関しては、ナレッジの少ない選択肢を選ぶのにはリスクが非常に高いので、採用しなくて正解だったとも言えます。 この当時、精神的に色々やられましたがなんとか諦めをつけることができました。 まさに、失恋した気分でした。 というかこれで行くしかない Auroraへの移行も考えましたが、社内事情などもありながら、とりあえず現状通りRDSMySQLでトライしてみることにしました。 では実際にどのくらいの瞬間風速で同時起動数が跳ね上がるのかを検証してみました。 結果は以下でした。 現状のサービス規模であれば、コネクション問題を回避することが可能であるということが検証により明らかになりました。 このように、紆余曲折を経てアーキテクチャの決定までこぎつけることができました。 新アーキテクチャと構成 以下の画像が新アーキテクチャです。 どうでしょうか。 大まかに説明します。 まずクライアントから S3に直接写真を突っ込み、それに反応し、の ステートマシンが起動します。 ステートマシン内で、それぞれの処理をするLambdaファンクションが順々に実行されていき、DBへのデータ登録やサムネイルなどが作成され終了です。 アーキテクチャを以下の様に分解して、説明します。 長すぎて忘れてしまっていたらすみません... 実はこの部分こそが、写真のアップロード速度を爆速にできた要因となっています。 写真のアップロード速度は、ブラウザ上でsubmitしてから、レスポンスが返ってくるまでの時間です。 移行前の構成では、レスポンスを返すまでに色々な処理が走ったため、待ち時間が発生してしまっていました。 ですので、これをシンプルに S3に写真を保存したら即レスポンスにするのが理論上、最も速いです。 写真を保存するだけなら、サーバー経由でもできますが、それは最速ではないです。 S3に直接 これが最速です。 速くするからには最速にこだわりました。 速いは正義です。 ですが、S3に直接送信するためには、セキュリティの問題が存在しました。 当初などの認証サービスを使用することでセキュリティを担保することを考えましたが、このためだけに認証サービスを入れるのはお金も時間もコストがかかりすぎました。 そこで見つけたのが S3の署名付きURLでした。 参考: この署名付きURLを用いてアップロードを行うことで、セキュリティを担保しながらS3への直接アップロードを実現しました。 基本的にはSDKの使い方そのままなので非常に簡単でした。 us - east - 1. amazonaws. 詳しくは公式ドキュメントに記載してありますので割愛させていただきます。 StepFunctionsについては、色々な入門的な記事があるので、そちらを参考にしてみてください 基本的には、LambdaやDynamoDB、SQSなどのAWS各種サービスを使い、ワークフローを構築できるというサービスです。 並行処理や条件分岐、失敗時のリトライや、エラーをCatchしての処理などの機能が備わっています。 移行前のアーキテクチャでは、LambdaをS3トリガーで単一的使っていました。 そこには、エラー時に捕捉できず、失敗したらそのままにするしかない、などというサーバーレス特有の問題がありました。 StepFunctionsを使うことで、自由にリトライさせることもできますし、並列処理を用いて、サムネイルを数パターン作らせるとか、Rekognitionも同時に実行することなど、色々な処理を構築することができることが魅力的です。 ステートマシンの定義 今回は、割と単純な構成です。 各種データのDBへの保存、トリミング、サムネイル 失敗時には、レコードをエラーステータスに更新する。 といった処理を行っています。 ステートマシン定義の一部 今回構築したワークフローは比較的単純なので、最初の部分のみステートマシンの定義方法を紹介します。 ポイントは Retryの部分です。 待機時間に関しては、図中の説明の通りですが、今回のアーキテクチャ特有のエラーハンドリングが2つあります。 Lambda. TooManyRequestsException これは、急激に大量のLambdaを起動した際に発生するエラーになります。 瞬間的な負荷にも耐えなければいけないですが、こちらはAWSが制限を設けているので、ある程度仕方ないエラーです。 この場合は、ちょっとだけ時間をあけてリトライさせて回避しています。 Lambda. ENILimitReachedException こちらは、VPCのの制限です。 しかも、このENIはLambdaコンテナが消えても一定時間残り続けるので、短い時間に大量のLambdaが起動してしまうとENIが爆増し、制限に達してしまいエラーとなります。 ENIの消滅に時間がかかるので、待機時間も長めにとっています。 ただこちらは、ちょうどリリースする直前にAWSが改善してくれました。 この発表には飛び跳ねました。 このように、エラーに対して適切なハンドリングを設定できたのがStepFunctionsの魅力です。 失敗するとレコード中のエラーステータスを更新するようにしておりますが、エラーの種類によって実行Functionを切り替えて、ステータスコードを別のものにするなどもできた方がデバッグに役立ったかもしれません。 エラー内容をfunctionへ受け渡すこともできたような記憶も... CICD さて、上記で写真を爆速でアップロードするための仕組みが整いました。 ここからはCICDの仕組みの構築です。 我々エンジニアは、作ればOKという世界でありませんよね。 作ったものを安全に正確にデプロイ 世の中へ供給 する必要があります。 ServerlessFrameworkによるサーバーレスデプロイ StepFunctionsやLambdaのデプロイにはを使用しています。 サーバーレスであるLambdaはもちろんGCP、AzureなどのサービスをCLIからデプロイできるツールです。 こちらも細かい使い方は省きますが、設定ファイルである serverless. ymlの設定をご紹介します。 参考: Lambdaの定義 ここでは1つのFunctionを紹介します。 functions : storePhotoData : handler : storePhotoData. reservedConcurrency. これは、ServerlessFrameworkの機能であるカスタム変数を利用し、各デプロイ環境ごとに値をセットしています。 参考: 実際に以下のように設定しています。 db・・・RDSの接続情報• VPC・・・セキュリティグループとサブネットの情報 実は、弊社ではえんフォトと同様、写真販売サービスというのも運営しており、基本的な構成はえんフォトと同じなので、同時にデプロイできるようにしています。 えんフォトとクラプリ、本番・ステージング・開発環境でそれぞれ別の値をセットしたいため、カスタム変数を使っています。 都度、OS上の環境を読み込むため、基本的にはCircleCIの環境変数に事前にセットしておくことでデプロイします。 また、 tracing: Active にも注目です。 後述の監視で紹介しますが、を有効にするための設定です。 StepFunctionsの定義 Serverless FrameworkはデフォルトでStepFunctionsが使えないので以下のプラグインを入れることで対応します。 stepFunctions : stateMachines : enphotoSpica : events : - cloudwatchEvent : event : source : - aws. s3 detail-type : - AWS API Call via CloudTrail detail : eventSource : - s3. amazonaws. TooManyRequestsException 呼び出し頻度のエラー IntervalSeconds : 5 MaxAttempts : 5 - ErrorEquals : - Lambda. ENILimitReachedException ENIの制限エラー IntervalSeconds : 30 MaxAttempts : 2 - ErrorEquals : - States. ALL IntervalSeconds : 1 MaxAttempts : 3 Catch : - ErrorEquals : - States. error Next : updatePhotoDataToError Next : Trimming 基本的には、ステートファイルの定義をyaml形式に変えたものになります。 CircleCIによる自動デプロイ ServerlessFrameworkの準備ができたら、CircleCIで自動デプロイをするようにします。 0 cd. デプロイは以下のように行います。 CircleCIの適切な場所でコマンドを実行してください。 監視 さて、サーバーレスの実行、そして自動デプロイまで整いCIのための基盤は整いました。 ここからは、それを正しく運用するための監視基盤を紹介します。 それほど大したものではありませんが AWS X-Ray LambdaにX-Rayを簡単に導入できるため、お試しの意味も込めて導入しました。 Lambdaのエラーなどを可視化することができます。 単純な絵ですね... 画像は全部緑ですが 失敗したりしていると色が変わってくれます。 また、実行時間のアベレージも表示してくれて便利です。 エラーログのSlack通知 StepFunctionは基本的に大量実行に向いていないようで、ログがあまり充実していないです。 コンソールから見ることができるログも1000回までで、それ以前のログは遡れないです。 そのため、エラーが発生した時にはSlackに通知し、できるだけ早く調査対応を行えるようにしました。 クラスメソッドさんのこちらの記事を参考にさせていただきました。 Lambdaのソースコードは以下です。 Request url req. read こんな感じに通知が来ます。 最後に いかがでしたでしょうか。 割と長めの記事を書いたので、書くのも疲れましたが、最後まで読んでいただいた方々も疲れたと思います。 読んでいただきありがとうございました。 アップロード速度 肝心のアップロード速度がどうなったか気になりますよね。 こんな感じです!どーん 特定の写真で実際に計測した結果ですが、4倍速という結果になりました! 元々が少し遅めだったということもありますが、お客様には非常に好評をいただいております。 嬉しいですね。 AWS サポートの大切さ プロジェクト開始時、最初は色々と自力でなんとかしようと踏ん張っていた時期がありました。 ですが、どうしても答えが見つからなかったり、ベストプラクティス的な問題にぶち当たったり、色々な困難がある中で、勇気を出してAWSサポートへ問い合わせをしてみた結果 とても参考になるアドバイスをくれることが結構ありました。 AWSの中の人が書いた記事などのリンクまで張ってきてアドバイスをくれたり、とても親切に対応してくださいました。 さすが天下のAWSさま。 これはやばい、いち早く導入して、不安要素を取り除きたいと思います! まとめ 自己紹介が遅れましたが、私は新卒3年目の中堅? 二歩?手前の エンジニアです。 サービス成長のために、自らサーバーレスによる改善を提案し、実行させていただきました。 AWSに関する書籍や、ネット記事、AWSカンファレンスなどにも参加し、サーバーレスについてほとんど何も知らない状態から色々な情報をインプットし、成し遂げることができました。 情報取集を含めると最初に動き始めてからは半年くらいの時間をこのプロジェクトに捧げました。 実際の稼働は3、4ヶ月ほどです。 その間には、特に社内のインフラエンジニアの先輩方には非常にお世話になりました。 リリース1ヶ月前くらいからは毎日終電前まで残業に付き合ってくださいました。 この場を借りてお礼申し上げます。 また、最後まで読んでいただいた皆さま、ありがとうございます。 ぜひ少しでもお役に立てた場合は いいねを押してください!! 終わり Advent Calendar 17日目でした。 明日18日目は ryuichi fukudaさんによる記事を乞うご期待!.

次の