サービス縮小時のサーバ削減についてのメモ書き


新規サイトの立ち上げや、サーバの移設などで、サーバ群を新規構築したり、逆に全てを停止したりすることはたまに行ってきたけど、サイトを維持したままサーバの台数を減らしてランニングコストを減らすことはあまりしてこなかったので、そのメモ。

サーバ構成

今回、削減対象となるサーバ群は、一般的な以下の構成で計4台のクラウドサービスの仮想サーバ。

RP (ReverseProxy, LoadBalancer)

Web
├─────┐
│      │
DB(Master) DB(Slave)

DBには高速ストレージを追加してあり、サービスが成長し、ある程度のトラフィックとデータ量になっても耐えられるように設計されていた。
が、当初の想定通りには進まず、ほとんどトラフィックがないにもかかわらず、ランニングコストが月額10数万円ほどかかってしまっていた。
これを、月に1万円程度にできないか、という要求。コストを10分の1にせよ、と。

このサイトには設計にも構築にも運用にも関わってなかったので中身は分からないが、ざっと見たところできなくはなさそうなのでやってみた。

サーバ削減計画

webサーバが1台しかないのがアレだけど、webサービスを運営するサーバ構成としてはごく一般的な形。
これを削減していくにあたり、フェーズとして以下の3段階に分けて考えた。

1. Slave DB を削除

障害でサービスが止まってもよい(かつ、過去のある時期のデータが残っていて復旧できれば良い)という要件だったので、まずはさくっとできる Slave DB を停止することでコスト削減。
DBサーバがコストの大きなシェアを持っているので効果大。

2. RPを削除

可用性、負荷分散のためにロードバランサ(apache によるリバースプロキシ)が存在しているが、現状 web サーバは一台だけで、処理能力的にそれで十分、かつ、可用性も求められないということで削除。
フェーズ1,2でコストは当初の半分に。

結果的にこれが予想以上に手間取った。

3. Master DB を webサーバと統合

ディスク容量、メモリ容量的に不安があるが、webサーバで DB も動かしてしまうことで 1台でサイト運用ができる。
これが最終型。月額1万円台に。

ごく普通の MySQL サーバだと思ったら、mroonga が入っており、若干手間取った。

フェーズごとに順を追っていく

1. Slave DB を削除

まずは、
・ ps、netstat、lsof、chkconfig などで mysql 以外のサービスが動いてないか確認
・ cron で何かタスクを動かす設定がされていないか確認

上記により下記が判明
・ mysql 以外には何も役割は担っていない
・ mysql への接続は web サーバからのみ
・ cron で自分のディスクに対してDBの日次バックアップを行っている

やること
・ web サーバから slave DB への接続をやめる
・ 日次バックアップの処理を master DB へ移す
・ slave を止める

・ webサーバから slave DB への接続をやめる

webのシステムはどうやら symfony2 で作られている模様。社内的には他では使われていないので、手探り。
DBの接続情報のところで、更新用のDBと、参照用のDBを指定して接続を切り分けているところがあり、ホントはそこで更新系/参照計を一つにまとめるのが筋だけど、やり方を調べて動作検証をするのがめんどいので、とりあえず参照用も master へ向けることで解決。
DB接続が無駄に倍になるので良い子はマネしちゃだめ。

・ 日次バックアップの処理を master DB へ移す

こちらは、DBのバックアップを行うスクリプトファイルを master のサーバへうつし、master にて朝方に cron 起動するように設定。
DBへの更新はほとんどないので稼働中のバックアップで問題なし。

・ slave を止める

mysql> stop slave;

で、他のサーバからの接続がなくなっていることを確認してサーバを shutdown。
数日 slave 無しでサイトを運用して問題がないこを確認して、サーバ解約!

第1フェーズは特に詰まるところもなくさくっと完了。
長くなったので、第2フェーズ以降はまた次回。。。