CakePHPのセッション管理はデフォルトではローカルのディレクトリにファイルで〜という形になっていて、
AWSのEC2などを使ってスケーラブルなものにしようとした場合、裏側はスケーラブルなKeyValueストアにするのが良い感じです。
AWSの場合はElastiCacheのMemcached(Consistent Hashing)とRedis(Master-Slave)という選択肢がありますが、
今回はMemcahedで構築してみたいと思います。(次回はRedisやります)
■ EC2インスタンスの起動
EC2のAmazon LinuxにCakePHPをインストールしてきます。
友人の@yandoが著者のCakePHP2実践入門によると、
– PHP5.2.8以上
– Apache等のHTTPサーバー(IISやNginxでもOK)、
– mod_rewriteが使えると良さ気
– データベース使う場合はPDO(PHP Data Object)モジュール
とのことで、Amazon LinuxにApacheとPHPとMySQLをyumでインストールすれば良いかな、と。
Management ConsoleからLaunch Instanceする時に、サクっとReview and Launchボタンで立ち上げると、
デフォルトでセキュリティグループの設定で80番ポートが開いてないので↓のようにAddしてやります。
■ Apache, PHP, MySQLのインストール
yumで↓こんな感じでインストールしていきます。
$ sudo yum -y install httpd php mysql-server php-mysql 読み込んだプラグイン:priorities, update-motd, upgrade-helper 依存性の解決をしています 〜略〜 インストール: httpd.x86_64 0:2.2.26-1.1.amzn1 mysql-server.noarch 0:5.5-1.3.amzn1 php.x86_64 0:5.3.27-1.0.amzn1 php-mysql.x86_64 0:5.3.27-1.0.amzn1 依存性関連をインストールしました: apr.x86_64 0:1.4.6-1.10.amzn1 apr-util.x86_64 0:1.4.1-4.14.amzn1 apr-util-ldap.x86_64 0:1.4.1-4.14.amzn1 generic-logos.noarch 0:17.0.0-2.5.amzn1 httpd-tools.x86_64 0:2.2.26-1.1.amzn1 mysql55.x86_64 0:5.5.34-1.40.amzn1 mysql55-common.x86_64 0:5.5.34-1.40.amzn1 mysql55-libs.x86_64 0:5.5.34-1.40.amzn1 mysql55-server.x86_64 0:5.5.34-1.40.amzn1 perl-DBD-MySQL.x86_64 0:4.020-2.8.amzn1 perl-DBI.x86_64 0:1.609-4.4.amzn1 php-cli.x86_64 0:5.3.27-1.0.amzn1 php-common.x86_64 0:5.3.27-1.0.amzn1 php-pdo.x86_64 0:5.3.27-1.0.amzn1 完了しました!
ApacheとMySQLを起動します。
ついでにマシンイメージを取得して、そこからインスタンスを立ち上げる場合などに備えて、
自動起動の設定を入れておきましょう。
– Apache
$ sudo /etc/init.d/httpd start httpd を起動中: [ OK ] $ sudo chkconfig httpd on
– MySQL
$ sudo /etc/init.d/mysqld start MySQL データベースを初期化中: Installing MySQL system tables... OK Filling help tables... OK 〜略〜 Please report any problems with the /usr/bin/mysqlbug script! [ OK ] mysqld を起動中: [ OK ] $ sudo chkconfig mysqld on
■ CakePHPのインストール
続きましてCakePHPのインストール、というかダウンロードして配置します。
$ cd /var/www/html/ $ sudo curl -O https://codeload.github.com/cakephp/cakephp/zip/2.4.3 % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 2042k 100 2042k 0 0 367k 0 0:00:05 0:00:05 --:--:-- 495k $ ls -ltr 合計 2044 -rw-r--r-- 1 root root 2091758 12月 17 01:39 2013 2.4.3 $ sudo unzip 2.4.3 Archive: 2.4.3 eb34e011e2384041997da167821c36125e8f836e creating: cakephp-2.4.3/ inflating: cakephp-2.4.3/.editorconfig inflating: cakephp-2.4.3/.gitignore 〜略〜 $ pwd /var/www/html $ ls -l 合計 2048 -rw-r--r-- 1 root root 2091758 12月 17 01:39 2013 2.4.3 drwxr-xr-x 6 root root 4096 11月 25 02:25 2013 cakephp-2.4.3
Apacheのプロセスはapacheユーザーで動いているので、ディレクトリの権限をapacheに変更します。
$ ps -ef | grep httpd root 1397 1 0 01:21 ? 00:00:00 /usr/sbin/httpd apache 1400 1397 0 01:21 ? 00:00:00 /usr/sbin/httpd apache 1401 1397 0 01:21 ? 00:00:00 /usr/sbin/httpd apache 1402 1397 0 01:21 ? 00:00:00 /usr/sbin/httpd apache 1403 1397 0 01:21 ? 00:00:00 /usr/sbin/httpd apache 1404 1397 0 01:21 ? 00:00:00 /usr/sbin/httpd apache 1405 1397 0 01:21 ? 00:00:00 /usr/sbin/httpd apache 1406 1397 0 01:21 ? 00:00:00 /usr/sbin/httpd apache 1407 1397 0 01:21 ? 00:00:00 /usr/sbin/httpd ec2-user 1766 1304 0 01:42 pts/0 00:00:00 grep httpd $ sudo chown -R apache:apache /var/www/html/cakephp-2.4.3
Apacheの設定ファイルでDocumentルートをcakephp-2.4.3にします。
Apacheの設定ファイルは /etc/httpd/conf.d/ に配置されますが、そこのREADMEを読むと、
以下のように書かれていて、このディレクトリにある”.conf”ファイルならOKとのことです。
ついでにアルファベット順で並ぶから、mod_perlを使うようなモノはperl.confより後で〜
って注意書きもあったりもします。 #ハマったりしそうですね。。コレ。。。
This directory holds Apache 2.0 module-specific configuration files; any files in this directory which have the ".conf" extension will be processed as Apache configuration files. Files are processed in alphabetical order, so if using configuration directives which depend on, say, mod_perl being loaded, ensure that these are placed in a filename later in the sort order than "perl.conf".
ということで、以下のように cake.conf というファイルを作ってみました。
.htaccessを使いたいのでAllowOverride Allにします。
↓こちらのブログを参考にさせていただきました。
http://d.hatena.ne.jp/hrendoh/20110501/1304271044
$ sudo vim /etc/httpd/conf.d/cake.conf <VirtualHost ec2-xxx-xxx-xxx-xxx.ap-northeast-1.compute.amazonaws.com:80> DocumentRoot /var/www/html/cakephp-2.4.3 <Directory /var/www/html/cakephp-2.4.3> AllowOverride All </Directory> </VirtualHost>
最後にApacheを再起動して、EC2にCakePHPがインストールできました。
$ sudo /etc/init.d/httpd restart httpd を停止中: [ OK ] httpd を起動中: [ OK ]
↓saltが〜とか、データベースの設定ファイルが〜って言われていますね、、、w
ということで、データベースにテーブルを作ってScaffoldしてみようと思います。
- UTF-8でデータベース作って mysql> create database caketest default character set utf8; Query OK, 1 row affected (0.00 sec) - データベースユーザー作って mysql> create user cakeuser@localhost; Query OK, 0 rows affected (0.01 sec) - データベースユーザーのパスワードを設定して mysql> set password for cakeuser@localhost = password('cakepassword'); Query OK, 0 rows affected (0.00 sec) - 作ったユーザーに権限を付与します mysql> grant all on caketest.* to cakeuser@localhost; Query OK, 0 rows affected (0.00 sec) - 作ったデータベースにテーブルを作ります mysql> use caketest Database changed mysql> create table cakes (id INT(11) NOT NULL AUTO_INCREMENT, description VARCHAR(64), created DATE, PRIMARY KEY(id)); Query OK, 0 rows affected (0.03 sec)
CakePHPのデータベース接続設定を変更します。
$ cd /var/www/html/cakephp-2.4.3/app/Config $ sudo cp database.php.default database.php $ sudo chown apache:apache database.php 62 class DATABASE_CONFIG { 63 64 public $default = array( 65 'datasource' => 'Database/Mysql', 66 'persistent' => false, 67 'host' => 'localhost', 68 'login' => 'cakeuser', //データベースユーザー 69 'password' => 'cakepassword', //パスワード 70 'database' => 'caketest', //データベース名 71 'prefix' => '', 72 //'encoding' => 'utf8', 73 );
Scaffold用Controllerを作ります。
cd /var/www/html/cakephp-2.4.3/app/Controller $ sudo vim CakesController.php <?php class CakesController extends AppController { public $scaffold; }
ブラウザからアクセスすると↓
動いてるっぽいですが、ワーニングが出まくってるのが気になる。。。
ググっていくと↓こちらのページに詳しく書かれていますね。
http://oki2a24.com/2012/08/24/how-to-set-php-ini-date-timezone/
Timezoneの設定をしてApacheを再起動します
$ sudo vim /etc/php.ini 953 [Date] 954 ; Defines the default timezone used by the date functions 955 ; http://www.php.net/manual/en/datetime.configuration.php#ini.date.timezone 956 date.timezone = "Asia/Tokyo" $ sudo /etc/init.d/httpd restart httpd を停止中: [ OK ] httpd を起動中: [ OK ]
ワーニング出なくなりましたーヽ(´▽`)ノ
■ CakePHPのセッション管理
CakePHPのデフォルトではローカルのファイルシステムを使ってセッション管理をします。
Controllerは↓こんな感じ。セッションオブジェクトに出し入れしてViewに渡す。
<?php class TestController extends AppController { function index() { $this->Session->write('TestKey', 'TestValue'); $value = $this->Session->read('TestKey'); $this->set('session', $value); } }
Viewは↓こんな感じ。
Controllerから受け取った値を表示する。
<?php echo "Hello World!!"; echo $session;
設定ファイルをみると↓のような感じ。デフォルトではphp.iniの設定に従う、と。
(セッションをDBでという場合はapp/Config/Schema/sessions.phpを流してテーブル作ってね、って感じ)
181 /** 182 * Session configuration. 〜略〜 204 * The built in defaults are: 205 * 206 * - 'php' - Uses settings defined in your php.ini. 207 * - 'cake' - Saves session files in CakePHP's /tmp directory. 208 * - 'database' - Uses CakePHP's database sessions. 209 * - 'cache' - Use the Cache class to save sessions. 〜略〜 214 * To use database sessions, run the app/Config/Schema/sessions.php schema using 215 * the cake shell command: cake schema create Sessions 216 * 217 */ 218 Configure::write('Session', array( 219 'defaults' => 'php' 220 ));
では、php.iniの中はどうなっているかというと↓ココのようです。
1277 session.save_path = "/var/lib/php/session"
実際みてみると、タイムスタンプが更新されて中身も上記の値が入っています。
$ pwd /var/lib/php/session $ ls -ltr total 152 -rw------- 1 apache apache 138 Dec 17 12:52 sess_hrs97ck4c5ie709dic2956ob60 〜略〜 -rw------- 1 apache apache 81 Dec 18 12:45 sess_gqad70guq37jocap6kmkqjcka5 -rw------- 1 apache apache 81 Dec 18 13:18 sess_00vn5bs2o8b540qkh9dvcs5vg3 -rw------- 1 apache apache 138 Dec 18 13:21 sess_8bo261uc8grii2rlkn3konjk17 - 現在の時刻は UTCで13時31分。 $ date Wed Dec 18 13:31:44 UTC 2013 - ブラウザからアクセス後にみてみると、現在時刻のファイルができています。 $ ls -ltr total 152 -rw------- 1 apache apache 138 Dec 17 12:52 sess_hrs97ck4c5ie709dic2956ob60 〜略〜 -rw------- 1 apache apache 81 Dec 18 13:18 sess_00vn5bs2o8b540qkh9dvcs5vg3 -rw------- 1 apache apache 138 Dec 18 13:31 sess_8bo261uc8grii2rlkn3konjk17 - 中身を参照してみると、Controllerで入れたKeyとValueが確認できました。 $ cat sess_8bo261uc8grii2rlkn3konjk17 Config|a:3:{s:9:"userAgent";s:32:"6d912fd2293bc65a0521c338cf959e27";s:4:"time";i:1387387908;s:9:"countdown";i:10;}TestKey|s:9:"TestValue";
■ CakePHPのセッション管理をElastiCacheのMemcachedで
ElastiCacheのManagementConsoleで3ノード。t1.microで。
それ用のセキュリティグループ(11211ポート)を立てます。
↓ElastiCacheが起動するとこんな感じになります。
↓各ノード
Configration Endpointにtelnetで接続してみます。
$ sudo yum install telnet $ telnet cakecache.nwiwua.cfg.apne1.cache.amazonaws.com 11211 Trying 172.31.20.172... Connected to cakecache.nwiwua.cfg.apne1.cache.amazonaws.com. Escape character is '^]'. set key 0 900 4 //"key"というキーで hoge //"hoge"という文字列を保存 STORED get key //"key"というキーの値を取得 VALUE key 0 4 hoge //取得した文字列 END quit
Configuration Endpointというは、AWSが提供しているライブラリを使用すれば、
AutoDiscoveryで〜的な(詳しくは↓のリア充な先輩のブログを参照)事が出来ますが、
http://understeer.hatenablog.com/entry/2013/01/04/061717
今回は、作った3つのノードを普通に使います。
CakePHPの設定ファイルのcore.phpを変更します。
私の環境では /var/www/html/cakephp-2.4.3/app/Config/core.php になります。
defaults を php から cache に変えて、handler で config を defaultに。
206 * – ‘php’ – Uses settings defined in your php.ini.
209 * – ‘cache’ – Use the Cache class to save sessions.
Configure::write('Session', array( 'defaults' => 'cache', 'handler' => array( 'config' => 'default' ), ));
そしてdefaultの設定。
serversの所をElasciCacheのNodesのEndpointを記載します。
(ソレ以外はコメントに書いてあった設定をそのままです)
Cache::config('default', array( 'engine' => 'Memcache', //[required] 'duration' => 3600, //[optional] 'probability' => 100, //[optional] 'prefix' => Inflector::slug(APP_DIR) . '_', //[optional] prefix every cache file with this string 'servers' => array( 'cakecache.nwiwua.0001.apne1.cache.amazonaws.com:11211', 'cakecache.nwiwua.0002.apne1.cache.amazonaws.com:11211', 'cakecache.nwiwua.0003.apne1.cache.amazonaws.com:11211', ), //[optional] 'persistent' => true, // [optional] set this to false for non-persistent connections 'compress' => false, // [optional] compress data in Memcache (slower, but uses less memory) ));
が、エラーになってしまいました。。
↓こちらのブログをみると、MemcachedのPHPクライアントとして、php-pecl-memcacheが必要なようでしたので、
http://ab.blog.jp/archives/3867657.html
↓yumでインストールしてApacheを再起動します。
$ sudo yum install php-pecl-memcache $ sudo /etc/init.d/httpd restart Stopping httpd: [ OK ] Starting httpd: [ OK ]
無事に画面が表示できました↓
↓ローカルにはタイムスタンプ的にファイルは作成されていません。
$ date Wed Dec 18 14:37:15 UTC 2013 $ ls -ltr total 152 -rw------- 1 apache apache 138 Dec 17 12:52 sess_hrs97ck4c5ie709dic2956ob60 〜略〜 -rw------- 1 apache apache 81 Dec 18 13:18 sess_00vn5bs2o8b540qkh9dvcs5vg3 -rw------- 1 apache apache 138 Dec 18 13:31 sess_8bo261uc8grii2rlkn3konjk17
telnetでMamcachedの方を見てみましょう。stats items と stats cachedump を使います。
– 0001のインスタンスには入ってないようです。
$ telnet cakecache.nwiwua.0001.apne1.cache.amazonaws.com 11211 Trying 172.31.20.44... Connected to cakecache.nwiwua.0001.apne1.cache.amazonaws.com. Escape character is '^]'. stats items STAT items:4:number 1 STAT items:4:age 1132 〜略〜 STAT items:4:evicted_unfetched 0 END stats cachedump 4 1 ITEM app_qs0c11va9rt51ldi9u1td3n5a0 [81 b; 1387382341 s] END get app_qs0c11va9rt51ldi9u1td3n5a0 VALUE app_qs0c11va9rt51ldi9u1td3n5a0 0 81 Config|a:3:{s:9:"userAgent";s:0:"";s:4:"time";i:1387393140;s:9:"countdown";i:10;} END quit
– 続いて0002。入ってますね。
$ telnet cakecache.nwiwua.0002.apne1.cache.amazonaws.com 11211 Trying 172.31.30.203... Connected to cakecache.nwiwua.0002.apne1.cache.amazonaws.com. Escape character is '^]'. stats items STAT items:6:number 1 STAT items:6:age 1138 〜略〜 STAT items:6:evicted_unfetched 0 END stats cachedump 6 1 ITEM app_8bo261uc8grii2rlkn3konjk17 [159 b; 1387382492 s] END get app_8bo261uc8grii2rlkn3konjk17 VALUE app_8bo261uc8grii2rlkn3konjk17 0 159 Config|a:3:{s:9:"userAgent";s:32:"6d912fd2293bc65a0521c338cf959e27";s:4:"time";i:1387393288;s:9:"countdown";i:10;}TestKey|s:9:"TestValue";From01|s:7:"Value01"; END
– 0003にはありません(先ほどテストで入れた”key”が残っていますが。)
$ telnet cakecache.nwiwua.0003.apne1.cache.amazonaws.com 11211 Trying 172.31.20.172... Connected to cakecache.nwiwua.0003.apne1.cache.amazonaws.com. Escape character is '^]'. stats items STAT items:1:number 1 STAT items:1:age 39292 〜略〜 STAT items:1:evicted_unfetched 0 END stats cachedump 1 1 ITEM key [4 b; 1387341830 s] END
■ 複数台のWebサーバーからセッションにデータを出し入れ
1台のCakePHPのWebサーバーからはMemcahedにアクセスできる事がわかったので、
今回はマシンイメージを取得して、そこから3インスタンス立ち上げて、前段にロードバランサを設置してみましょう。
では、まずマシンイメージを取得。EC2のManagement Consoleで右クリックして”Create Image”するだけです。
名前を付けて保存します。
3つインスタンスを立ち上げてみます。
上記で保存したイメージを右クリックして”Launch”するだけです。
続いてロードバランサを立てます。
ヘルスチェックはindex.phpで行います。レスポンスコード200が返ればOK。
ヘルスチェックのインターバルやスレッショルドはテストの為、短めで。
セキュリティグループの設定も忘れずに。
in service(全部OK)になりました。
続いて、ApacheのVirtualHostの設定を書き換えます。
他に何か動かす予定もないため*で。
$ sudo vim /etc/httpd/conf.d/cake.conf <VirtualHost *:80>
CakePHPのコントローラーでは、他のインスタンスでセットした値を読み込むようにしてみました。
– 1つ目のインスタンス
<?php class TestController extends AppController { function index() { $this->Session->write('From01', 'Value01'); $value = $this->Session->read('From02'); $this->set('session', $value); } }
– 2つ目のインスタンス
<?php class TestController extends AppController { function index() { $this->Session->write('From02', 'Value02'); $value = $this->Session->read('From03'); $this->set('session', $value); } }
– 3つ目のインスタンス
<?php class TestController extends AppController { function index() { $this->Session->write('From03', 'Value03'); $value = $this->Session->read('From01'); $this->set('session', $value); } }
MemcachedのクラスタをManagement ConsoleからRebootして、
何回かブラウザでアクセスしていくと↓のようにイイ感じです。
次回はElastiCache Cluster ClientをCakePHPに組み込んで、Configuration Endpointでやりくりしてみたいと思います。
技術評論社
売り上げランキング: 32,187
コメント