AWS
lambda

AWS Lambdaを使うときに注意する4つのこと -> 3つになりました

More than 3 years have passed since last update.


Lambda

AWSにLambdaがローンチされて早1年がすぎ、いろいろなところでLambdaを使ったという話を聞くようになりました。

そんなLambdaですが、使うときに注意しなければならないことがいくつかわかってきたので、整理しておきたいと思います。


AWS Lambdaとは

なんでしょうか。簡単に確認しておきましょう。

AWSのページ( https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/welcome.html )を見ると


  • AWS Lambda は、コードを AWS Lambda にアップロードすると、サービスが AWS インフラストラクチャを使用してコードの実行を代行するコンピューティングサービスです。

と、書いています。

通常、サーバ側でなんらかの処理をするためには、EC2上でアプリケーションを動かして、そこで処理をすると思いますが、LambdaはEC2を使わずに、リクエストを処理するサービスです。

最近はやりのサーバレスアーキテクチャでシステムを構築するときに、非常に有効なサービスです。

また、Lambdaを利用することで、あまりアクセスがないときにEC2のインスタンスが無駄に起動していたり、念のため2台稼働するような必要もなく、コストメリットもあります。

さらに、EC2で構築すると、アクセス数から必要な台数を予想して起動したり、アクセスが増えた時にAutoScaleを使って台数のコントロールをしますが、Lambdaはそれを気にする必要がありません。AWSがすべて自動的にやってくれるので、安心です。


注意すること


その1、Javaが遅い

Lambdaがローンチされた時、使える言語はNode.jsだけでした。

その後、2015年5月にJavaが使えるようになりました。(さらに2015年10月にPythonも使えるようになりました。)

JavaでLambdaを実行できると、過去の資産がたくさん利用できたり、既存のシステムを移行しやすいなど、喜んだ人も多いのではないでしょうか。

ただ、Javaで動作させるとおそい(というか処理時間にばらつきがある)です。

Node.jsだと数10msで実行完了する処理が、Javaだと数10msから数100msかかる場合もあるようです。

原因を探っていくと、Javaのクラスをロードするのに時間がかかっているようです。

Lambdaのインスタンスが再利用された場合は早いのですが、新たにロードする場合は時間が余計にかかってしまうのです。

せっかく、時間単位の課金で金額が削減できるのに、JavaだとNode.jsに比べてコストがかかってしまうことがあり、効果が薄まってしまいます。

なので、どの言語で実装するかの検討は注意が必要です。(ごめんなさい、Pythonでは試していません)


その2、制限

Lambdaで動くインスタンスにはメモリの制限があります。

128MB〜1.5GBまで、64MB単位で使用するメモリ量を指定できます。違う言い方をすると、1.5GB以上のメモリが確保できないということです。メモリが大量に必要になる処理だとメモリを確保できずに、Lambdaが使えないこともあります。

また、処理時間の制限もあります。

処理がタイムアウトになるまでの時間を指定します。(最大300秒)

こちらも同様に、300秒以上かかる処理の場合、Lambdaが使えないので、普通にEC2で実現する必要があります。


その3、失敗時に3回リトライしてくれる

理由2と繋がるのですが、Lambdaの処理に失敗した場合、3回自動的にリトライしてくれます。

Lambdaがリトライする条件として、その2で書いたメモリ不足や、実行時間のタイムアウトが発生した場合や、Lambdaの処理が失敗した場合もリトライします。

Node.jsの場合、context.fail()を呼び出した場合、処理が失敗したと判断します。再実行してほしい場合は良いのですが、再実行しても失敗するような場合、context.fail()を呼び出してしまうと、リトライされてしまうので、注意が必要です。実行回数や時間が追加されてしまうので、コストも無駄になってしまいます。

このような場合は、context.done()を呼び出すと再実行せずに終了します。


その4、VPCの中に入れない

VPCの中に入れないということはどういうことでしょうか。

単純にLambda内で処理をするだけであれば問題ないのですが、AWS内の他のサービスにアクセスするときに問題になります。

わかりやすい例でいうと、処理結果をDBに格納したい場合、どうなるでしょうか。

AWSのRDSでDBを構成している場合、RDSはVPCに入っているのですが、LambdaはVPCに入れません。LambdaからRDSにアクセスするためには、セキュリティグループで、すべてのIPアドレスから受け入れるようにする必要があります。

。。。。。。。。。。。

いやいやいやいや、それはないでしょー!!

超暫定対策としては、Lambdaが取りうるIPアドレスすべてをセキュリティグループに追加する事がありますが、AWS内からは誰でもアクセスに可能になってしまいますし。。。。

いやいやいやいや。

もう少しちゃんとした対応をするならば、Lambdaの中で自分のIPアドレスをセキュリティグループに追加して、終わる前に外す処理をすることで対応できると思います。。。。。。

めんどくさい。

これはAWSも把握していて、対応すると言っています。(re:Invent2015の時に「年内に対応する」ということだったのですが、2015/01/18時点ではまだ対応されていません。)

つ、ついに、AWSで対応されました!(詳しくはこちらを見てください -> http://aws.typepad.com/aws_japan/2016/02/access-resources-in-a-vpc-from-your-lambda-functions.html)


まとめ

とのように、いくつか課題がありますが、きちんと使えばとても便利なサービスであることに変わりはありません。

ぜひ、チャンスがあれば使ってみてください!