COLOPL Tech Blog

コロプラのエンジニアブログです

MIGによるサーバー費用削減:エンジニアによる実践記

都内某日、在宅勤務でとあるゲームの運用を行っていた男は
プロジェクトマネージャーから打診を受ける。
 M「サーバー費用はこんなにかかるものなのですか?」

他のプロジェクトと比較してみても、そこまで目立って多いわけではない
ある意味では適正である。
スペックの見直しをしてどのくらい費用が抑えられるのか ─────

その後、男はある疑問を抱えることになる。
「夜間のサーバー維持費はもっと抑えることができるのではないか?」

男は名を田中という、コロプラのバックエンドエンジニアである。

〜プロジェクト MIG〜
  お急ぎの方は、記事の最後に対応まとめを記載しておりますので、そちらをご覧ください

 

目標と課題

時は少し遡り
マネージャーからの打診を受けた日、田中は売り上げとサーバー維持費の比率を眺めていた。
 田中「意外と日々の売り上げに対してサーバーの維持費は結構かかってるなぁ」

マネージャーから打診を受けたのち、田中はサーバーのスペックダウンをインフラチームに検討依頼した。
 インフラ「1段階スペック下げても運用上問題ないですね」
 田中「それでは下げて運用しましょう」
とんとん拍子に事は進み、APサーバーのスペックを下げ、当然費用も多少は削減した。

ただ、プロジェクトとしてスペックダウンだけの費用削減効果は
マネージャーが期待していたものよりも少なかった────

もっと費用を下げれないものか、、、頭を抱える田中は様々なデータを確認する
ユーザーリクエストを眺めていた。

16時台がピークになっていて、20時台にも少し上がるいつも通りのグラフだ。
ピークを超え0時付近を境にリクエストは減っていく。
・・・当然だ、ほとんどのユーザーは就寝している。

ふとこの時、日々のタスクの中でサーバーの台数調整は
1日に1回しか行っていないことが引っかかった。
日毎に、16時台のピークを予想して台数を変更しているが
それ以外の時間帯に合わせて台数調整はしていない。

 田中「夜間のサーバー維持費はもっと抑えることができるのではないか?」

もし、0時過ぎた段階で台数を下げ
リクエストが増加してくる前の6時台に台数を元に戻せば、その間の維持費が削減できる。

希望が、見えた ─────

しかし、実際に運用を行おうとすると大きな壁があった。
 ー当然のことながら深夜・早朝に手動で台数調整を行うことは考えられない
 ーそこで、行うとしたらcronにて自動で台数調整を行うことが思い浮かぶのだが
   自動で行っている作業にエラーが発生した時どうするのか
 ー深夜・早朝に見守ることになると結局手動で調整するのとほぼ変わらないことになる
どうにもこの方法は絵空事のようだ。

持て余した田中はインフラチームに相談することにする。

 田中「APサーバーの台数を深夜帯(時間はまだ未確定)で削減できないか検討しているのですが
   自動でAPサーバーの台数を増減することは可能でしょうか?
 インフラ「現在利用しているシステムに、カレンダーに登録した時間で
   台数を調整する自社製スクリプト[semi-autoscale] がありますので利用できるかもしれません
   調査に1ヶ月ほどかかってしまうのでお待ちいただけますか?」

なるほど、そんな便利な機能があるのか!
実現性を帯びた返答に、田中は一も二もなく導入することをお願いした。

1ヶ月後、インフラから返答が届く─────

 インフラ「semi-autoscale では台数を全て決めておかなければならないのに対し、
   gcpmanaged instance group(MIG) の autoscaling が利用できるかもしれないので
   調査していました

田中は驚愕する。台数に関しては台数指定をするタイミングを設ける必要があるため
ある程度余剰が生じても仕方がないと考えていたからだ。
それが、余剰が極力発生しない形で管理できるとは、、、

サーバー台数変動想像図

さらに説明は続く
インフラ「ただし、デプロイ方法が変更になってしまいます
  新しい方式では、新たにサーバーを作成し本番反映した後に
  旧サーバーを抜いていくことになり、旧サーバーは全て削除されてしまいます」

ここで従来のデプロイ方法を説明しておく必要がある。

例えば10台サーバーが稼働し、ゲームを運用しているとする。
追加で作成したり、修正したプログラムを稼働しているサーバーに反映するときには

まず2台のサーバーを「ユーザーからアクセスできる環境」から切り離し、
プログラムファイルを更新、再び「ユーザーからアクセスできる環境」に戻す。
この工程を繰り返し、全ての台数分ファイルの更新が完了すれば完了となる。
この方法だと、使用しているサーバー自体は変わらないことになる。

これに対し、新たなデプロイだと
先に新たなサーバーを用意しておき、「ユーザーからアクセスできる環境」に追加した後で
旧サーバーを削除することになる。


この方法だとサーバー自体が新たなものに置き換わってしまう。
新たなデプロイ方法で問題となるのは
 ・旧サーバーに保存されているログが削除されてしまうこと
 ・それぞれのサーバのキャッシュデータが取り直しになり
   一時的に負荷が上がってしまうこと
などが考えられた。
それら全て対応しても費用削減の効果は大きそうだ。

 田中「費用削減効果の方が大きそうなので、その方法で運用を目指しましょう」

インフラと協力し合い、それぞれの問題に対する対応策を考えた。

まず、ログに関して2つの問題への対応である。

1つ目は、アクセスログ・実行ログ・エラーログなど通常確認は行わないが調査などに使用することがあるログの類を避難させること。

 これはサーバーを削除する前にインフラ側でファイルを取得し、GCS(Google Cloud Storage)に保存することで事なきを得た。
ただし、調査の際にはアクセス権限を持っているインフラにデータ取得をお願いすることとなった。

2つ目は、普段確認するエラーログの監視方法の修正。

 展開時だけでなく、MIGがautoscalingを行うタイミング(自動で行われるためタイミングをはかることはできない)でサーバーが切り替わってしまうため、
既存では運用を行っている特定サーバーのエラーログを取得していたロジックを変更し、
エラーログを取得するタイミングで毎回稼働サーバーを検出することで対応する事にした。

次に、キャッシュデータに対しての対応だが

 元々、MIGは急激なアクセス過多に対しては対応しきれないところがあるため
アクセスが集中する時間帯の前に予め台数を増やすスケジュールを組み急激に台数変動が起こらないように予防しておく想定だった。
これに伴い、キャッシュデータに関してはピーク時点で既に作成されているため問題ないという結論に至った。

ちなみにMIGのスケジュール設定では、サーバーの下限台数とその開始時間、継続時間が設定できるようになっている。
例えば普段5,6台で運用しているところ、16時のピークに合わせ台数を36台まで増台しておき、その状態を1時間継続するといった具合だ。

 

導入と不具合

考えつく問題点を取り除きリリースして問題ないと思われる段階まで進んだ。

2023年1月某日 いよいよMIGを利用しての運用を開始する日が来た。

インフラと連携して作業を行う。
まず、サービスインしていない環境で問題なくデプロイできていることを確認
 そして本番へ─────

ここでデプロイ時に30分程時間がかかることが発覚する。
普段10分程で完了することを考えると3倍かかっていることになる。
不具合が発生した時にすぐに修正ができないのは問題があるため今後の改修課題となった。

それ以外は順調に新たなデプロイでサーバーを追加していく、、
動作している、大丈夫そうだ そう思った時、、、不具合が発生した。

一部のサーバーにアクセスが集中したらしく、集中したアクセスによりサーバーが落ちる。
落ちたサーバーに割り振られていたアクセスが他のサーバーに再度振り分けられ
他のサーバーにも飛び火していく。

すぐさまサーバー台数を増やし、負荷分散を行い事態の収拾をはかる。
程なくして、負荷が正しく分散され正常に戻っていく。

この時点では原因がわからず、たまたま運悪く調子の悪いサーバーを掴んでしまい
問題が発生したと思っていたが、
2回目にデプロイを行った時にも同様の問題が発生してしまった。
(2回目の際はサーバーダウンが起こる前に台数を増やして事無きを得た)

毎回デプロイを行うと不具合が発生するため、一度MIGでの運用を取りやめ
既存の方法で運用を行うこととなった。

ひとまず直面したサーバー停止の不具合は収束したのだが
重要な課題が残されてしまう形となった。

 

原因の特定と解決

翌日、調査を行い
一部のサーバーで負荷が上がり、アクセスを処理できなくなったサーバーが停止、再起動を行っている間に
稼働している別のサーバーへアクセスが集中し、また停止する というように
連鎖的にサービスアウトとサービスインを繰り返すようになっていたことが発覚したのだが

インフラでもなぜそのような動作になるのか調べても肝心の理由がわからず
Googleへの問い合わせを行うことになった。

ただ今回の問題に関してはサーバー1台あたりのリクエスト上限を上げる事により解消できるとの提案も受け
このタイミングで再度MIGの運用に切り替えることも検討したが、安全に運用を行うことを重視し、デプロイ時間の短縮を優先し一時見送る事にした。

デプロイ時間の短縮が完了した連絡を受け、2023年3月末頃
再度、本番反映が行われる運びとなる。
デプロイ時間の短縮も行われており、前回よりスムーズに作業が進む。
特に前回のような問題も起こらず、既存のサーバーからMIGサーバーへの移管が行われる。

───── 問題、ないのか? ─────

今回問題がないのであれば、前回起こった不具合は何が原因だったんだ
そんな疑問を抱きながら、作業は完了を迎える。

結局、特に問題も起こらず導入が完了する。
必要に応じてサーバー台数が増減し、適切な台数に保たれる様をグラフで確認できるようになると、感慨深いものがある。

その後1,2日ほどMIGの最大/最小台数の設定や、適切なスケジュール設定などの
詳細なカスタマイズを行いながら通常運用を行っていく。

このまま何もなく過ごせると思っていた矢先─────

 インフラ
  「12:00 から何か施策やっていましたか?」

突如寄せられた質問と一緒に、サーバー負荷をグラフ化したスクショが送られてくる。この時、特に大きな施策は行っておらず
 変更があったのはMIGを利用してのサーバー自動増加ぐらいのものだった。

サーバー台数がMIGによって自動で増加され、大きな問題に繋がることなく
 負荷は収まっていったのだが、原因を突き止めるべく議論は続く。

 ーdbへの負荷が12:00過ぎに上がっている
 ーサーバー台数が増えてキャッシュに保存前に
   リクエストがきて詰まっていったのではないか
 ー詰まった状態でMIGが自動で台数増やして
   さらにキャッシュ保存前のサーバーが増えているのではないか
 ーとすると、増台したサーバーへは
   リクエストの振り分けを通常よりも少なめにすれば良いのでは

インフラ
 「リクエストをコントロールできるか週明け調べてみます

この日は土曜でアラートの収束と今後の方針が決定したことで解散となった。
すぐさま意見交換や合意形成が行え、調査検証に移れることがこの会社の強みだなとひしひしと感じる。

しかし、調査を行う前に幾度かアラートが発生することになった。
MIGが自動的に台数を上げて負荷を下げてくれるため致命傷とまでは行かないまでも、
このまま運用を続けていくのには不安になる。

1週間ほどの間に、何度かアラートが届く状態が続いたところで
どうやら台数を増やしているタイミングではなく、減らしているタイミングで負荷が増大していることに気づく。
原因の特定には未だ至らないが、リクエストの分散を行っているロードバランサーの部分で何やら問題がありそうなことがわかってきた。
Googleへの問い合わせを行うことで何かわかりそうだ。

2日後、インフラから連絡が届く。

インフラ「先ほど先方から回答が届いたのですが、
     サーバー台数が急に変更される際、均等に配分されるのに2−3分かかるそうで
     増台/減台関わらず再振り分けが行われるみたいです」

なんと
 リクエスト分配は 増台/減台 共に時間経過しないと正常に動作しないことがわかった。
増台時に割り振りが偏ることは想像できたのだが、減台するときは均等分配されているものを均等に削除していくものだと思っていたため想定外だった。

長い間わからなかった、リクエストが偏ってしまう謎の原因がようやく特定できたのだった。

 

本当の導入

原因がわかってしまえば、対処法はすぐに思いついた。
増台を行う際は
 5分以上をかけてスケジュールを分割して目標台数まで上げれば良く、
減台を行う際は
 1度に削除する台数に上限を設け、こちらも数回に分けて削除しておけば良い。

この回答が届いたのが金曜日、即座に対応を行えば週末に間に合う。
スケジュールの見直し、減台数の制御など諸々の設定を無事に行い週末を迎える。

 何も起こらないでくれ─────

結果、減台/増台を繰り返したにもかかわらず、
アラートは発生せず、週末を無事に乗り越えれたのである。

稼働しているサーバー費用の削減をしたい
そんな思いから長い間、取り組んできたMIGの導入がここに完結したのである。
実に構想から10ヶ月程経っての目標達成だった。

 

あとがき

というわけで、いかがでしたでしょうか?
コロプラ バックエンドエンジニア 田中でございます。

実際にMIGを導入するにあたって行ったことをまとめると

◆対応まとめ
 ・ログが削除されてしまうので、退避方法とエラー確認処理の見直し
 ・リクエスト肥大タイミングに向けてのスケジュール調整
 ・減台/増台タイミングの分割対応
 ・デプロイ処理の変更

といった内容が主になり、
作業的にはインフラ側に対応していただいた作業がメインになるため
今回は運用に至るまでの体験談のように記事を書かせていただきました。

所属プロジェクトでの成果はサーバー費用全体の1割ほどの削減になり、現状でも安定して運用できております。
試行錯誤の大切さ、原因究明の当たりをつけた上で検証/調査を進めていく
他部署との合意形成など、普段行っている業務の一旦を感じ取ってくれたなら幸いです。

MIGを導入以降、日々のサーバー台数調整が無くなった事で他の作業に集中できるようになったり
所属プロジェクトで安定運用ができることがわかった段階で、他のプロジェクトにも続々導入され、結果として複数プロジェクトの費用削減に繋り
自分が想像していたよりも大きな成果が出たのではないかと満足しています。

最後に、エンタメ精神を存分に含んだ文体を公式で掲載していただいた寛大な担当者への感謝と、今回導入させていただいたMIGに関連するリンクをご紹介させていただいて
締めくくりとさせていただきます。
長文、駄文を最後までお読みいただきありがとうございました。

 

◆関連リンク

マネージド インスタンス グループ(MIG)
https://cloud.google.com/compute/docs/instance-groups/creating-groups-of-managed-instances?hl=ja

自動スケーリング
https://cloud.google.com/compute/docs/autoscaler?hl=ja#specifications

ロードバランサー
https://cloud.google.com/load-balancing/docs/application-load-balancer?hl=ja

 


ColoplTechについて

コロプラでは、勉強会やブログを通じてエンジニアの方々に役立つ技術や取り組みを幅広く発信していきます。
connpassおよびX(Twitter)で情報発信していますので、是非メンバー登録とフォローをよろしくお願いいたします。

colopl.connpass.com

twitter.com

 

また、コロプラではゲームや基盤開発のバックエンド・インフラエンジニアを積極採用中です!
興味を持っていただいた方はぜひお気軽にご連絡ください。