Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

パフォーマンス改善(キャッシュ活用) #1638

Closed
ryo-endo opened this issue Jul 27, 2016 · 27 comments
Closed

パフォーマンス改善(キャッシュ活用) #1638

ryo-endo opened this issue Jul 27, 2016 · 27 comments
Labels
enhancement 機能追加
Milestone

Comments

@ryo-endo
Copy link
Contributor

ryo-endo commented Jul 27, 2016

パフォーマンス改善(キャッシュ活用)

概要

各種キャッシュを活用することでパフォーマンスの向上を行います。

対応内容

Symfony
 HTTPキャッシュ ref #1673
  ページの出力をキャッシュすることで、
  以降のリクエストに対しては極力キャッシュを返却させることでパフォーマンスを向上させます。

Doctrine
 Metadataキャッシュ
  yamlファイルのパース結果をキャッシュすることで、
  2回目以降のパース処理が不要になるためパフォーマンスが向上します。
 
 Queryキャッシュ
  SQLのクエリ生成結果をキャッシュすることで、
  2回目以降のクエリ生成処理が不要になるためパフォーマンスが向上します。

その他
 yamlファイルキャッシュ ref #696
  yamlファイルのパース結果をキャッシュすることで、
  2回目以降のパース処理が不要になるためパフォーマンスが向上します。
  app/config以下のyamlファイルを対象にします。

 キャッシュをクリア機能
  上記の各種キャッシュをクリアするための機能を管理画面に追加。
  

その他

APC/APCuやOpechacheを利用できるサーバー環境であれば、よりパフォーマンスの向上を見込めます。

@ryo-endo ryo-endo added the enhancement 機能追加 label Jul 27, 2016
@ryo-endo ryo-endo added this to the 3.0.11 milestone Jul 27, 2016
@ttsuru
Copy link
Contributor

ttsuru commented Jul 27, 2016

Doctrineは Rails でよく言われるN+1問題の対応をすることもパフォーマンス上良いと思います。

@shinichi-takahashi
Copy link

DoctrineのN+1問題は、EMが優秀で 最大で N+1になりますが、同一性が保障されてるRecord(Entity)に関してはクエリ走りませんよ。

@ttsuru
Copy link
Contributor

ttsuru commented Jul 27, 2016

@shinichi-takahashi
もちろんそうなんですが、N+1にもならないように適切に事前にJoinしてあげるとより高速化します。

@shinichi-takahashi
Copy link

事前にJoin...?
Mapper活かしながらそんなんできましたっけ?

@ttsuru
Copy link
Contributor

ttsuru commented Jul 27, 2016

Joinすると無駄なクエリが減ります

@shinichi-takahashi
Copy link

そりゃそうなんですけど、今回、私が担当していたときにはパフォーマンスを最大化するっていうより、アプリレイヤーでModel層を管理しやすくしようという意味合いでのORM採用だったんで、そのへんの方針どうなんかなーって感じですね

nanasess added a commit to nanasess/ec-cube that referenced this issue Aug 10, 2016
- see
  k-yamamura/eccube3-performance@58c8c86
- 単なる array ファイルをキャッシュにしているだけなので、Yaml に加えて
  array でも config ファイルを記述できるようにしたら良い気がします
@nanasess
Copy link
Contributor

nanasess commented Aug 22, 2016

#1672 + #1695 の対応をしたもので travis-ci を実行してみました
40%弱程度の性能向上が見られました

memcached を使用
https://travis-ci.org/nanasess/ec-cube/builds/154657261

redis を使用
https://travis-ci.org/nanasess/ec-cube/builds/154655121

デフォルト
https://travis-ci.org/nanasess/ec-cube/builds/154066092

default memcached redis
PHP5.3 6.22 3.28 3.58
PHP5.3 7.22 4.32 3.95
PHP5.4 4.94 3.38 3.41
PHP5.4 5.9 3.4 3.85
PHP5.5 3.99 2.57 2.56
PHP5.5 4.68 2.94 3.37
PHP5.6 4.2 2.24 2.37
PHP5.6 4.7 2.93 2.8
PHP7 1.64 1.06 1.04
PHP7 1.92 1.25 1.33
total 45.41 27.37 28.26
39.73% 37.77%

@nobuhiko
Copy link
Contributor

この時間は何の時間の比較なのですか?ビルド時間?

@nanasess
Copy link
Contributor

@nobuhiko PHPUnit の実行時間ですね
Time: 5.99 minutes, Memory: 232.00Mb とかでてくるやつです

@nobuhiko
Copy link
Contributor

nobuhiko commented Aug 23, 2016

index_dev.phpでアクセスした時に表示される、描画タイム?でどのくらい改善されたのか?どの位を目標にしているのかが気になるところです
(改善という割には現状分析と、改善目標がない)

@nanasess
Copy link
Contributor

#1638 (comment) の計測方法に誤りがあったため修正しました。 おおむね40%弱程度の性能改善です。

@nanasess
Copy link
Contributor

@nobuhiko たぶん、 @ryo-endo さんがレポートしてくれるはず

@ryo-endo
Copy link
Contributor Author

間違った理解で書きそうなので、 @chihiro-adachi お願いします。。

chihiro-adachi pushed a commit that referenced this issue Aug 31, 2016
キャッシュ管理画面でtwigディレクトリ以外も削除できるように修正 #1638
@chihiro-adachi
Copy link
Contributor

chihiro-adachi commented Sep 1, 2016

遅くなりましたが、以下にまとめました。

計測環境

さくらのクラウド

  • サーバプラン : 4 GB / 4 仮想コア
  • HDD : 100 GB SSDプラン
  • ディスクイメージ : CentOS7.2 64bit
  • MySQL 5.6.32
  • Apache 2.4.6
  • PHP 5.6 / 7.0.9
    • apcu, opcache有効

デフォルトインストールされた状態で、トップページをApache Bench(v2.3)で計測
Apache Benchの実行は別サーバから行う

ab -n 100 -c 10 http://xxx.xxx.xxx/

3.0.11は以下のキャッシュ設定を有効にしています

  • doctrine-cache
    • metadata-cache: filesystem
    • query-cache: filesystem
  • config_php_output: true

各バージョンでの比較

以下、実行結果(Request Per Second)を記載します

PHP5.6 PHP7
2.13.5 101.63 -
3.0.10 20.6 36.24
3.0.11 35.53 60.27

3.0.10 -> 3.0.11では+50%~60%向上

各設定の比較

各設定をそれぞれ単独で有効にした際の計測結果です。
こちらは以下の環境で計測しています。

  • サーバプラン : 1 GB / 1 仮想コア
  • HDD : 20 GB SSDプラン
  • ディスクイメージ : CentOS7.2 64bit
  • MySQL 5.6.32
  • Apache 2.4.6
  • PHP 5.6
    • apcu, opcache有効
バージョン 項目 設定値 結果
2.13.5 - - 25.29 / 25.38 / 26.15
3.0.11 設定なし - 5.09 / 5.31 / 5.32
3.0.11 metadata cache filesystem 7.27 / 7.51 / 7.54
3.0.11 query cache filesystem 5.47 / 5.45 / 5.47
3.0.11 config output php true 5.42 / 5.71 / 5.50
3.0.11 session handler redis 5.11 / 5.58 / 5.53
3.0.11 上記すべて - 7.91 / 7.85 / 8.08

※実行結果はRequest Per Secondの値

  • metadata cache
    • 最も効果が高い
  • query cache
    • 少し向上。クエリビルダ使用箇所のみ効くため、対象範囲が限定されている
  • config_output_php
    • 少し向上。対象のymlファイル数が少ないため、対象範囲が限定されている
  • session hander
    • 少し向上。ディスクが速ければ、redisでもファイルでもそれほど変わらない
    • 冗長構成とるような際に利用はできそう
  • doctrineのキャッシュドライバの違い
    • 上記の結果には記載できていませんが、redisでも実行してみています
    • ディスクが速ければ、redisでもファイルでもそれほど変わらないようです

パフォーマンスが必要な際の環境

  • サーバ環境
    • PHP7を使う
    • apcu or wincache / opcacheを有効にする
    • ディスクはSSDなど速いもの
  • キャッシュ機構の設定
    • doctrineのキャッシュ機構を有効に
    • config_output_phpを有効に
    • httpキャッシュは、扱い方が難しいですが、静的に近いページや、更新頻度がそれほど高くないブロック(新着情報やカテゴリ)などでは使えそうです(今回は未計測)。

今後の課題

  • result cacheの対応
    • マスタデータ系や更新頻度の低いデータのキャッシュ化
    • findしている箇所をクエリビルダに置き換えていく必要があります
  • lazy loadの抑止
    • 特にフロント側
  • blockのsub request読み込み
  • インデックス
    • 検索対象となるカラムにインデックス張る

などなど、、

今回の対応で、50%~60%程度は向上できる見込ですが、地道なチューニングはまだ必要そうです。

設定方法

キャッシュ等の設定方法は、以下に記載しています。あわせてご覧ください。
http://ec-cube.github.io/config

@ttsuru
Copy link
Contributor

ttsuru commented Sep 2, 2016

@chihiro-adachi
Composer の class map って生成されてますか?
最近ではリリース時には以下を実行するのが定番になってます。

$ composer dump-autoload --optimize

refs Symfony Performance
http://symfony.com/doc/current/performance.html

@nobuhiko
Copy link
Contributor

nobuhiko commented Sep 2, 2016

結果だけみるとチューニングしている場所が違うんじゃないかという印象が・・・

@ttsuru
Copy link
Contributor

ttsuru commented Sep 2, 2016

@nobuhiko
👍

Debug Toolbarみるとチューニングポイントがわかりますね。
Symfonyだとたいてい初期化とControllerとTwigが時間かかるポイントですね。
DBからの取得自体は意外と早いんですよね。

@chihiro-adachi
http://twig.sensiolabs.org/doc/installation.html#installing-the-c-extension
Twig の C Extension もありましたが、Drupal では逆に速度が落ちるという謎現象が・・・
https://www.drupal.org/node/2568247

@chihiro-adachi
Copy link
Contributor

@ttsuru

Composer の class map って生成されてますか?

以下のコマンドでclass map生成していたつもりですが、dump-autoload --optimize とは別ものでしょうか?

composer install --no-dev --optimize-autoloader

@chihiro-adachi
Copy link
Contributor

@nobuhiko

ボトルネックをまだ全て見切れていない可能性もありますね。

今回は、symfonyやdoctrineの一般的なチューニングはある程度検証できたかなと思ってます。
※オフィシャルの情報と、以下あたりを参考にしました。

http://www.glic.co.jp/blog/archives/2627
https://tideways.io/profiler/blog/5-doctrine-orm-performance-traps-you-should-avoid
https://tideways.io/profiler/blog/5-ways-to-optimize-symfony-baseline-performance

課題事項にあげているような内容も、今後検証していきたいところです。

@chihiro-adachi
Copy link
Contributor

@tturu
twig周りだと、ブロックのsub requestの箇所かな、と思ってます。
カテゴリやニュースなどは、部分的にhttp cacheを使えば改善はできそうな気はします。

cのextensionもあるんですね
試してみたいですが、Drupalの謎現象は気になりますね。

@ttsuru
Copy link
Contributor

ttsuru commented Sep 2, 2016

@chihiro-adachi

$ composer install --no-dev --optimize-autoloader

で問題ないと思います。

@tanaka-ichiro
Copy link

@nobuhiko どの箇所のパフォーマンスが気になるのか是非知りたいです!

@nobuhiko
Copy link
Contributor

@tanaka-ichiro
見方があっているのかわかりませんが、現状だとEC-CUBE2系の半分以下の性能ということですよね?

@tanaka-ichiro
Copy link

@nobuhiko 最近EC-CUBE自体を初めて使っているのですが、パフォーマンスが悪いより良い事に越した事がないのでお聞きしました。
初心者が出しゃばって質問をして大変申し訳ございません。
お気分を害されたならお詫び申し上げます。

@nobuhiko
Copy link
Contributor

@tanaka-ichiro
こちらこそすみません
3.0.10 -> 3.0.11では+50%~60%向上 と書いてありますが、その上に書いてある2系のパフォーマンスの半分にも達していない点が一番気になっています(しかも2系が早いとは思っていません)
データをキャッシュするというのはECサイトではセンシティブな問題になりやすいと思っていますが、それを導入しても劇的に改善した様子がなかったので突っ込んだ次第です

@nobuhiko
Copy link
Contributor

@tanaka-ichiro
この修正をいれてブラウザでアクセスすると
3系は1.2秒ぐらいで描画され、内PHPの処理が0.9秒ぐらい
2系は0.4秒ぐらい、内PHPは0.2秒ぐらい
TOPページの比較でこの位の差がありますね

@tanaka-ichiro
Copy link

@nobuhiko
ご丁寧に確認までありがとうございます。
こちらもphp5.6とphp7でapache benchを試しました。
ab -n 100 -c 10 http://xxx.xxx.xxx/

2系の方が確かに早かったのですがエラーページを返していたようで解決方法がわかりませんでした。
3系は遅かったのですがエラーは発生せず結果が返されておりphp7だとさらに結果が良くなりました。

ブラウザでトップページにアクセスすると、
php7+apcu, opcache有効だと2系よりも同等かそれ以上の結果が得られました。

php7を使っても2系より結果が悪ければ2系にしようと思いましたが、
いずれメンテナンスが終わっていくphp5系やeccube2系を使うより、
php7が使える3系を使う理由ができました。

2系も初めて触ってみたのですが構成がすごく分かりづらいし、
ソースが凄く汚くて3系に比べて非常に読みづらく、
どこで何をやっているのか私の知識ではさっぱり理解できませんでした。

3系はどのような構成になっているのかすごく分かりやすく初めてでもまだ読めました。
2系に比べて機能は少なくまだまだ不具合は多いと思いますが、
脆弱性対応や開発のしやすさ、今後のメンテナンスを考えて3系で開発していきたいと思います。
Symfony2を覚えなければいけないという障壁がありますが。。。

色々とありがとうございました。

@Yangsin Yangsin closed this as completed Sep 29, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement 機能追加
Projects
None yet
Development

No branches or pull requests

8 participants