読者です 読者をやめる 読者になる 読者になる

HDE BLOG

コードもサーバも、雲の上

ワーカーをオートスケールでスポットインスタンスをアジャストしてプライスを1/4にしたファクト

おはこんばんちは!! 尾藤 a.k.a. BTO です。

メール流量とインスタンス数が完全に一致!!

まずはこの図をご覧ください。

f:id:masatobito:20141212153222p:plain

上がメール流量で、下がインスタンス数になっていますが、グラフが完全に一致しています。適切な時間に適切な台数を配置することで、サーバ代を1/4に削減することができました。今回はその話を書きたいと思います。

f:id:masatobito:20141205145731p:plain

こちらがメールアーカイブシステムの概要です。この中で、トークナイザーフラッシャーがワーカーになります。このワーカーが今回オートスケールする対象となります。

スポットインスタンス

オートスケールの話を始める前に、まずスポットインスタンスについて説明します。 詳しい説明はAWSのページを見ていただくとして、簡単に説明すると余剰のインスタンスを激安で使用するインスタンスの事です。 価格は常に変動しており、入札で購入し、価格が上昇すると容赦なく落とされます。特徴をまとめるとこんな感じです。

  • 入札制
  • 価格が安い
  • 勝手に落とされる

スポットインスタンスがどれだけ安いか価格を見てみましょう。

インスタンス スポット オンデマンド
m3.medium $0.0126 $0.0731
m3.large $0.0236 $0.1461
m3.xlarge $0.0911 $0.2936
m3.2xlarge $0.1369 $0.5903

*1

だいたい通常価格の1/3〜1/5ぐらいです!!

つまり勝手にサーバが落とされても大丈夫なシステムを作れば、サーバ代を大幅に削減することが可能になってくるのです。

サーバの強制終了

スポットインスタンスを利用するには、サーバが強制終了しても大丈夫なように構成しないといけません。 ワーカーでの処理の流れは次のようになります。

  • キューからメッセージ取得
  • データ処理
  • 結果書き込み
  • キューからメッセージ削除

この処理の流れの途中で中断したケースを考えてみます。

キューからメッセージ取得前

何も処理が始まっていませんから、サーバが落ちても問題ありません。

データ処理前・処理中・処理後

処理中のデータはメモリ上にあります。処理結果は無駄になりますが、動作上の問題はありません。

キューメッセージは処理中のままになりますが、タイムアウト後に取得可能になり別のワーカーによって処理されます。

結果書き込み・キューメッセージ削除前

ここが一番問題になります。処理は終わっているのに、キューメッセージが削除されていない状態なので、また別のワーカーが同じ処理を実行することになります。これは、重複データは上書きするデータが重複しても結果が変わらないようにするという事で解決しています。このように何度実行しても、結果が変わらないようにすることを冪(べき)等性を確保すると言います。

相変わらずキューメッセージは処理中のままなので、タイムアウト時に別のワーカーが処理しますが、前述のように冪等性が確保されているので問題ありません。

キューメッセージ削除後

処理が完全に終わっている状態なので問題ありません。

サーバの自動起動

オートスケールするためには、インスタンスを立ち上げて、サーバが起動して、処理を開始するところまでを全て自動でできるようにしないといけません。やり方はいろいろあるので、詳細は省きますが、事前に全て設定してあります。

AWSのオートスケール

ここまでで、オートスケールをはじめるのに必要な事前準備が整いました。あとはオートスケールするだけです。 AWSにもオートスケールの機能はありますが、うまく実現できない機能があったので今回は採用を見送りました。

  • オートスケールする条件を細かく制御できない

ある程度汎用的なものはちゃんと用意されているのですが、キューのメッセージ数に応じて変えたりとか細かい制御をしようとすると、自前でやる必要がでてきます。

スポットインスタンスのゾーン毎の比較や、オンデマンドインスタンスとの価格比較など、細かい制御ができません。我々は安いサーバが使いたいんだ!!

オートスケールマネージャー

そこで、AWSのオートスケールは使わずに、自前のオートスケールマネージャーを実装しました。 オートスケールマネージャーは、状況に応じてインスタンスの起動・終了を行い、スポットインスタンスの価格を見ながら、できるだけサーバ代が安くなるように調整します。

オートスケールマネージャーが管理するのは、具体的に次のようなものになります。

順番に説明していきます。

メールが増えたら、インスタンス数を増やす

ここでは、SQSのキューのメッセージ数を確認します。キューのメッセージ数 = 処理するメールの数になっていますので、キューのメッセージ数を数えれば、メールの数が分かります。1台当りで処理できるキューのメッセージ数をあらかじめ調べておき、適切な台数を立ち上げます。

もちろんインスタンスを立ち上げるときは、あらかじめ設定されたいくつかのインスタンスタイプの中からスポットインスタンス価格の安いものを自動選択して使います。スポットインスタンスは常に安いわけではなく価格が変動しますので、オンデマンドの価格と比較して十分に安い場合に使用します。そうでなければ、オンデマンドのインスタンスを立ち上げます。

メールが減ったら、インスタンス数を減らす

深夜帯等はメールの流量がぐっと減りますので、インスタンス数を減らします。これはサーバを終了させればいいだけなので簡単にできます。

ですが、注意しないといけないのはサーバを増やす時と違って、減らすときは処理を途中で中断させることになりますので、あまり積極的に落とすと効率が下がります。なので、サーバを減らす場合のしきい値は、増やすときと比べて緩めに設定する必要があります。

うまく動いていないサーバを落とす

サーバを自動起動しているとはいえ、たまにうまく動いてくれないものもあります。うまく動いていないのをずっと動かし続けるのはお金がもったいないだけなので、落とします。具体的には、CPU使用率を調べて明らかに動きが悪いものを落とします。

オンデマンドのサーバを安いスポットインスタンスに変える

スポットインスタンスは価格が変動しますので、常に使えるわけではありません。しかしながらずっとオンデマンドのインスタンスを使い続けるのももったいないので、スポットインスタンスの価格を調べて、オンデマンドインスタンスをスポットインスタンスに置き換えることもしています。

インスタンスの最大数・最小数の管理

オートスケールにすると、メールが突然増えた時に際限なくインスタンスを立ち上げてしまいます。このままだと大量にインスタンスが立ち上がって、サーバ代が大変な事になる可能性があります。ですので、インスタンスの最大数を管理してて、最大数以上はインスタンスを増やさないようにしています。

またインスタンスの最小数も設定していて、最低何台かは起動するようにしています。

まとめ

ワーカーをオートスケールすると次のようなメリットがあります。

オートスケールできるようにするには、システムに次のような特性を持たせる必要があります。

  • サーバが自動起動できる
  • 冪等性が確保されている

では、ハッピーオートスケールライフ!!

*1:2014年12月12日現在での価格