という話

技術ブログにしたい

9ヶ月で月間1000万PVにスケールするまでに躓いたこと

2月にベータ版を公開してから、9ヶ月(2014年11月)でPVが1000万を超えた記念。
サービスがスケールするにつれて、ググっても同じ悩みを持つ人が少なくなっていって問題解決に時間がかかった。
参考になるかは分からないけどメモ。
そんなの当たり前だろ!ってことも多いですが初めはそういうもんだということで。
お仕事で作ったサービスなのでサービス名は伏せときます。

時系列で躓いた点を上げていきます。まずはスペック

スペック

・クラウド     : AWS, さくらクラウド
・言語       : PHP, javascript
・フレームワーク  : FulePHP
・Webサーバー   : Apache(EC2)
・DBサーバー    : Mysql(RDS)
・キャッシュサーバー: Redis(EC2)

俺スペック

・PHPer歴2年
・Linux歴2年


躓いたところ

画像の動的作成は非常に重い処理(2014年3月ごろ)

そんなに重い処理だとはつゆ知らず、URLに幅を指定してやれば動的に画像をリサイズする処理を入れてたんですが、すぐサーバー落ちました。
同時アクセス5くらいで落ちてましたw

対策:画像をアップロードするときにリサイズするようにした。
デザインが毎週コロコロ変わるとかで無ければアップロード時にリサイズした方がいいです。
計測してみたらHTMLをレンダリングするまでの時間が300ms位だったのに対し、画像1枚に300〜500ms(デカイ画像だと1秒)とかかかってた。
画像1枚の処理に、URLパースしてDB接続して色々計算してみたいな処理を全部終えるのと同じかそれ以上かかるわけです。
20枚画像あったら20倍ですよ、やばい。

webサーバー1台の限界(2014年4月ごろ)

この頃からグノシーさんとかに補足され始めてちらほらアクセスが集まって来ました。
それまではwebサーバー1台DBサーバー1台でやってて、アクセスが上がるたびに一回サービス止めてインスタンスを良い奴にして再起動みたいな事してました。
ですがある程度のスペックまで上げると、それ以上良いインスタンス使ってもアクセスが捌けなくなりました。

対策:負荷分散しました
このへんは4回に分けて記事書きました。

ネットワーク素人が、さくらクラウドで負荷分散構築した時のメモ1【準備編】 - なりせなるてず


転送量が多すぎる(2014年9月ごろ)

PHPなどの処理はAWSで、画像などの静的ファイルは転送量課金が無いさくらクラウドから配信していたのですが、アクセスが集まると画像だけ非常に遅く表示されるようになりました。
ISDNの古き良き時代を思い出させるサービスとして、これはこれでいいかという気の持ちようで居たのですが上司からダメ出しをくらいました。
さくらクラウドの標準ネットワーク速度は100Mbpsなのでそれをぶっちぎってたわけです。

対策:サーバーの追加と静的ファイルの圧縮
単純に1台サーバーを追加すれば200Mbpsになるので、サーバーを追加しました。
それでは根本的な解決ではないので、静的ファイルを圧縮しました。
javascriptとcssはGruntを使いminifyします。
静的な画像はPNGならtinypngで、JPEGはoptimizillaで極限まで圧縮しました。
転送量が3分の1位まで減りました。サーバー費も浮きますね。

瞬間的アクセスで落ちる(2014年11月ごろから現在)

これはまだ解決しきれてない問題ですが一応。
iPhoneアプリのユーザーが増えてきてアプリでPUSHを送ると瞬間的(5秒間位)に秒間100アクセス以上あり、いつもは秒間5〜10アクセス位なので当然捌ききれず2,3分サービスがほぼ停止状態に陥る。

対策:データの持たせ方の変更と、サーバーの追加
この問題には複数の原因がありました。
・原因1
瞬間的アクセスがあるとすぐにDBが息しなくなるので原因調査したらデータの持たせ方に問題がありました。
アクセス数をページ毎に持たせていたのですが、1ページ1レコードでした。
Update文を発行すると対象行はロックされます。秒間100アクセスなのでロック待ちの処理が大量発生しレスポンスが返ってこなかったのです。
アクセス数を1ページ30レコード位に増やし、ランダムでインクリメントし、表示時は足して表示するようにしました。
これでロック待ちの処理は30分の1になりました。

・原因2
タイムアウトまでの時間が短すぎました。
タイムアウトを5秒に設定していたので高負荷時はレスポンスを返せませんでした。

・原因3
単純にWebサーバーの力不足。
平常時の秒間5アクセス位に合わせてサーバーを建ててるので瞬間的なアクセスには耐えられません。
オートスケールでは秒単位のアクセス増加には間に合いません。
サーバーをずっと建てとけばいいんですが、サーバー費がガッツリかかるのでそれも出来ません。
ここの折り合いがつかず、まだ解決しきれてません。


おわりに

元々プログラマとしてしか仕事してなかったのでサーバー構築・管理は未だに分からない事だらけです。
月間1000万PVとか昔は信じられなかったですが、意外と一人でもなんとかなるもんですね