CentOS6.5にphpRedisAdminをインストール
開発中などに手軽にRedisに保存した値を確認できる便利な管理ツールをご紹介します。
その名もphpRedisAdmin!!
画面は2ペインのシンプルな構成でkey-valueの検索、追加、編集、削除が可能です。
管理画面
topページ
key-valueページ
phpRedisAdminのインストール
- phpRedisAdminのダウンロード
# cd # git clone https://github.com/ErikDubbelboer/phpRedisAdmin.git # cd phpRedisAdmin # git clone https://github.com/nrk/predis.git vendor
- phpRedisAdminをドキュメントルートにコピー
# cd # cp -r phpRedisAdmin /var/www/html
- phpRedisAdmin用のApache設定ファイル作成
- サーバを外部公開する場合は必要?
# vi /etc/httpd/conf.d/phpRedisAdmin.conf phpRedisAdmin.confの内容 ================================================================================ <Location /phpredisadmin> Order deny,allow Deny from all # 全て拒否 Allow from 127.0.0.1 # 自身からのアクセスを許可 Allow from 192.168.56.1 # 特定IPからのアクセスを許可(適宜変更して下さい) </Location> ================================================================================
- 動作確認
# vi /var/www/html/redis.php redis.phpの内容 ================================================================================ <?php $redis = new Redis(); $redis->connect('127.0.0.1', 6379); $val = array('key1'=>'value1', 'key2'=>'value2'); $redis->setex('key', 60 * 60, serialize($val)); // 有効期間 3600sec var_dump(unserialize($redis->get('key'))); ================================================================================
- http://192.168.56.101/redis.php にアクセスしてRedisに値を保存する。
- http://192.168.56.101/phpRedisAdmin/ にアクセスして管理画面が表示されることを確認する。
CentOS6.5にApache2.2+PHP5.4+Redis2.4をインストール
の続きです。
Apache2.2のインストール
# yum install httpd
- インストール内容の確認
# yum list installed | grep httpd httpd.x86_64 2.2.15-31.el6.centos httpd-tools.x86_64 2.2.15-31.el6.centos
- httpd.confの編集
# cp /etc/httpd/conf/httpd.conf /etc/httpd/conf/httpd.conf.bk # vi /etc/httpd/conf/httpd.conf ================================================================================ 修正前(338行目付近) AllowOverride None 修正後 AllowOverride ALL ================================================================================ ================================================================================ 修正前(402行目付近) DirectoryIndex index.html index.html.var 修正後 DirectoryIndex index.html index.php ================================================================================
- 自動起動設定
# chkconfig httpd on
- Apacheの起動
# /etc/init.d/httpd start
- 動作確認
- ブラウザで http://192.168.56.101/ にアクセスして「Apache 2 Test Page」の画面が表示されることを確認する。
PHP5.4のインストール
# yum install --enablerepo=remi php php-mysql php-mbstring php-gd php-redis php-pecl-apc
- インストール内容の確認
# yum list installed | grep php php.x86_64 5.4.31-1.el6.remi @remi php-cli.x86_64 5.4.31-1.el6.remi @remi php-common.x86_64 5.4.31-1.el6.remi @remi php-gd.x86_64 5.4.31-1.el6.remi @remi php-mbstring.x86_64 5.4.31-1.el6.remi @remi php-mysql.x86_64 5.4.31-1.el6.remi @remi php-pdo.x86_64 5.4.31-1.el6.remi @remi php-pear.noarch 1:1.9.5-2.el6.remi @remi php-pecl-apc.x86_64 3.1.15-0.4.20130912.el6.remi.5.4 php-pecl-igbinary.x86_64 php-pecl-redis.x86_64 php-process.x86_64 5.4.31-1.el6.remi @remi php-xml.x86_64 5.4.31-1.el6.remi @remi
- php.iniの編集
# cp /etc/php.ini /etc/php.ini.bk # vi /etc/php.ini ================================================================================ 文字コード設定 default_charset = "UTF-8" タイムゾーン設定 date.timezone = Asia/Tokyo エラー設定 display_errors = On error_log = /var/log/php.log マルチバイト文字設定 mbstring.language = Japanese mbstring.internal_encoding = UTF-8 mbstring.http_input = pass mbstring.http_output = pass mbstring.encoding_translation = Off mbstring.detect_order = UTF-8 mbstring.substitute_character = none ================================================================================
- エラーログファイル作成
# touch /var/log/php.log # chown apache:apache /var/log/php.log
- Apache再起動
# /etc/init.d/httpd restart
- 動作確認
# echo "<?php phpinfo(); ?>" > /var/www/html/phpinfo.php
- ブラウザで http://192.168.56.101/phpinfo.php にアクセスしてphpinfoの画面が表示されることを確認する。
Redisのインストール
# yum --enablerepo=epel install redis
- インストール内容の確認
# yum list installed | grep redis php-pecl-redis.x86_64 2.2.5-1.el6.remi.5.4 @remi redis.x86_64 2.4.10-1.el6 @epel
- 自動起動設定
# chkconfig redis on
- Redis起動
# /etc/init.d/redis start
- 動作確認
# echo '<?php $redis = new Redis(); if ($redis->connect("127.0.0.1", 6379)) print("redis connect OK"); ?>' > /var/www/html/redis.php
- ブラウザで http://192.168.56.101/redis.php にアクセスして「redis connect OK」が表示されることを確認する。
CentOS6.5にMySQL5.5をインストール
VirtualBoxにCentOS6.5をインストール ~ 初期設定 の続きです。
MySQL5.5のインストール
- remiリポジトリからMySQL5.5のインストール
# yum --enablerepo=remi install mysql mysql-server mysql-devel
- インストールの確認
# yum list installed | grep mysql compat-mysql51.x86_64 mysql.x86_64 5.5.39-1.el6.remi @remi mysql-devel.x86_64 5.5.39-1.el6.remi @remi mysql-libs.x86_64 5.5.39-1.el6.remi @remi mysql-server.x86_64 5.5.39-1.el6.remi @remi
初期設定
- my.cnfの編集
# cp /etc/my.cnf /etc/my.cnf.bk # vi /etc/my.cnf ================================================== [mysqld] character-set-server=utf8 # 追記する。 ==================================================
- 自動起動設定
# chkconfig mysqld on
- MySQL起動
# /etc/init.d/mysqld start
- セキュリティ周りの設定
# mysql_secure_installation ======================================================= Enter current password for root (enter for none): rootのパスワードは未設定なので Enterキー を押下する。 Set root password? [Y/n] rootのパスワードを設定するので Y を選択する。 New password: rootの新しいパスワードを入力する。 Re-enter new password: もう一度パスワードを入力する。 Remove anonymous users? [Y/n] 匿名ユーザは不要なので Y を選択する。 Disallow root login remotely? [Y/n] rootのリモートログインは不要なので Y を選択する。 Remove test database and access to it? [Y/n] testデータベースは不要なので Y を選択する。 Reload privilege tables now? [Y/n] 権限テーブルの再読み込みを行うので Y を選択する。 =======================================================
- ログインの確認
# mysql -u root -p[新しいパスワード]
接続用ユーザーの作成
- 以下のユーザーを作成する。
- ユーザ名:dev
- パスワード:dev001
mysql> grant all privileges on *.* to dev@'%' identified by 'dev001'; mysql> grant all privileges on *.* to dev@'localhost' identified by 'dev001'; mysql> grant all privileges on *.* to dev@'127.0.0.1' identified by 'dev001';
- 登録したユーザが存在するか確認
mysql> select user,host from mysql.user; +---------+-----------+ | user | host | +---------+-----------+ | dev | % | | dev | 127.0.0.1 | | root | 127.0.0.1 | | root | ::1 | | dev | localhost | | root | localhost | +---------+-----------+ 6 rows in set (0.00 sec)
- 一旦終了
mysql> exit;
- ログインの確認(作成したユーザーで再接続できればOK)
# mysql -u dev -pdev001
VirtualBoxにCentOS6.5をインストール ~ 初期設定
やりたいこと
- CentOS6.5を最小構成でVirtualBoxにインストールする。
- ターミナルソフトでsshログインできるようにする。
仮想マシンの作成
- VirtualBoxを起動する。
- 「新規」ボタンをクリックする。
- 仮想マシンを作成する。
- 名前とオペレーティングシステム
- メモリーサイズ
- 2048MB割り当てる(メモリサイズに応じて変更)
- 「次へ」ボタンを押下する。
- ハードドライブ
- 「仮想ハードドライブを作成する」を選択する。
- 「作成」ボタンを押下する。
- ハードドライブのファイルタイプ
- 「VDI(VirtualBox Disk Image)」を選択する。
- 「次へ」ボタンを押下する。
- 物理ハードドライブの作成
- 「可変サイズ」を選択する。
- 「次へ」ボタンを押下する。
- ファイルの場所とサイズ
- 8.00GBに設定する(ディスク容量に応じて変更)
- 「作成」ボタンを押下する。
CentOSのインストール
- VirtualBoxを起動する。
- 「設定」ボタンを押下する。
- 「ストレージ」を選択する。
- ストレージツリーの空となっている部分を選択する。
- 右側の属性CD/DVDドライブにあるCDのアイコンをクリックする。
- 「仮想CD/DVDディスクファイルの選択」を選択する。
- ダウンロードした「CentOS-6.5-x86_64-minimal.iso」を選択する。
- 「OK」ボタンを押下する。
- VirtualBoxのホーム画面に戻る。
- 「起動」ボタンを押下してCentOSを起動する。
- Welcome to CentOS 6.5!
- 「Install or upgrade an existing system」を選択する。
- Enterキーを押下する。
- Disc Found
- 「Skip」ボタンを押下する。
- CentOS6
- 「Next」ボタンを押下する。
- インストールで使用する言語
- 「japanese(日本語)」を選択する。
- 「次」ボタンを押下する。
- キーボード
- 「日本語」を選択する。
- 「次」ボタンを押下する。
- ストレージタイプ
- 「基本ストレージデバイス」を選択する。
- 「次」ボタンを押下する。
- ストレージデバイスの警告
- ホスト名
- ホスト名に「localhost.localdomain」を入力する。
- 「ネットワークの設定」ボタンを押下する。
- 「System eth0」を選択して「編集」ボタンを押下する。
- 「自動接続する」にチェックを付ける。
- 「適用」ボタンを押下する。
- 「閉じる」ボタンを押下する。
- 「次」ボタンを押下する。
- タイムゾーン
- 「アジア/東京」を選択する。
- 「システムクロックでUTCを使用」にチェックを付ける。
- 「次」ボタンを押下する。
- rootユーザのパスワード
- rootパスワードと確認に「root001」を入力する(パスワードは何でもよい)
- 「次」ボタンを押下する。
- 「パスワードが弱すぎる」ダイアログが表示されたら「とにかく使用する」ボタンを押下する。
- どのタイプのインストール?
- 「既存のLinuxシステムを入れ替える」を選択する。
- 「次」ボタンを押下する。
- 「ストレージ構成をディスクに書き込み中」ダイアログが表示されたら「変更をディスクに書き込む」ボタンを押下する。
- インストールが完了したら「再起動」ボタンを押下する。
- Welcome to CentOS 6.5!
- rootユーザでログインできることを確認する。
ネットワーク設定
- ホストオンリーアダプター追加
- VirtualBoxを起動する。
- 「設定」ボタンを押下する。
- 「ネットワーク」を選択する。
- 「アダプター2」タブをクリックする。
- ネットワーク設定を行う。
- 「ネットワークアダプターを有効化」にチェックを付ける。
- 割り当てに「ホストオンリーアダプター」を選択する。
- 名前に「VirtualBox Host-Only Ethernet Adapter」を選択する。
- 「高度」をクリックして下にある項目を展開する。
- MACアドレスをメモする。
- 「OK」ボタンを押下する。
- ifcfg-eth1作成
- CentOSを起動する。
- rootユーザでログインする。
- 次のコマンドを実行する。
# cd /etc/sysconfig/network-scripts # vi ifcfg-eth1 =================================== DEVICE=eth1 TYPE=Ethernet ONBOOT=yes BOOTPROTO=static HWADDR=08:00:27:F5:9E:07 # メモしたMACアドレスを記載 NAME="System eth1" IPADDR=192.168.56.101 # 適当でよい NETMASK=255.255.255.0 NETWORK=192.168.56.0 =================================== # ifup eth1
CentOS設定
- iptables停止
# service iptables stop # chkconfig iptables off
- SELinux停止
# setenforce 0 # vi /etc/sysconfig/selinux =================================== 修正前 SELINUX=enforcing 修正後 SELINUX=disabled ===================================
- 再起動
# shutdown -r now
- CentOSの更新
# yum -y update
- パッケージグループのインストール
# yum groupinstall "Base" # yum groupinstall "Development tools" # yum groupinstall "Japanese Support"
# rpm -ivh http://ftp-srv2.kddilabs.jp/Linux/distributions/fedora/epel/6/x86_64/epel-release-6-8.noarch.rpm # rpm -ivh http://pkgs.repoforge.org/rpmforge-release/rpmforge-release-0.5.3-1.el6.rf.x86_64.rpm # rpm -ivh http://rpms.famillecollet.com/enterprise/remi-release-6.rpm enabled=1になっている箇所を全てenabled=0に変更する。 # vi /etc/yum.repos.d/epel.repo # vi /etc/yum.repos.d/rpmforge.repo # vi /etc/yum.repos.d/remi.repo リポジトリを指定する場合は次のようにする。 # yum --enablerepo=epel install XXXX # yum --enablerepo=rpmforge install XXXX # yum --enablerepo=remi install XXXX
- ユーザ作成
# useradd admin # passwd admin # usermod -G wheel admin # visudo =================================== 修正前 # %wheel ALL=(ALL) ALL 修正後(コメントを外す) %wheel ALL=(ALL) ALL =================================== # chmod 755 /home/admin
- 設定後、adminユーザがログインできること、rootユーザになれることを確認する。
CakePHP2.x系で多次元(三次元)配列をソートする
array_multisort関数を使用した二次元配列のソートはネット上によくあるのですが、三次元配列のソートに言及しているところはほとんどなかったので自作してみました。
CakePHPはモデルメソッドの戻り値が[インデックス][モデル名][フィールド名]のような三次元配列で表現されることが多いので利用できるシチュエーションは多いと思います。
また、CakePHPにはHash::sortという多次元配列をソートできるメソッドが存在するのですが、ソート対象のフィールドを1つしか指定できないため若干不便です。そのため自作したメソッドは何個でもフィールドを指定できるようにしています。
サンプルプログラム
ソートメソッドの使用例
<?php public function index() { // ソート対象配列(Model::findの戻り値を想定) $models = array(); // 1レコード目 $models[0]['A']['field_a_1'] = '4'; $models[0]['A']['field_a_2'] = '1'; $models[0]['B']['field_b_1'] = '2'; // 2レコード目 $models[1]['A']['field_a_1'] = '30'; $models[1]['A']['field_a_2'] = '1'; $models[1]['B']['field_b_1'] = '4'; // 3レコード目 $models[2]['A']['field_a_1'] = '30'; $models[2]['A']['field_a_2'] = '2'; $models[2]['B']['field_b_1'] = '6'; // 4レコード目 $models[3]['A']['field_a_1'] = '9'; $models[3]['A']['field_a_2'] = '3'; $models[3]['B']['field_b_1'] = '6'; // 多次元配列ソート $result = Common::sortArr($models, '{n}.A.field_a_1', SORT_ASC, '{n}.B.field_b_1', SORT_DESC); debug($result); /* array( (int) 0 => array( 'A' => array( 'field_a_1' => '4', 'field_a_2' => '1' ), 'B' => array( 'field_b_1' => '2' ) ), (int) 1 => array( 'A' => array( 'field_a_1' => '9', 'field_a_2' => '3' ), 'B' => array( 'field_b_1' => '6' ) ), (int) 2 => array( 'A' => array( 'field_a_1' => '30', 'field_a_2' => '2' ), 'B' => array( 'field_b_1' => '6' ) ), (int) 3 => array( 'A' => array( 'field_a_1' => '30', 'field_a_2' => '1' ), 'B' => array( 'field_b_1' => '4' ) ) ) */ exit; }
Common::sortArrがソートを行うメソッドです。
この手のコントローラやモデルなど様々なところで利用されるメソッドはapp/Vendorディレクトリの下にCommonクラス(名前は何でもよい)を作成して、その中でメソッドを定義すると使い勝手がよいと思います。
Common::sortArrメソッドの引数
第一引数にはソート対象配列を指定します。
第二引数(第四引数、、)はソート対象フィールドをCakePHPのHashパスで指定します。
Hashパスがわからない方は下のサイトを参考にして下さい。
■Hash — CakePHP Cookbook 2.x ドキュメント
http://book.cakephp.org/2.0/ja/core-utility-libraries/hash.html
Hashクラスには配列を操作するための便利なメソッドが沢山あり、特にHash::extractは本当によく使用します!!
第三引数(第五引数、、)は昇順ソートしたい場合はSORT_ASC、降順ソートしたい場合はSORT_DESCを指定します。
ソートメソッドの定義
<?php /** * 多次元配列ソート * @param ソート対象配列、Hashパス、ソート方法(Hashパス、ソート方法は可変) * @return ソート後の多次元配列 */ public static function sortArr() { // 引数取得 $args = func_get_args(); // ソート対象配列取得 $data = array_shift($args); // ソート対象配列のキー取得(これをソートする) $orgKeys = array_keys($data); // ソート対象配列のキーをソート $params = array(); $argc = count($args); for ($i = 0; $i < $argc; $i += 2) { $params[] = Hash::extract($data, $args[$i]); $params[] = $args[$i + 1]; $params[] = SORT_NATURAL; } $params[] = &$orgKeys; call_user_func_array('array_multisort', $params); // ソート後のソート対象配列のキーを取得 $sortedData = array_pop($params); // ソート後のキーを使用してソート対象配列をソートする $result = array(); foreach ($sortedData as $s) { $result[] = $data[$s]; } return $result; }
結局、array_multisort関数を使用してソートしています(;´・ω・)
配列そのものではなく、配列のキーをソートしているのがポイントです。
ソート後はソートされたキーの順番で配列要素を取り出して、あたかも配列自体をソートしたかのように見せています。
あと「SORT_NATURAL」は自然順を意味しており、以下のサイトのarray1_sort_flagsのフラグ定数であれば何でも設定できます。
■PHP: array_multisort - Manual
http://www.php.net/manual/ja/function.array-multisort.php
これについては状況に応じて「SORT_REGULAR」や「SORT_NUMERIC」などを設定してください。
パラメータにして外部から渡すようにした方が汎用性が高まってよいかもしれません。
最後に
このメソッドを使うメリットの一つは、Model::findメソッドなどでORDER BY句を指定する必要がなくなるということです。
インデックスを張っていないカラムをORDER BY句に含めると、EXPLAINのExtraフィールドにusing filesortが発生することがあります。
処理件数が少ない場合であればメモリ内で処理が完結するので気にしなくてよいですが、処理件数が多い場合は対策を講じる必要があります。
一番簡単な対策はインデックスを張ることですが、ディスク容量の増加・更新処理による負荷の増大などを考慮する必要があります(ここら辺はサーバスペック次第ですが。。)
またソーシャルゲームでありがちなカードのID順・レアリティ順・入手順などのように複数のソートがある場合、その全てに対応したインデックスを張るのは現実的ではありません。
そういった場合や少しでもDB負荷を軽くしたい場合は、SQLではなくアプリ側でソート処理を行った方がよいと思います^^