いまさらCakePHP2のモデルが遅い原因を発見
最近、CakePHP1系からCakePHP2に移行する機会があり対応しました。
さすがにバージョンが上がるので、悪くはならないと想定していましたが、逆に遅くなってしまい、かなり困りました。そして原因追求の旅をすることになりましたね。(先が見えなかったー。。。)
そして解決まで発見できたので、記事にします。
ただいまさらCakePHP2かよ。というご指摘はごもっともですが、世の中には色々な事情がね。。。すみません。
先に結論としては、DBとクラウド環境が影響しており、時代の影響をもろにうけた原因だったのかな。というところです。
構成
- WEBサーバー:EC2
- DB:RDS(Postgresql)
WEBサーバーについては、2台で冗長構成です。
状況
WEBページを開くと、早い時と遅い時があり、遅い時は4秒ぐらい待たされるため、ストレスになっちゃいました。
ローカル環境で開発していた時には、そこまで遅い印象を受けなかったので、クラウド環境へ反映した途端に遅くなったので困りました。
2分の1で遅いという事で、大体の予測を立てて取り組みましたが、予想通りで意外だった原因でした。
原因
アベイラビリティゾーンの違いでかなりの影響が出ていることを発見。
東京リージョン内でもサーバーが別のところにあるイメージです。可用性を高める点で複数サーバーにする場合は、アベイラビリティゾーンを均等に作るといい構成になります。
クラウドになって複数台構成や可用性をあげる仕組みが簡単になったのはいいことです。
ただ古いフレームワークだと構成次第でこういうのが発生することはありそうです。
さすがに予測できないよね。
さらに根本の原因はcakephp2とDBへの情報取得部分の「getColumnMeta()」が主な原因になっていました。
原因の詳細
DBからデータを持ってきた後に、型ごとに処理する部分がcakephpにあり、それぞれのcolumnの型を取得する必要があります。
データをもってくるところでも型をとってこれるのですが、cakephp2の実装ではカラムごとに毎回取得する形になっており、columnごとにDBにアクセスをしていたのではないかと予想しました。
結局は大量にDBへのアクセスが発生するため、環境によりDBアクセスまでの時間がかかる状況が発生したものだと予想できます。
これがcakephp1系の時に発生しなかったのは、PDOではなく、postgresの関数を使用していたため発生していなかったみたいです。(cakephp1系のソースを読むと、pdoではなくpostgresql関数でした)
原因を探すために、デバックログを大量に埋め込んでやっと見つけたけど、対応までに時間がかかってしまいました。
解決策
PDOが絡んでいることから修正に悩んでいたところ、やっぱり世の中には対応している人がいました。
これを導入しただけで、もう完全に解決しました。
ソースも読んでみましたが、ものすごい簡単に解決できたんですね。
これができるのが、できるエンジニアですよね。
簡単な修正に見えて、これを導くことができる能力ができるエンジニアです。
もっと柔軟に対応していきたいです。