memcachedを利用して、複数サーバのセッションを共有化

By | 2015年7月30日

AmazonEC2(CentOS6)を複数台利用した環境で、ELBによる負荷分散環境を構築していました。
その際、複数サーバ間のセッション管理をどうしようかと検討した結果、memcachedを利用してセッションを共有化することにしました。memcached自体は全サーバにインストールしてセッションを共有化するように設定しました(1台のみにすると、そのサーバが死んだときにセッション共有ができなくなるので)。
構築の際、いくつかはまったポイントがあったのでメモです。

1. memcachedのインストール

#rpm -Uhv http://apt.sw.be/redhat/el5/en/x86_64/rpmforge/RPMS/rpmforge-release-0.5.2-2.el5.rf.x86_64.rpm
#yum install memcached
#yum install php-pecl-memcached

#chkconfig memcached on
#service memcached start

2. memcachedの環境設定

#vi /etc/sysconfig/memcached
→CACHESIZEを512に変更

※CACHESIZEは環境に合わせて設定してくださいね。

#vi /etc/php.ini
→下記の箇所をコメントアウト
; session.save_handler = files
; session.save_path = "/var/lib/php/session"
#vi /etc/php.d/memcached.ini
→下記の箇所のコメントアウトを外して編集
session.save_handler = memcached
session.save_path = "[IPアドレス]:11211,[IPアドレス]:11211,・・・"

※session.save_pathには、セッション共有をさせるサーバのアドレスを設定します。私の場合は、EC2のプライベートIPアドレスを設定しました。
※「tcp://[IPアドレス]:11211」の形式で設定する場合もあるようですが、私の環境では「tcp://」では動作しなかったです。

#vi /etc/php-fpm.d/www.conf
→下記を追加
session.save_handler = memcached
session.save_path = "[IPアドレス]:11211,[IPアドレス]:11211,・・・"

※「/etc/php.d/memcached.ini」に書いたものと同じものを「/etc/php-fpm.d/www.conf」にも記載する必要がありました。どういう理屈かはわかりきっていないのですが。。。片方だけではうまく動作しなかったです。

ここまでやったら念のため、Apacheとmemcachedを再起動

#service httpd restart
#service memcached restart

3. memcachedの動作確認

#yum install telnet
#telnet [IPアドレス] 11211
Trying [IPアドレス]...
Connected to [IPアドレス].
Escape character is '^]'.
#stats ←動作状況が確認できる
#quit

これで他のサーバにも接続してみた動作状況を確認します。うまくつがらない場合は、ポートが解放されているかを確認すると良いかもです。

以下のようなモジュールを各サーバに配置して、セッションが共有化されているかを確認します。


<html>
<body>
<?php echo "test1";?>
<?php
session_start();
if(isset($_SESSION['test1'])){
    $_SESSION['test1'] = $_SESSION['test1'] + 1;
}else{
    $_SESSION['test1'] = 0;
}

?>
<?php print_r($_SESSION); ?>
</body>
</html>


<html>
<body>
<?php echo "test2";?>
<?php
session_start();
if(isset($_SESSION['test2'])){
    $_SESSION['test2'] = $_SESSION['test2'] + 1;
}else{
    $_SESSION['test2'] = 0;
}

?>
<?php print_r($_SESSION); ?>
</body>
</html>