WonderPlanet DEVELOPER BLOG

ワンダープラネットの開発者ブログです。モバイルゲーム開発情報を発信。

Amazon LinuxにPHP + memcached + Redisをインストール

こんにちは!サーバー担当の山内です。
今回は、Amazon LinuxでのApacheサーバー構築手順です。PHP5.4系にAPCをインストールしたあと、memcachedやRedisモジュールを載せたAPサーバーを構築するストーリーになります。FuelPHPについても触れています。

1. Launch Your Instance!

Amazon Linux AMI 2013.03.1 64bitを使ってLaunchします。
Security Groupsの例です。

Port (Service) Source
22 (SSH) 0.0.0.0/0
80 (HTTP) 0.0.0.0/0
443 (HTTPS) 0.0.0.0/0
3306 (MYSQL) 0.0.0.0/0
6379 (Redis) 0.0.0.0/0
11211(memcached) 0.0.0.0/0

ここではRDS(MySQL)にも繋げられるようにTCP 3306も開放しておきます。
EC2の準備が整ったらSSHで接続しましょう。

ssh -i penguin.pem ec2-user@hostname

2. Linuxアップデート, gccとmakeのインストール, タイムゾーンの設定

タイムゾーンは東京に設定します。

sudo su  
yum update  
yum install gcc make  
ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime

3. REMI Repositoryの追加

REMI RepositoryはRHEL/CentOS向けのサードパーティリポジトリです。
公式リポジトリよりも新しいバージョンのパッケージを提供しています。
Amazon公式のリポジトリをそのまま使っても問題ありませんが、今回は有効にします。

wget http://rpms.famillecollet.com/enterprise/remi-release-6.rpm  
rpm -ivh remi-release-6.rpm

remi.repo内のenabled=0を1に修正し、priority=1を追記すればREMI Repositoryが有効になります。

vim /etc/yum.repos.d/remi.repo

[remi]  
name=Les RPM de remi pour Enterprise Linux 6 - $basearch  
#baseurl=http://rpms.famillecollet.com/enterprise/6/remi/$basearch/  
mirrorlist=http://rpms.famillecollet.com/enterprise/6/remi/mirror  
enabled=1  
gpgcheck=1  
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-remi  
priority=1  

4. PHPPHP extensionsのインストール

yum install php php-common php-mbstring php-pdo php-cli php-devel \  
php-fpm php-mysqln php-devel php-mcrypt php-xml mod_ssl php-ldap php-odbc \  
curl-devel php-pear pcre-devel

今回は軽いノリでぐわーっと入れてますが、本当はひとつひとつ吟味していきたいところ!

次にPHPの初期設定をします。

vim /etc/php.ini

;; X-Powered-By隠蔽  
expose_php = Off  
  
;; PHPタイムゾーン設定  
date.timezone = Asia/Tokyo  
  
;; デフォルトの言語を設定  
mbstring.language = Japanese  
  
;; 内部文字エンコーディング  
mbstring.internal_encoding = UTF-8  
  
;; HTTP入力文字エンコーディング(auto:mgstring.languageの設定で展開)  
mbstring.http_input = auto  
  
;; HTTP出力文字エンコーディング(pass:変換しない)  
mbstring.http_output = pass  
  
;; HTTP入力変換を有効にする  
mbstring.encoding_translation = On  
  
;; デフォルトの文字エンコーディング検出順序を設定  
mbstring.detect_order = auto  
  
;; 無効な文字を出力しない  
mbstring.substitute_character = none;  

5. Apache自動起動

chkconfigコマンドでApache自動起動を有効にします。

chkconfig httpd on ; chkconfig --list | grep httpd  
httpd           0:off   1:off   2:on    3:on    4:on    5:on    6:off

ランレベル2〜5がonになっていることを確認します。
次にデフォルトの設定を変更します。

vim /etc/httpd/conf/httpd.conf

サーバー情報を限定する

ServerTokens ProductOnly  

フッタにサーバー情報を表示させない

ServerSignature Off  

クロスサイトトレーシング(XST)防止のためTRACEメソッドを無効化

TraceEnable Off  

Directoryディレクティブの設定

<Directory "/var/www/html">  
    Options FollowSymLinks  
    AllowOverride All  
    Order allow,deny  
    Allow from all  
</Directory>  

OptionsでFollowSymLinksを有効にすると、リクエストごとにファイル属性を調べなくなるためパフォーマンスが向上するといわれています。Indexesは無効にします。
AllowOverrideをAllにすると、リクエストごとに.htaccessファイルの有無をチェックするためパフォーマンスが低下するといわれています。セキュリティ面についての話は割愛させていただきます。

5. APCのインストール

yum install httpd-devel php-pecl-apc

APC管理画面スクリプトであるapc.phpを/var/www/html/apc/にコピーする場合

mkdir /var/www/html/apc  
find / -name "apc.php" -print0 | xargs -0 -i cp "{}" /var/www/html/apc/

APCのユーザー名とパスワードを変更する

vim /var/www/html/apc/apc.php

defaults('ADMIN_USERNAME','admin');    // デフォルト値を変更  
defaults('ADMIN_PASSWORD','password'); // デフォルト値を変更  

APC管理画面スクリプトにDigest認証をかける

defaults('USE_AUTHENTICATION',0); // 1を0に変更  
vim /var/www/html/apc/.htaccess

AuthType Digest  
AuthName "APC"  
AuthDigestDomain /var/www/html/apc/  
AuthUserFile /var/www/html/apc/.htdigest  
Require valid-user  
htdigest -c /etc/httpd/.htdigest 'APC' admin (パスワードを決定する)  
service httpd reload

6. memcachedのインストール

yum install php-pecl-memcache  
yum install php-pecl-memcached libevent libevent-devel

7. Redisのインストール

GitHubから最新のソースを落としてコンパイル&インストールします。

yum install git-core  
git clone https://github.com/nicolasff/phpredis.git  
cd ./phpredis  
phpize  
./configure && make && make install  
vim /etc/php.ini (extension=redis.soを追記)  
service httpd reload

付録1. bashエイリアス

cd  
vim .bashrc

alias crontab='crontab -i'  
alias duh='du -h --max-depth=1'  
alias df='df -H'  
alias ps='ps -ef'  
alias pg='ps -ef | grep -v grep | grep -i'  
alias lss='ls -alhF'  
alias log='tail -f'  
alias c='clear'  
alias h='history'  
alias path='echo -e ${PATH//:/\\n}'  
alias ping='ping -c 5'  
alias ports='netstat -tulanp'  
alias header='curl -I'  
alias headerc='curl -I --compress'  
alias update='yum update'  
alias vm='vmstat -S M'  
alias mem='free -m -l -t'  
  
# mkdir name && cd name  
function mkdircd () {  
    mkdir -p "$@" && cd "$@";  
}  
  
# check PHP syntax  
function phplint () {  
    find "$@" "*.php" -type f -print0 | xargs -0 -n1 -P0 php -l  
}  

phplint()は指定したディレクトリ内にあるPHPの文法をチェックする関数です。

phplint ./

findの結果を-print0で渡して、-0で受け取ることで区切り文字をNull文字(\0)とします。そうすると、ファイル名に空白が入っていても正しく処理されます。-n1で結果を1つずつ処理、-P0で可能な限りプロセスを生成して並列処理するオプションです。並列処理を有効にするとCPU使用率が急上昇します。

エイリアスに慣れすぎると他の端末を扱うときに戸惑うこともあったり。

付録2. Apacheチューニング

mod_deflateによる圧縮転送を有効化する

<IfModule mod_deflate.c>  
    DeflateCompressionLevel 4  
    <Location />  
        SetOutputFilter DEFLATE  
    </Location>  
</IfModule>  

圧縮レベルは低くても十分で、値は2〜3としても効果あり。逆に高すぎても圧縮率は伸びません。gzip圧縮処理はApacheCPU使用率を高めるので、スペックと相談してキメちゃってください☆

MPMについて
非スレッドセーフのApacheモジュール(例えばmod_php)がある場合、MPMはデフォルトのprefork一択となります。マルチスレッドに対応したworkerやeventを選択すると、メモリ空間を共有するためmod_phpは正常に動作しません。

スレッドセーフかどうか確認するには下記コマンドを実行して、

php -r "phpinfo();" | grep -e "Thread Safety" -e "Debug Build"

下記の結果となればスレッドセーフです。

Debug Build => no  
Thread Safety => enabled

preforkに関する以下の設定値は適宜調整してください。

<IfModule prefork.c>  
    StartServers 5  
    MinSpareServers 200  
    MaxSpareServers 200  
    ServerLimit 200  
    MaxClients 200  
    MaxRequestsPerChild 64  
</IfModule>  

この例では、無駄なforkとkillを実行しないように、プロセス数が常に一定になるようにしています。

タイムアウト設定
Elastic Load Balancer配下に設置する場合は、KeepAliveを有効にすることが推奨されています。

KeepAlive On  
KeepAliveTimeout 120  

Apacheステータスのインストール
コメントアウトを外して有効にします。

<Location /server-status>  
    SetHandler server-status  
    Order deny,allow  
    Deny from all  
    Allow from [アクセスを許可するIP]  
</Location>  

付録3. FuelPHPのインストール

FuelPHP v1.6.1をインストールします。

chmod 757 /var/www/

FuelPHPのzipファイルをDLして解凍します。
publicディレクトリの中身は/var/www/html/にアップロードします。
fuelディレクトリ、composer.json、composer.lock、composer.phar、oilを/var/www/に設置します。

php composer.phar self-update  
php composer.phar update

fuel/app/config/config.php内のコメントアウトを一部外します。

// 一部省略  
  
// プロファイラの無効化  
'profiling' => false,  
  
// ログ出力レベルの設定  
'log_threshold' => Fuel::L_WARNING,  
  
// モジュールの有効化  
'module_paths' => array(  
    APPPATH.'modules'.DS  
),  
  

memcachedの設定
fuel/core/config/cache.phpを修正します。

// 一部省略  
return array(  
  
    // default storage driver  
    'driver'      => 'memcached',  
  
    // default expiration (null = no expiration)  
    'expiration'  => '600',  
  
    // specific configuration settings for the memcached driver  
    'memcached'  => array(  
        'cache_id'  => 'fuel',  // unique id to distinquish fuel cache items from others stored on the same server(s)  
        'servers'   => array(   // array of servers and portnumbers that run the memcached service  
            'default' => array('host' => 'wonderpla.net.cache.amazonaws.com', 'port' => 11211, 'weight' => 100)  
        ),  
    ),  
);  

Redisの設定
fuel/core/config/db.phpを修正します。

// 一部省略  
return array(  
  
    /**  
     * Base Redis config  
     */  
    'redis' => array(  
        'default' => array(  
            'hostname'  => 'wonderpla.net.cache.amazonaws.com',  
            'port'      => 6379,  
            'timeout'   => null,  
        )  
    ),  
  
);  

HAPPY END!

今回はPHP5.4系でしたが、別の機会にPHP5.5系について書きたいと思います。