CopyContentDetectorをいろいろ見直しを行いました。
地味で地味でたいへんな作業でしたが、現時点でかなり最適化とサーバの圧縮に成功したと思います。大体5台くらいサーバ減らせました。
PHPのプロファイリングはblackfireを利用しました。とても良かったです。
■見直したこと
▼マスターデータベースのINDEXの見直しとSQLの見直し
ちょっとIOWaitが高かったんです。なので見直しました。
目標値は「long_query_time0.2秒に設定して、slow queryログに何もでないようにする」という基準にしました。現状達成することができています。
・データの偏りでINDEXの効き方が変わってきたのでINDEXの見直し
いままでINDEXで利用されていたのが、データの偏りでフルスキャンになったりしていたので、いろいろ見直しました。 基本に忠実に遅いクエリをexplainで一つずつ潰していきました。
・フレームワークを使ってselect * とかして全カラム取得していたのを見直し
Cakephp使っていて、find使っていたのですが、その処理で使っていないカラムのデータも取得していました。無駄を減らしました。
・繰り返し取得するデータに関してはmemcacheに一定保持することでデータベースにアクセスしないようにした
チェックバッチで何度も取得するようなデータに関してはmemcacheにデータを保持するようにすることで、データベースへのアクセスを減らしました。
★結果
良くなりました。IOWAITですが、かなり減りました。伴ってその他のCPU利用率もかなり効率化されました。
▼コードの見直し(これが一番効果があった)
今回はプロファイリングにblackfireを利用しました。PHP7でも動くプロファイリングツールです。コールグラフなんかも作ってくれて今回とても助かりました。
・CakePHPを使わなくて良い箇所は使わなくした
CopyContentDetectorでは、各種テキスト処理はAPIみたいな感じにして、バッチから処理を分離しています。
フレームワークは便利なのですが、プロファイリングをするとフレームワークの実行だけで結構な実行時間を消費します。何もしなくても200msくらいはフレームワークで持っていかれる感じです。通常のサイト表示での利用であれば200msくらいであれば気にならないのですが、今回はAPI的な感じで利用している部分です。結果が全部違うのでキャッシュにも乗っけられません。大量にアクセス前提なのでこの200msの時間はもったいなかったです。
APIではデータベースアクセスも発生しない単純処理が大多数でした。このAPI部分はフレームワークを捨てました。結果、5msとか10msくらいまで応答時間を短縮することができました。メモリの利用量も大幅に減らせたのです。
これが一番大きかったです。速度も早くなるし、サーバも減らせました。
・composerのautoloadの最適化
プロファイリングしているとcomposerのautoloadする部分が時間を使っていました。どうにも、最適化オプションが有る様子。
以下で最適化したautoloadのファイルが利用できて、少しだけ(50msとかくらい)早くなりました。
composer install --optimize-autoloader
か、インストール済みなら
composer dumpautoload -o
composer何度も使っているのですが、どんなに使い込んでもどうしても好きになれない。。。なんだかこれも気持ち悪いし。
▼ミドルウェアの見直し
php5.6からphp7.1へ。mysqlも5.6から5.7へ。OSのカーネルも4.6系へ。変更できる部分は全部変更しました。効果は不明。ほんの少し早くなったんじゃない?
というところで、かなり手を入れてまた愛着がわきましたとさ。サービスには愛着を持つのがとても重要ですね。
まだまだ効率化できそうな部分も多いので、もっといじくります。