EC-CUBE の Session を Redis に変更する (Azure)


こんにちは。
昨日のセミナーで解説を飛ばした部分について補足します。(まずは、Session の話)

EC-CUBE において、データベースの負荷軽減はボトルネック解消の重要な要素です。ここでは、EC-CUBE の Session 管理として Redis を使用する手順を、Azure を使って紹介します。

Azure Web App の PHP 環境には wincache (Windows Cache Extension for PHP) がビルトインされているので、Session をファイルやメモリに保持することもできますが、Redis を使うことでインスタンス間で Session を効率的に共有できます。

 

EC-CUBE の Session Handler (超概要)

EC-CUBE では、Session Handler として、既定で SC_Helper_Session_Ex オブジェクト (data/class_extends/helper_extends/SC_Helper_Session_Ex.php) を読み込みます。
SC_Helper_Session_Ex は SC_Helper_Session (data/class/helper/SC_Helper_Session.php) から派生 (継承) されたオブジェクトで、既定で SC_Helper_Session_Ex には何も実装されていません。このため、結果的に親クラスの SC_Helper_Session のコードが動作します。
このソースコード (SC_Helper_Session) を見ていただくとわかりますが、既定では、MySQL (または PostgreSQL) が使用されているのです。

EC-CUBE で Session 管理をカスタマイズするには、この SC_Helper_Session_Ex を記述します。

 

環境作成

まず当然ですが、「EC-CUBE の簡単インストールと、実運用のための構成変更」で紹介した手順で EC-CUBE (及び、データベース) の環境を用意しておきましょう。(インストールは、あっという間に終わります。)

つぎに、Redis Cache を作成し、PHP 用の Redis のライブラリーである Predis をインストール (下記コマンドを実行) します。
この手順は、以前「Azure Redis Cache の使用 (.NET, PHP, Node.js)」に記載しましたので参照してください。Azure には、Redis Cache のビルトイン サービスが提供されていますので、Redis 用に OS を立ち上げるなどの面倒な手続きは不要です。

curl http://getcomposer.org/installer | php
php composer.phar require predis/predis dev-master

Azure Redis Cache の使用 (.NET, PHP, Node.js)」に記載しているように、Non-SSL の有効化も忘れずにおこなってください。

また、この投稿で記載しているように、Predis の Session Handler を使うには PHP 5.4 以上が必要です。
現在の Azure ギャラリーの EC-CUBE では PHP 5.3 を使用していますので、バージョンを 5.4 以上に変更しておきましょう。(下図)

 

Redis を使った Session 管理

役者はそろいました。あとは、SC_Helper_Session_Ex.php に下記 (太字) のコードを追加するだけです。
下記の register() 関数により、内部で PHP の session_set_save_handler() 関数が呼び出され、Predis が提供する Session Handler が登録されます。

下記の Host、Port、Auth (key) には「Azure Redis Cache の使用 (.NET, PHP, Node.js)」で取得した値を設定します。

<?php
require_once CLASS_REALDIR . 'helper/SC_Helper_Session.php';
require_once dirname(__FILE__).'\..\..\..\vendor\autoload.php';

class SC_Helper_Session_Ex extends SC_Helper_Session
{
  public function __construct()
  {
    Predis\Autoloader::register();
    $redis = new Predis\Client('tcp://tsmatsuz01.redis.cache.windows.net:6379');
    $redis->auth('PcDPRkroG6...');
    // memo : EC-CUBE default MAX_LIFETIME is 7200 sec
    $handler =
      new Predis\Session\Handler($redis, array('gc_maxlifetime' => MAX_LIFETIME));
    $handler->register();
  }
}

 

なお、EC-CUBE では、一部、DB への接続が前提となっている箇所があるようなので注意してください。

例えば、会員のログインや、管理ページのログインの際に、LC_Page (LC_Page_Admin) オブジェクトが Plug-in (フック) を確認しますが、上述の Redis の Session Handler を設定すると、この箇所で SC_Query (DB のクエリーを扱うオブジェクト) が初期化されずに、SC_Helper_Plugin_Ex::getSingletonInstance がオブジェクトを返さないというエラー (現象) が発生しました。(MySQL の Session を使用している際には、Session の Read/Write であらかじめ SC_Query が初期化されるため、この問題は発生しません。)
これは、LC_Page.php の 105 行目と LC_Page_Admin.php の 65 行目に、下記 (太字) を挿入するこで回避できます。

. . .

// スーパーフックポイントを実行.
SC_Query_Ex::getSingletonInstance();
$objPlugin = SC_Helper_Plugin_Ex::getSingletonInstance($this->plugin_activate_flg);
$objPlugin->doAction('LC_Page_preProcess', array($this));            
. . .

管理、会員登録など、いろいろ動かしてみて この 2 箇所だけでしたが、まだあるかもしれませんのでご注意ください。。。(念のため、ちゃんとテストをおこなってください。)

 

※ 参考情報「EC-CUBE の簡単インストールと、実運用のための構成変更

 

Comments (0)

Skip to main content