はじめに
下記記事の続き。
サーバレスは銀の弾丸ではないので、考慮すべき点を少しまとめた記事。
サーバレスの導入時の考慮点
1.コールドスタート問題
一定時間アクセスがない関数はコールドスタート
状態となり、最初の実行時に起動時間が長くなります。
2.ベンダーロックイン
特定のクラウドプロバイダーの仕様に従った実装だと、今後プロバイダー間での移行が困難になる場合があります。
急に経営層が、「AWSでいいんだっけ?」みたいなことを言い出したりすることも。
3.コスト管理の複雑さ
従量課金制のため、トラフィックが予測困難な場合、コストの見積もりが難しくなります。
以下のようなケースで、予期せぬ高額請求が発生するリスクもあります。
- 予期せぬ大量のリクエストが発生した
- 開発者が意識せずに大量にリソース消費した
- 無限ループなどの不具合が発生した
4.各種リソースの制限
メモリやCPU、実行時間などのリソース使用量に制限があります。
実行時間で見てみると、各CSPごとに以下のような感じでした。
(AIに聞いてます)
AWS Lambda:
同期実行: 最大15分 (900秒)
非同期実行: 最大15分 (900秒)Google Cloud Functions:
1世代 (1st gen): 最大9分 (540秒)
2世代 (2nd gen): 最大60分 (3,600秒)Azure Functions:
消費プラン: 最大10分 (600秒)
プレミアムプラン: 最大60分 (3,600秒)
専用プラン: 最大無制限Cloudflare Workers:
無料プラン: 最大10ミリ秒
有料プラン: 最大30秒
AWSしか知らなかったので、少しびっくりしましたが、他のCSPは60分とか無制限とか、かなり長く設定できるんだなぁ。
その他Lambdaの場合、メモリは128MB〜10GBのメモリを選択可能。
ディスク容量も/tmp
は512MBの制限。
特定の分野における大規模な計算処理や大量のメモリを必要とする処理には適してはいません。
5.状態管理の複雑さ
サーバレスで構築する場合、ステートレスに構築していくことになりそうですが、状態の保持が必要になった場合、追加の対応が必要です。
対処法
1.コールドスタート問題
この問題が顕著に現れるのは、Java(特にSpring Boot)や.netなど起動に時間がかかる言語。
まずは、軽量な言語やフレームワークの選定をするのが良いと思います。
メンバーのスキルセットでJavaしかできない!みたいなことも多くあるのですが、Lamdbaだと、snap start
という高速化技術があります!
あとシステム提供側が一定周期でサービスを叩く、ウォームアップリクエストの実装も有効みたいです。
ウォームアップリクエストを何分周期で実施すべきかは、別記事で調べてみたいと思います。
2.ベンダーロックイン
AWSのホワイトペーパーがとても参考になりました。
このホワイトペーパーでは対処法として、以下を挙げています。
- データ移行サービスの利用
- コンテナ技術の利用
- VMware on AWS
- DevOpsツール
ただし、AWSでは、「選択の自由はお客様にある」としていて、お客様がいつでも任意の別のベンダーに変更することができる各種ツールやサービスを提供しているとのことです。
またロックインを考える時は移行コスト(スイッチングコスト)も併せて考えるべきだとしています。
例えば、JavaからNodeJSへの移行は、単純に移行コスト(スイッチングコスト)が発生しているのみで、ロックインではない、としています。
何か特定の技術を選んだ時点で、移行コスト(スイッチングコスト)はかならず発生します。
長期の契約などで変更ができない、極端に移行が困難となるような仕組みになっている。みたいな状況をロックインと呼ぶべきなのかもです。
CSP含む技術選定の際には、技術面・契約面の両面でロックインが生じないように、移行コスト(スイッチングコスト)を評価することも重要です。
3.コスト管理の複雑さ
コストのモニタリングをするべきです。
見積もり時に決めた予算の閾値を超えた、とか普段はないコストの上昇があったなどにアラートが上がる仕組みを設けると良いと思います。
AWSでは、AWS Budgetsで予算管理できます。
日々のコストをモニタリングしたい場合は、以前紹介したこんな仕組みも良いかもです!
4.各種リソースの制限
非同期処理や、ステートマシンを活用していくのが良いと思います。
また、FaaS系サービスではなく、コンテナサービスへの移行なんかも場合によっては良いかもです。
AWSで言うと、15分未満で済むバッチはLambdaを使い、それを超える場合は、ECS Scheduled Tasksを使うなどの手法がありそうです。
5.状態管理の複雑さ
DynamoDB等の永続化ストア、Step Functionsを使ったステートマシンの活用がありそうです。
またAIに聞いて初めて知りましたが、イベントソーシングパターンの導入なんかも良いと思います。
一連のイベントを全て永続化しておくことで、任意の時点におけるアプリケーションの状態を特定することもできそうです。
最後に!
この記事、色々調べることがあってかなり時間かかってしまいました。
強みも弱みも知った上で利用するのが一番ですね!