2018年4月20日金曜日

【AWS Lambda】課金体系解説【無料枠】

株式会社ジェニシス 技術開発事業部の遠藤 太志郎(Tacy)です。

最近、AWSをフル活用して社内システムを作ったので、そのノウハウのご紹介を行っています。

今回はAWS Lambdaの料金解説です。

手始め

クラウド環境を使う人が真っ先に気にするのは、やはり料金ではないでしょうか?

クラウド環境が活用される理由の第一はやっぱりコストで、コストパフォーマンス良くランニングしたい人の為のサービスですから。

しかしながら、クラウド環境のコストは千差万別。
普通のレンタルサーバの場合は月々いくらの定額制が多いですが、クラウド環境は従量課金制であることが多く、「従量課金ってのは、具体的にどういう計算になるの?」という所が非常に難しいです。

特にAWSは数あるクラウド環境の中でも課金体系が複雑な方だと言われており、これはAWSの欠点の一つだと言えるでしょう。

ともかく今回はLambda部分の課金についてご説明です。

GB-秒課金

こちらがLambdaの料金の公式ページです。


そこにはこう書かれています。

Lambda では 1 か月に 1,000,000 件の無料リクエストおよび 400,000 GB-秒のコンピューティング時間が無料利用枠となっています。

400,000 GB-秒のコンピューティング時間って何ぞや???

普段は余り耳にしない独特の単語が出てきました。

  • GB-秒
  • コンピューティング時間

これを分かり易い言葉に置き換えると、こういうことなんです。

  • インスタンスのメモリ×実行時間

つまり「AWS内のメモリを累計でどれだけ消費したか?」で課金されるという意味になります。
以下の青色の面積が課金対象です。


インスタンスのメモリ

「インスタンスのメモリって何のこっちゃ?」という方もいらっしゃるかもしれないので、Lambdaの画面の一部を切り抜いてお見せしましょう。

以下のように、Lambdaコンソールの「基本設定」蘭にメモリを指定する項目があります。これがインスタンスの設定メモリです。




一番小さい設定で128MB、一番大きい設定で3008MBになります。
(何故3008MBなどという中途半端な値なのかは不明)

課金基準は「インスタンスのメモリ×実行時間」なので、このメモリのサイズに正比例して料金が上がっていくことになりますね。

ここでお分かりになると思いますが、Lambdaはメモリが小さいほど正義なインフラという意味になります。

通常のサーバの場合、「メモリが8GBなら8GBをフルに使わないと勿体ない」という発想で、積んであるメモリをキッチリ使い切ることが芸術です。

そこがLambdaは全然違って、メモリの正比例でお金がかかっていきますから、可能か限りメモリを少なく済ませることが財布に直結するという、プログラマーの腕の見せ所なインフラなのです。

従って、採用する言語もメモリを余り使わない言語の方が優れているということになり、メモリを大量消費する言語であるJavaはLambdaとの相性が最悪です。

私のエンジニアとしての経歴はJavaを起点にしていますが、来るべきクラウド時代を考えるとJavaのみしか使えないエンジニアは活躍の場所が限られると考えています。

「Javaエンジニアは、主力言語はJavaのままでも良いが、補助としてもう一つ言語を覚えるべき」

という私の持論はここに起因しているわけです。

インスタンスの実行時間

インスタンスの実行時間はそのまま、処理が開始されてから終了されるまでの時間です。

  • 1秒で処理が完了したら、1秒を課金。
  • 3秒で処理が完了したら、3秒を課金。

プログラムの速さが料金に直結してくるという、やはりプログラマーの腕の見せ所なインフラなのです。

課金は秒単位で行われます。
どういう意味かと言いますと、昔は

  • 課金は時間課金。
  • インスタンスを30分使っても課金は1時間。
  • 1秒使っても1時間分の金を払いやがれ!!

というカツアゲみたいな課金体系でしたが、クラウド黎明期はこれでも凄いことだと言われていたそうです。
今は1秒単位なので、随分効率が良くなりましたね。

しかし、プログラマーとしては結構キツいなぁ。

「この処理、今は3秒かかっているけど、工夫すれば2秒になるんじゃない?」

とか言われちゃうってことでしょ?
キッツ~。

あと、当たり前ですが、アクセスが殺到してインスタンスが複数立ち上がったら、その正比例でコンピューティング時間に追加されていきます。

無料範囲

こう考えると「400,000 GB-秒のコンピューティング時間が無料利用枠」という意味も分かってきますね。

メモリが128MBの場合、

  • 400,000(GB・秒) ÷ 128(MB) = 3,125,000(秒) = 868時間 = 36 日

という計算になりますね。
だから、立ち上がるインスタンスが1コならずっとタダで使えるってことになります。

しかし、処理の都合でメモリは最低でも1280MBは欲しいとなってくると、この場合だと3.6日ということになります。

短いような気もしますが、ここで忘れてはいけないのは、あくまで「処理時間」ということです。
アクセスが来ていない時間帯は処理していませんので料金は発生しません。
Lambdaは、

  • アクセスが来ていない時は寝ている。
  • アクセスが来たら起きて処理して終わったらまた寝る。

という挙動ですからね。

サービスとしては24時間立ち上がっていても、サーバとして処理している時間が短いシステムであれば、3.6日というのはまあまあの無料枠を貰えていると考えて良いのではないでしょうか?

なかなかお得なインフラです。

手始め

引き続きLambdaの連載を継続します。

2018年4月11日水曜日

【AWS Lambda】帳票出力API開発 その2~RDBMSを使うな~

株式会社ジェニシス 技術開発事業部の遠藤 太志郎(Tacy)です。

最近、AWSをフル活用して社内システムを作ったので、そのノウハウのご紹介を行っています。


前回に引き続き、AWS Lambdaのご紹介です。

特徴3:RDBMSを使うな

特徴3は重大です。

  • RDBMSを使ってはならぬ。

とだけ言うと語弊があるので、ここは詳しく説明していきましょう。

RDBMSとは

RDBMSが何かということは、各自でwikipediaでも見て貰えば十分かと。
リレーショナルデータベースマネジメントシステム、つまり普通のDBです。

  • Oracle
  • MySQL
  • PostgreSQL

これを使うな、とは過激な話です。

「DBを使えないシステムなんて実質役に立たないだろ!!」

と思う人も多いはず。
これには理由があるんです。

それは「コネクション」です。

コネクションの概念

通常のWebシステムの場合、まずWebシステムのインスタンスが起動し、そこからRDBMSに対してコネクションを張ります。

この時、「SQLを発行する都度、コネクションを張る」という挙動をするシステムは基本無いです。
(大昔のへっぽこシステムなら分かりませんが)

  • Webシステム起動時に一定数のコネクションを確保し、それを使い回す。

これが基本……と言うか、これ以外選択肢は無いと思います。

コネクションをいくつ取るかはアプリ側に任されていて、RDBMSは上限数までは要求されるだけ張るようになっています。



上の図はコネクション数5をイメージしています。

これはつまり、同時にSQLを実行できるのは5つまで。
6つ以上のSQLが発生した場合、5つに収まらない分は待ちになります。

よくある障害発生のパターンとして、SQLがコネクションを使ってそのまま開放しないというものがあります。
これをやられるとシステム全体のSQLが止まってしまうので、インスタンスの緊急再起動をさせることでコネクションを切って張りなおすことで回復させるのが常套手段です。
(DBまで再起動する羽目になったら目も当てられませんが)

上の図はインスタンスが一台のイメージでした。
では、ロードバランサーとかを使って、APサーバが2台ある構成のイメージを見てみましょう。


はい。
説明するまでも無いと思いますが、コネクションが2倍に増えました。

  • インスタンス毎にコネクションを確保する。

それがシステムの基本です。
ここにLambdaの罠があります。

Lambdaの特徴

Lambdaは以下が特徴のサービスです。

  • 処理が無い時はインスタンスが寝る。
  • 処理が増えた時はインスタンスが増える。
  • 処理が激増した時はインスタンスがガンガン増える。

そろそろお分かりになってきたでしょうか。

Lambdaはインスタンスの動的増減に価値を持っているサービスです。

しかし、インスタンス毎にコネクションを張るという物理的な制約は変わらない。
つまり、コネクション数が無限に増えるという仕様なのです。


この有様です。
イナゴとしか言いようがありません。

  • LambdaとRDBMSは相性が悪い。

これは覚えておかなければなりません。必須知識です。

使って良い場合

でも、カラクリが分かれば使えるシチュエーションもあることも分かるでしょう。

「インスタンスが無限に増えた時にRDBMSがボトルネックになる」が問題の核心部分ですから、インスタンスの数が制御されていれば問題にはなりません。

  • Webリクエストをトリガーとしてインスタンスを起動する場合はインスタンスがどれだけ増えるか分からないから絶対に使ってはいけない。
  • 定期バッチのように、インスタンス数がコントロールされている場合は使える。

これは大変重要な部分です。
覚えておいてください。

本システムの場合

本システムでは、Lambdaは帳票出力APIとして使用しています。
帳票出力に必要な情報は外部から全部JSONで貰うという仕様にしました。
DBにはアクセスしていません。

これが解決策なのです。


  • 必要な全データをリクエストから取得し、そのままDBを使用すること無く処理が完了する機能には最強!!


帳票出力APIにLambdaをチョイスしたのは我ながら名案です。

オマケ:それでもDBを使いたい

そんな制約がありながらも、それでもLambdaの拡張性や効率は魅力的です。

  • アクセスが少ないシステムの場合は、インスタンスが寝ているからタダで使える。
  • アクセスが増えても自動拡張してくれる。

この安定性とコストパフォーマンスは捨て難いです。
そんな人はNoSQLに活路を見出してみましょう。


AmazonのNoSQLであるDynamoDBは、GoogleのBigTableと並んで世界一有名なNoSQLです。

っていうか、LambdaもDynamoDBもGoogleのパクリとしか思え……ゲホゲホ

DynamoDBはクラウド型DBを名乗るだけあって、Lambdaのインスタンス激増から来るアクセス急増にも耐えられるように設計されています。

耐久性の秘密は分散にあります。
だから「保存したデータが別の場所からは見えない(伝搬してないから)」という現象が起きたりとか、RDBMSとはまるで別物。

分散を実現する為に「リレーション」というものが無く、従ってテーブル間結合も出来ないとか、DBをRDBMSからDynamoDBに差し替えれば使えるみたいな単純な話ではないところが厄介ですが、ちゃんと勉強して使いどころを見極めれば非常に心強い味方になってくれるでしょう。

終わりに

引き続きLambdaの話を続けます。

2018年4月2日月曜日

【AWS Lambda】帳票出力API開発 その1

株式会社ジェニシス 技術開発事業部の遠藤 太志郎(Tacy)です。



上記に記載したとおり、最近覚えたPythonをメインに使用して社内用のWebシステムを作ってみました。
システム構成はこんな感じです。




複数のアーキテクトから構成されるシステムですので、このブログでは分解して連載して行きたいと思います。

最初はAWS Lambdaで稼働する帳票出力APIです。

AWS Lambda

AWS Lambdaは、Lambdaが提供するコード実行環境です。
公式サイトはこちら。


公式サイトにはこのように書かれていますね。

AWS Lambda はサーバーをプロビジョニングしたり管理しなくてもコードを実行できるコンピューティングサービスです。AWS Lambda は必要に応じてコードを実行し、1 日あたり数個のリクエストから 1 秒あたり数千のリクエストまで自動的にスケーリングします。使用したコンピューティング時間に対してのみお支払いいただきます- コードが実行中でなければ料金はかかりません。AWS Lambda によって、実質どのようなタイプのアプリケーションやバックエンドサービスでも、管理なしでコードを実行できます。

でもこれ、初めてLambdaに触れる人には何言ってるのかチンプンカンプンだと思います。
そこでまずはLambdaの導入編として、その使い方や長所、短所といった解説から行ってみましょう。

特徴1:サーバレス環境である

サーバレス環境、サーバレスアーキテクチャ……。
最近のクラウド界で流行のキーワードです。

サーバレスとは直訳すれば「サーバが無い」という意味になりますが、実際のところ、サーバはあります。

あくまで我々利用者がサーバの細かい設定を意識しなくて良い、利用者目線でサーバが無いかのように見える、という概念的な話です。

概念的な話なのでぼんやりとしてしまいがちですが、この画面を見るとピンと来ると思います。




これはLambdaの管理画面で、ソースをアップロードする項目です。

画面からお察しのとおり、Zipで圧縮したソースをアップロードするだけで実行可能な状態になります。

ソースをサーバのどこどこに配置して、そこにパスを通し、Webリクエストを受ける為にapacheやロードバランサの設定も……とか、そういうのは不要です。

Zipファイルをドンと載せるだけで実行可能。サーバ構築不要。
それが「サーバレス」という言葉の意味です。

ちなみにですが、前述のとおり、我々がサーバを意識しないだけで、実際にはサーバはあるんです。
大企業などでは「インフラ担当」「リリース担当」「開発担当」が完全に分かれている場合、開発担当は作ったソースをリリース担当に渡せばそのうちリリースしておいて貰えるという体制が構築されていることがありますが、
この場合、開発担当の視点ではサーバレスということになります。

従来は「インフラ担当」「リリース担当」がやってくれていた作業を自動でやってくれる。
それがLambdaです。

今まで出来なかったことが可能になるわけではありませんが、今までやっていたことが楽に出来るようになります。

一方、人を介在させず全自動でやるために「制約」も色々ありますが、それは徐々に勉強していきましょう。

特徴2:コンピューティング時間課金

特徴その2は、コンピューティング時間課金であること。

普通のレンタルサーバを借りる場合、月3000円でサーバ1台をレンタル、とかそういう課金方式です。

Lambdaはソースが動いた時間で課金されるので、ソース実行時間が1秒だったら1秒だけ課金されるという方式です。

「じゃあ、1日1度、夜間に3秒で終わるファイルクリーンアップバッチを実行したい場合、1日3秒。月90秒の時間だけお金払えば良いってこと?」

と問われれば、そのとおりです。
そういうところで長所を発揮するサービスです。

軽微な処理の為にサーバを1台占拠したり、既に動いているサーバの隅っこにこっそり置かせて貰ったりとか、そういうのは必要ありません。

軽微な処理だけの為の独立した環境が手に入るという、疎結合という観点でも優れたシステム設計を実現出来ます。

しかし、それ故の欠点もあります。

何故「処理が動いた時間だけ課金」という事が可能なのかというと、それは動いていない時間帯は裏側にあるインスタンス(=サーバ)が寝ているからなのです。

ずっと起きっぱなしだったらAWS側のリソースを食ってしまいますので、無課金というわけにはいきません。
使っていない時間帯は寝ているからリソースを食わない。従って、寝ている間はタダでOK。
そういうカラクリなのです。

だから、寝ぼけた状態から起きる為のコスト、「スタートアップ時間」が発生します。

これが決定的に向かないのがJavaです。
Javaは初期起動でJavaVMを展開するコストが重く、その後もクラスロードが重いと、とにかく最初が重い言語です。

最初が重い言語であるにも関わらず、Lambdaでは起きる度にスタートアップを要求される。
致命的に相反する性質です。

でも実は、今回開発した帳票出力APIはJavaで作ってしまいました。
何故Javaなのか?
それはJavaのライブラリを使わなきゃ実現出来なかったからです。(泣)

事情は後の連載で明らかになりますが、私は好きでLambdaにJavaを展開したわけじゃないってことはご理解下さい。

ちなみに、元々はJavaエンジニアである私が最近Pythonに手を伸ばした理由の一つとして、コレがあります。


  • スタートアップが遅いJavaでは、これからのクラウド時代に適合し切れない


と、私は考えています。

Java自体は良い言語で、今後もずーっと使われていく絶対的安全牌の言語だと思います。
しかし、Javaしか出来ないってエンジニアはヤバい。
Javaの欠点を補える性質を持った言語を身につけておかないと、使い回しの効かないエンジニアが出来上がる危険性があると思います。

そういうわけで、今までJavaだけやってきたエンジニアは、これからの時代の変化に対応する為にPythonを勉強していくことがオススメです。

続く

Lambdaで紹介することはまだまだあります。
次回に続きます。