株式会社ジェニシス 技術開発事業部の遠藤 太志郎(Tacy)です。
最近、AWSをフル活用して社内システムを作ったので、そのノウハウのご紹介を行っています。
今回は気になるニュースを見たので雑談です。
ダイソーで予算超過危機が発生したらしい
ダイソーでLambdaを使ったら年間数千万円のコスト超過に陥るピンチになったらしいですね。
原因は Amazon DynamoDB だそうな。
Lambda と DynamoDB のコスト面での違い
記事を読むと、リスクの原因はLambdaとDynamoDBではコスト面の思想が違うことがキモであるようですね。
Lambdaは従量課金制
私がLambdaに着目する最大の理由ですが、Lambdaは使った分だけ支払う従量課金制です。
Lambdaではない通常のレンタルサーバの場合、サーバを丸ごと一台を借りて占有してしまうわけですから、使っていてもいなくても占有リソースは一定、従って料金は一定です。
つまり、夜中とか誰も使っていない時間帯でも金はそのまま取られているってことですよ。
想定される処理の最大負荷が8と仮定して、それに備えてサーバには10のリソースを割いているとします。
すると、サーバリソースは以下のように消費されます。
|
レンタルサーバの場合のリソース無駄使い |
水色の部分が実際に必要なリソース。
グレーの部分はお金をドブに捨てている部分です。
負荷の最大/最小の差が大きいほど、このグレーゾーンは大きくなります。
「日中しか使わない社内システム」とか「人気ゲームの発売日直後だけ忙しくなる攻略Wiki」とか、かなり勿体ない使い方をしていると思います。
対して、Lambdaの場合はこんな感じ。
|
Lambdaの場合は無駄遣いが殆ど無い |
グレーゾーンが殆どありません。
全く無いとは言いませんが、かなり細かい粒度で節約してくれるわけです。
素晴らしい。
DynamoDBは性能ベース
DynamoDBは「プロビジョニングベース」と言いまして、プロビジョニングとは何なのかはさておき、話の趣旨としては要するにこういうことです。
|
DynamoDBの場合のリソース無駄使い |
DynamoDBは従量課金制ではない。
つまり、
- APサーバであるLambdaは従量課金制かもしれないが、DBサーバであるDynamoDBは従量課金制ではない。
- ダイソーのレジは「忙しい時間帯」と「暇な時間帯」があって、DynamoDBは暇な時間帯でも忙しい時間帯と同じ料金を取られる。
- だからDynamoDBがコスト超過に陥る。
なんてこった。
どうすれば良いのか?
ダイソーの場合
クラウドの面白い所であるが欠点でもあるという所だと思いますが、クラウド環境ってこういう従来方式であれば考えなくて良い制約ってものがあるんですよ。
それを克服出来るかどうかがエンジニアの腕の見せ所。
記事を見ると、ダイソーの場合はLambdaを遅延させることでDynamoDBの最大負荷を下げて解決したようです。
リアルタイム性が必要無いのであれば、そのようなキュー方式を採用するのも一つのアイデアですね。
勉強になります。
S3を使ってはどうか?
ダイソーのキュー方式作戦は一つの正解だったと思いますが、要点はこういうことですよね。
- 出来る限りDynamoDBの負荷を下げなければならない。
核心部分としては、DBサーバの負荷を下げる為のプログラムチューニングなわけですよ。
この記事を見た時は、私は直観で「DBを節約したいなら、ファイルでやればどうか?」と思いましたね。
昔、クラウドではないオンプレミス環境のシステムを作った頃の経験なんですけど、私は大量データ収集配布処理を作ったことがあるんですよ。
あの時は「DBで持つ情報」と「ファイルで持つ情報」を分類して管理していました。
この作戦です。
ファイルサーバに相当するAmazon S3は従量課金制だから、DynamoDBみたいボトルネックにはなりません。
ファイルで持つ情報
ファイルで情報を持つ大前提は「ファイルパスが一意キーである」ことです。
DBの用語で表現をするならば、主キー検索だけでしかアクセスしない情報はファイルで持てば良いのです。
DBで持つ情報
DBで持つ必要のある情報は、SQLですね。
「検索フォームから条件を入れて検索したい」とか「group by したい」みたいなSQLの機能があってこそ実現可能な要件のあるデータはDBで持つしかありません。
まあDynamoDBはNoSQLなのでちょっと違いますが、いずれにせよDynamoDBの中になければ使えない機能が必要なのであれば、DynamoDBに持つしかないです。
ダイソーはきっとこっちだったのでしょうね。
冗長に持つ
これは褒められた手段ではありませんが、状況によっては「殆ど主キー検索で使用するデータだけど、ちょっとだけgroup by したい時もある」みたいなケースもあります。
そういう時は、もう腹をくくって同じデータをファイルとDBの二重で持つのも一つの判断です。
データの不整合の余地を残すという弱点が生まれてしまいますが、チューニングには何かを犠牲にするという判断が必要になる時もあります。
ディスク使用量は問題ではない
私の経験則を一つ。
負荷という面において「ディスク使用量」というのは問題にはならんですよ。
あくまで一般論ですが、システムにおいて「ディスクスペース」ってのは安くて余裕があるものなのです。
だからディスクスペースを無駄遣いする代わりに別の部分を高速化するという手法は常套手段としてよく使います。
Amazonの場合もそうで、ファイルスペースであるS3に巨大データが居座っていることは問題にならんです。
1TB使って月23ドル。
プロジェクト全体の予算から考えればゴミみたいなものでしょう?
低アクセス領域におけばもっと安い。
チューニングにおいては「どこがクリティカルなのか?」ということを分かっていなければなりません。
注意点ですが、ネットワーク転送量は別の話です。
大量データをS3に置いておくだけなら易いですが、それを無数のユーザにダウンロードさせるようなことをすると、ネットワーク料金がかさんで破産します。
だからダウンロード用データはAmazonではなく別の定額制の場所に置くとか、CDN(コンテンツデリバリネットワーク)を使うとかいった工夫が必要になります。
まあ、そこまで話が伸びるとキリが無いのでここで終わり。
まとめ
ここまで書いて思うこととしては、
ということですね。
丸ごとドーンとサーバを貰っちゃってるオンプレミスとは条件が違いますから、処理効率を考案するアーキテクトの力量が非常に重要です。
ありとあらゆる創意工夫を総動員して総合的に効率的なシステムを構築しなければなりません。
となると、「実装が出来るだけ」みたいなドカタが背負えるようなものでは到底なくて、実装・DB・ネットワーク・AWS特性など色々な側面を平行して考慮出来るフルスタックエンジニアが求められてくるという……。
全く、IT業界は楽じゃないですね。