昨今じゃ当たり前になった NoSQL ってやつですが、自分はどうも使う機会が無かったというか、フツーに RDB 使ったほうが目的に叶うケースが多かったので memcached でさえ殆ど手を触れずに今日まで来ました。それがやっと先ごろ、NoSQL なシチュエーションが発生!という訳で、人生初 NoSQL の作業メモです。
要件は、各所から発生するデータをそのまま RDB に書き込むと諸事情で色々と嬉しくないので、いったんバッファに溜めておいて専用のデータストア用プログラム経由で逐次 RDB に格納するというものです。古いものから順に読み出す必要があるので、所謂 FIFO (First In First Out) バッファですな。memcached は万一のデータ消失が怖いので、最近評判が良いらしい Redis を採用。
まずは環境づくりから。当方の AWS EC2 な LAMP サーバにて、Redis を PHP から使えるようにします。Redis 関係は EPEL リポジトリにしか無いようなので、それを指定して yum でインスコします。
% sudo yum --enablerepo=epel -y install redis
Redis サーバを起動して、ブート時の設定も忘れずに。
% sudo service redis start
% sudo chkconfig redis on
で、動作確認…
$ redis-cli redis 127.0.0.1:6379> info redis_version:2.4.10 (省略) redis 127.0.0.1:6379> exit
よし、OK。
PHP の Redis 用モジュールのほうも同様にインスコ。
% sudo yum --enablerepo=epel -y install php-pecl-redis % sudo service httpd reload
以上で環境が整ったので、プログラムを書きます。Redis は色々なデータ型が用意されていますが、FIFO バッファは Lists 型を使って実現できるとここにあったので、これに倣って LPUSH で書き込み、RPOP で読み出すことにします。RDB 用のデータを Redis に書き込む側はこんな感じ。
$data = array(':name' => $name, ':email' => $email, ':created' => date('Y-m-d H:i:s')); //テーブル列名 => 値、な1レコードぶんのデータ $redis = new Redis(); $redis->connect('localhost'); $redis->lPush('mykey', json_encode($data)); //JSON に変換して Redis に保存
Redis → RDB の処理側はこんな感じ。
$redis = new Redis(); $redis->connect('localhost'); $pdo = new PDO('mysql:host=localhost;dbname=my_db', 'login_name', 'login_pw'); $stmt = $pdo->prepare('INSERT INTO my_table (name, email, created) VALUES (:name, :email, :created)'); while ($data = $redis->rPop('mykey')) { //有るだけ読み出しては RDB に追加 $data = json_decode($data, true); $stmt->execute($data); }
とまぁ、こんな具合です。実にシンプルな利用ケースなので一寸物足りない気もw 他のデータ型も使ってみたいなー。