Edited at

DynamoDBを使うサーバーレス設計で失敗した

More than 1 year has passed since last update.

DynamoDBを使うサーバーレス設計を使ったときに失敗したことがあったので書きます。

なお、この体験はハッカソン等での個人の体験であり、 実サービスとは関係ありません。

また、関わったエンジニアの方々を馬鹿にしたいわけでなく、同じ失敗を繰り返さないために自分用のメモとしても載せております。


わかること


  • DynamoDBを使うサーバーレス設計を利用するときの失敗例から導入すべきかどうか

  • 料金や工数は本当に下がるのか


要件


  • 投稿があったらその投稿にメールを返信したい

  • SNSログインもある

  • 件数は無限に多いと予想

  • Railsのomniauthとアクションメーラーでも良かったが、「サーバーサイドの負荷が楽になる+かっこいい」という理由で選択


    • Lambdaに任せるとスケールを自動でやってくれる

    • フルマネージドなので、サーバー運用管理、保守や障害時の対応など、システム管理をしなくて良い

    • オートスケーリングの設定やサーバーの保守をやりたくなかった(工数削減)

    • 投稿がないときは料金がかからない(EC2インスタンスを構えて置く必要がないが、DynamoDBはかかる)

    • サーバーレス設計ってかっこいい




実装作戦


  • APIGateway + Lambda + DynamoDB でフルマネージドなサービスとして実現、ServerlessFrameworkでコードで管理する (参考: serverless frameworkを使って本格的なAPIサーバーを構築(魅力編))

  • SNSログインは、DynamoDBにセッションを保存してCookieと組み合わせて、CallbackURLを用意しておくだけで実現できる

  • DynamoDBストリームを使って、putされたらメール送信

  • 管理画面がないので、今putされている件数を毎日10時にgoogleSheetに書き込む

  • DynamoDBのバックアップを毎日5時に、DataPipelineを使ってS3に保存する <- これがあかんかった

  • 気をつけるのはキャパシティユニットの計算のみ <- これもあかんかった

  • あとは、フロントでAPIを叩いてもらうだけ


失敗したこと(1) 負荷試験編

~時系列で説明します~


  • 1, 負荷試験を終え、DynamoDBに数万件のデータが溜まった状態で、キャパシティユニットを最小に下げる

  • 2, DynamoDBのバックアップを毎日5時に、DataPipelineを使ってS3に保存する これが、キャパシティユニットを最小に下げたことにより、一瞬で終わらなくなった


    • t2.xlargeのEC2インスタンスが一瞬立ち上がって消えていたみたいだが、立ちっぱなしになってしまった



  • 3, 気づかず放置していたためt2.xlargeのEC2インスタンスが大量発生!!!

  • 4, 莫大な請求金額へと跳ね上がる


失敗したこと(2) キャパシティユニット編

~時系列で説明します~


  • 1, 本番公開前の練習として、動作確認を担当者に依頼

  • 2, 本番時のキャパシティユニットはこちら!!というコメントを担当者がみつけたので、そのとおり設定


    • ServerlessFrameworkを利用していたため、serverless.ymlに該当のコメントがあった

    • 実際には、投稿されるであろう文字の最大文字数(20項目最大500文字)をすべて入力された状態でも耐えられる数字だったので、当日の本番はもっと抑えた数字でローンチする想定だった

    • DynamoDBのキャパシティユニットは、上昇させてから減少させると、スペックが変わってしまうので、最初から上げるのは無能である



  • 3, 無事、本番環境公開の練習が完了

  • 4, 担当者がそれを下げ忘れる(オペミス + キャパシティユニットの料金の理解不足)

  • 5, 数日放置

  • 6, (1)よりも莫大な請求金額へと跳ね上がる


まとめ


  • DynamoDBを使うサーバーレス設計は、フルマネージドなサービスであるがゆえにとても便利ですが、予備知識がないと膨大な料金がかかってしまうことがある

  • DynamoDBの知識はある程度持っておいたほうが良い、とくにキャパシティユニット

  • フルマネージドであるがゆえに、それぞれの管理画面が別にありどういう経路でどのFunctionが使われているかなどを把握しておかないといけない

  • CloudWatchLogでのログ反映が若干おそいので、少しやりにくい

  • 実装工数は、Railsで実装したほうが削減できたと思う

  • スケーリングもある程度は任せられるが、キャパシティユニットの調整はローンチしてからある程度見守りが必要だと思う


合わせて