サーバーレス開発の失敗例と解決方法 FaaS特有の落とし穴とは?

前回の記事では『サーバーレス開発のメリット・デメリット』についてご紹介しました。
サーバレスアーキテクチャには数多くのメリットがありますが、一方で、気をつけなければいけない点も多々存在します。

今回の記事では、実際にサーバレス開発を行った際、起きたトラブルや解決法についてご紹介します。
もしこれからサーバレスを触ってみようとされている方は、ぜひ一読されて、落とし穴にはまることが無いよう役立ててください。

目次

本書で出てくる言葉の定義

  • 関数:AWSのLambdaやGCPのCloud Runを指す。1つの処理を行う固まり
  • 機能:AWSのS3やRDS、GCPのCloud StorageやCloud SQL

失敗1:ベンダーロックインがすごい

とあるシステム開発を受注した際のことです。
そのシステム自体は何度か開発した経験があり、いずれも「AWS Lambda」を利用していました。
今回は先方の希望で「GCP」を使うこととなったのですが、
「Lambda」で使っていた機能を「Cloud Run」上で探したところ、似たような機能があったので、「問題ないでしょう」と軽く返事をしてしまいました。

……しかし実際に作業をし始めると、見通しの甘さを痛感します。
ただのサーバ移管とは訳が違うのです。
LambdaならLambdaの書き方、Cloud RunならCloud Runの書き方でプログラミングする必要があります。
結果、想定していた時間より、多くの時間を割くはめになりました。

対策:関数間の移行は大変!移行しない、もしくは相応のコスト計算を

サーバレスは大変便利ですが、LambdaならAWSへ、Cloud RunならGCPに依存することとなります。
もし移行を相談された場合は、相応のコストを見積もりましょう。

もちろん予め移行可能な形に対策を取っておく事もできますが、その場合、そもそもサーバレスを利用するメリットが薄れるかもしれません。
前回の記事でも書いた通り、『サーバレスに適したシステムか』という見極めが大切です。

失敗2:パフォーマンスがでない

サーバレスで開発を行った際、動作速度について問題を感じることはほぼないでしょう。
それぞれの機能に最適化されている分、下手なサーバよりも俊敏に動いてくれます。

しかしながら、サーバレスの動作時間には特有の問題があります。
前回の記事でも取り上げた『コールドスタート』の問題です。

常時待機状態にある一般的なサーバアプリと違い、
サーバレスアーキテクチャは、必要なときだけ起動します。
なので数分間利用しないだけで、機能が休眠状態に入り、次に動作する際余分な時間がかかるのです。
(更に「コンテナ初期化」「スケーリング処理」等の際も同じく時間が掛かります)

この使用のおかげで常駐サーバよりも安いコストで運用することが可能になるのですが、
気づかないままシステムを運用すると、テスト時にはまったく問題なかったシステムが、ものすごく時間がかかったり、時にはエラーを起こすようになるかもしれません。

対策:即応が必要な場合はサーバレス以外を使う。関数によっては対策機能が用意されている場合も

もしあなたの作りたいシステムが1秒・2秒の遅れも許されない、シビアなものの場合は、サーバレスを使わずに構築した方が良いかもしれません。

また、java等を使いたい時も、サーバレスは向いていないでしょう。
例えばLambdaでjavaを利用する場合、
リクエストを受けたLambdaは、コンテナを新しく作り、コードをロードし、変数を初期化します。この動作に時間がかかる上、リクエストの度にこれを繰り返すのです。

これでは時間が掛かり過ぎて、ユーザビリティを著しく損なってしまうでしょう。

なお関数によっては、このコールドスタートを回避できる仕組みが用意されています。
例えばAWS Lambdaなら「SnapStart」、GCPなら「CPU Boost」という機能です。
これらを使うなら、コールドスタートの問題は幾分かマシになるかもしれません。

失敗3:各関数・機能のバージョン管理が煩雑になる

前回、「サーバレス」は『サーバの管理がいらない』と書きましたが、「全てをお任せできる」訳ではありません。

特に「バージョン管理」の部分は複雑です。
例えばLambdaを利用している場合、まず各関数のバージョンがあります。
更にRDS等を利用していれば、その機能のバージョン
その上でMySQL等を利用している場合は、それらランタイムのバージョンも管理しなければなりません。
更にライブラリのバージョンや、連携している他のサービスやAPIのバージョン……まで考え出すと頭が痛くなりますね。

設定上は、全て最新のものになるよう「自動更新」を掛けることもできます。しかし、複数の機能を連携させている場合、バージョンが違うだけで
エラーが起きるかもしれません。

「シンプルなコードのアプリ」や「一時的に故障しても問題ないシステム」以外ではあまりおすすめできません。

対応:バージョンを揃える必要がある部分は洗い出しておく。更新作業の時間を盛り込む。

開発の段階で、バージョンの管理が必要なランタイム等は予め洗い出しておきましょう。
そうすれば、更新作業にそこまで時間を割く必要がなくなります。

あとは、定期的に更新作業の時間を取りましょう。
保守を請け負うのであれば、その時間もしっかりと見積もりに組み込むべきです。
(多くの場合、ランタイムの更新はマネジメントコンソールで行えるので、IaaSのランタイム更新より短時間で済みます)

失敗4:アプリ・システムの全体像が掴めなくなる

サーバレスは現在非常に注目されているため、各ベンダーが日々、新機能の開発を行っています。
そのため関数や機能をふんだんに用いて、複雑なアーキテクチャを構築することも不可能ではありません。

しかしながら、大量の関数や機能を利用した場合、その連携を把握するのは大変です。
「Aという機能で利用しているデータベースをいじったら、実はBという機能でも使っていてエラーが起きていた」ということもありえます。

エラーが起きた後も、すぐに原因が特定できればいいのですが、
もし全体像が掴めていない場合、そもそもどのエラーログを見ればいいのかすら、わからないかもしれません。

更に「チームで作業する場合」や「他の人が作ったアーキテクチャに手を入れる場合」は問題が深刻化するでしょう。

対応策:ドキュメントはしっかり作る。モニタリングサービスの利用も

サーバレス開発でもドキュメントはしっかり作りましょう。
「面倒だから……」と後回しにした場合、トラブルが起きて締まるのは自分の首です。
構成要素や関数間の連携、データの流れをきちんと記録しておきましょう。

また、サーバレスのモニタリングを行なう専用のツール(DATADOG・Site24x7等)も提供されているので、複雑なアーキテクチャの場合はそちらの利用も検討してください。

失敗5:長時間の処理ができなくなる

サーバレスでよくある問題として「実行時間」の制限があります。
例えばAWS Lambdaであれば、1つの関数あたり「15分」以内に処理を終わらせなければ、自動的にタイムアウトとなります。
(なお2018年までは5分でした)

もし開発段階で15分を超えるのであれば、何らかの対策を取る必要があります。
例えば1つの関数で行っていた処理を並列化したり、サーバレス以外の方法を取ったり、といった対策です。

しかし問題なのは「ずっと問題なく運用してきたシステムが、ある日15分を超えてしまった」場合です。

例えばデータベース内の記録から統計を出すプログラムを、サーバレスを用いて作ったとします。

最初は数秒で処理が終わるかもしれません。
しかしデータベースが膨らんで来たらどうなるでしょうか?
いつの間にか15分で終わらない処理になっているかもしれません。

対応策:将来的に実行時間の制限を超えないよう、予め対策しておく

前述の例でしたら、過去の統計は予め数値を出しておき、直近の計算だけを行なう方法等に変えられるかもしれません。
また、統計の範囲を過去1年まで等に制限することでも対応できるでしょう。

なお多くの場合、「実行時間」だけでなく、「同時実行数」にも制限があります。
「実行時間に引っかかるから……」と、処理をどんどん並列化していくと、今度は同時実行数の制限に引っかかるかもしれないので、注意してください。

失敗6:データサイズにより利用できなくなる

また先程と同じく「データサイズの上限」にも注意しましょう。

例えばLambdaのペイロードは6MBが上限です(同期の場合。非同期は256KB 引き上げ不可)

LambdaのAPIに対して画像データを送信するとしましょう。
手元にあった500kb程度の画像で問題がなかったとしても、
スマホの高画質モードで撮った画像ならば、6MBを超えてしまうかもしれません。

これも「開発時に問題がなかったにも関わらず、ある日エラーを起こす」要因です。

対応策:圧縮やファイルシステムの利用を

もし「少しだけ上限を超えることがあるかも」という事態であれば、圧縮で対応できるかもしれません。
gzipの利用や、画像サイズの変更等で上限をクリアできるでしょう。

動画や音声ファイルの場合、6MBに納めようとするのはあまり適切ではありません。
AWSならばS3、GCPならCloud Storage等に一旦アップし、それから処理を行うことで、データサイズの上限を回避することができます。

サーバレスは『使いこなせれば強い!』

ここまでサーバレスでよくある失敗例や、対応策等を記述してきましたが、
IaaSやPaaSに慣れている人にとっては「かえって面倒くさい」と感じてしまうかもしれません。
実際それらと比較すると、サーバレスには色々な制限があるため、思い通りにいかないこともあるでしょう。

しかしながら、サーバレスは使いこなせれば最高にコスパのいい道具です。
適切な場面で、適切な関数・機能を用いることができれば、長期に渡って少ないリソースでシステムを管理できます。

なお、サーバレスに関するスキルの習得が大変なのも事実です。
ベンダーごと、関数ごとに、機能毎に仕様やUIが異なりますし、歴史の浅い関数ではドキュメントも揃っていません。

もし単発のプロジェクトの場合は、開発部分を外注するのも手です。
適切な利用法であれば、開発時のコストを差し引いても、十分に元が取れるので、ぜひそちらも検討してみてください。

お問合せ&各種リンク

presented by 

よかったらシェアしてね!
  • URLをコピーしました!
目次