redis cluster を マスタースレーブ構成でレプリケーション張って、php-redisを利用した、リアルタイムアクセス解析を作ってみた。
■構成
サーバー全部で6台
3台でクラスタ構成その下にスレーブをぶら下げる
■永続性
まだ、怖いから1日に1回データをフラッシュさせる
■データ構成
データ型 sorted set
キー access_monitor:id:${ユーザーID}
スコア unixtime
バリュー アクセスされたURL\x09リファラ\x09アクセスしてきたID\x09unixtime(タブ区切り)
スコアに、unixtimeを入れることにより、最新のアクセス順みたいな感じでデータが取れる
■インストール
redis 3.01
php-redisは、クラスタ構成 に対応していないから(2015/06/16現在)、ここから、もってきてクラスタ構成用の、RedisClusterが動くように無理やりやる
他にも、jemalloc-devel(3.6.0.1)も入れた
■クラスタを作る
sudo ./redis-trib.rb create --replicas 1 IPアドレス:ポート IPアドレス:ポート IPアドレス:ポート
※redis-trib.rbは、redis本家のソースコードの中に入ってる。
初めは、sudo gem install redisしてあげる必要がある。
□クラスタが上手く作れないその1
こんなエラーが出たときは、
client.rb:113:in `call': ERR Slot 16011 is already busy (Redis::CommandError)
redis-cli -c
>select 0
>flushdb
>flushall
をやると、クラスタ作れる。
ただし、対象クラスタ全部やったほうが良い
□クラスタが作れないその2
クラスタを作るとき、nodes.confを作ると思うけど、再構築する際は、こいつの中身消したほうが良い
他にも、
17067: * Increased maximum number of open files to 10032 (it was originally set to 1024).
17067: * Node configuration loaded, I'm xxxxxe94c3dc311e558e3015ff1e51fe362c530d
17067: # Creating Server TCP listening socket *:16379: bind: Address already in use
とか、出たけど
全体の流れとして、
slect 0
flusdb
flushall
とかで、データ全部消して、
/etc/init.d/redis restart
:>nodes.conf (ファイルの中身消す)
で、
sudo ./redis-trib.rb create --replicas 1 IPアドレス:ポート IPアドレス:ポート IPアドレス:ポート IPアドレス:ポート IPアドレス:ポート IPアドレス:ポート
こんな感じで作れるはず
■redis.conf
こんな感じにした(自信なし)
=====
daemonize no
pidfile /var/run/redis.pid
port 6379
tcp-backlog 511
timeout 300
tcp-keepalive 60
loglevel notice
logfile /var/log/redis/redis.log
databases 16
### SNAPSHOTTING
save ""
dir /var/lib/redis/
####REPLICATION
slave-serve-stale-data yes
slave-read-only yes
repl-diskless-sync yes
repl-diskless-sync-delay 5
repl-disable-tcp-nodelay no
slave-priority 100
### SECURITY
### LIMITS
maxclients 10000
maxmemory 1g
maxmemory-policy volatile-ttl
maxmemory-samples 5
###APPEND ONLY MODE
appendonly no
appendfsync no
no-appendfsync-on-rewrite no
###LUA SCRIPTING
lua-time-limit 5000
###REDIS CLUSTER
cluster-enabled yes
cluster-config-file /etc/redis/nodes.conf
cluster-node-timeout 5000
###SLOW LOG
slowlog-log-slower-than 10000
slowlog-max-len 128
####LATENCY MONITOR
latency-monitor-threshold 0
###EVENT NOTIFICATION
notify-keyspace-events ""
### ADVANCED CONFIG
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
list-max-ziplist-entries 512
list-max-ziplist-value 64
set-max-intset-entries 512
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
hll-sparse-max-bytes 3000
activerehashing yes
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit slave 256mb 64mb 60
#client-output-buffer-limit pubsub 32mb 8mb 60
hz 10
aof-rewrite-incremental-fsync no
=====
■php-redisを利用してみる
define('REDIS_CONNECT_PORT' , 'srv101:6379,srv102:6379,srv103:6379,srv104:6379,srv105:6379,srv106:6379');
#アクセス情報をredisクラスタに格納
$port=explode( ',' , REDIS_CONNECT_PORT );
$redis_obj = new RedisCluster('cluster', $port);
$redis_obj->zadd(${KEY}, $unixtime_now, $value);
#最新のアクセス順で取得(スコアも一緒に取得)
$redis_obj->zrangebyscore(${KEY}, $unixtime_from, $unixtime_to, array('withscores' => TRUE));
■tips
・php-redis入れたら、apacheリスタート
・データの一括投入(クラスタ構成だと、一部しかはいらないよ)
perl -pe "s/\n/\r\n/g" ファイル | redis-cli --pipe -c
上記コマンド、ファイルの中身
set key_1 val1
set key_2 val2
・フェイルオーバー
マスターのクラスタの一台が死んだ場合、対応しているスレーブが自動でマスターに昇格。
死んだマスターを復活させたら、今度は、スレーブとして起動するようになる(すごいね)
・クラスタの構成確認
cluster nodes
・メモリ使用量の確認
infoで、used_memoryを確認
・日本語入れてみる
redis-cli -c
127.0.0.1:6383> get title
"\xa4\xa4\xa4\xa4\xa4\xa4"
ってなかんじで、日本語が文字化けてしまう
redis-cli -c --raw
127.0.0.1:6383> get title
いいい
ちゃんと出る
・hash型にデータの一括投入
$filed_values = array(
'id' => ${id},
'title' => ${title}
);
$redis_obj->hmset(${KEY}, $filed_values);
■アクセス解析に使った他のredisの型
zincrby(${KEY} . YYYYMMDDHH, 1, "/ページのurl");
これで、○時のアクセスランキング作れちゃう
以上、redis cluster x m-s構成でphp-redisを利用した、リアルタイムアクセス解析を作ってみる。でした。おしまい
■構成
サーバー全部で6台
3台でクラスタ構成その下にスレーブをぶら下げる
■永続性
まだ、怖いから1日に1回データをフラッシュさせる
■データ構成
データ型 sorted set
キー access_monitor:id:${ユーザーID}
スコア unixtime
バリュー アクセスされたURL\x09リファラ\x09アクセスしてきたID\x09unixtime(タブ区切り)
スコアに、unixtimeを入れることにより、最新のアクセス順みたいな感じでデータが取れる
■インストール
redis 3.01
php-redisは、クラスタ構成 に対応していないから(2015/06/16現在)、ここから、もってきてクラスタ構成用の、RedisClusterが動くように無理やりやる
他にも、jemalloc-devel(3.6.0.1)も入れた
■クラスタを作る
sudo ./redis-trib.rb create --replicas 1 IPアドレス:ポート IPアドレス:ポート IPアドレス:ポート
※redis-trib.rbは、redis本家のソースコードの中に入ってる。
初めは、sudo gem install redisしてあげる必要がある。
□クラスタが上手く作れないその1
こんなエラーが出たときは、
client.rb:113:in `call': ERR Slot 16011 is already busy (Redis::CommandError)
redis-cli -c
>select 0
>flushdb
>flushall
をやると、クラスタ作れる。
ただし、対象クラスタ全部やったほうが良い
□クラスタが作れないその2
クラスタを作るとき、nodes.confを作ると思うけど、再構築する際は、こいつの中身消したほうが良い
他にも、
17067: * Increased maximum number of open files to 10032 (it was originally set to 1024).
17067: * Node configuration loaded, I'm xxxxxe94c3dc311e558e3015ff1e51fe362c530d
17067: # Creating Server TCP listening socket *:16379: bind: Address already in use
とか、出たけど
全体の流れとして、
slect 0
flusdb
flushall
とかで、データ全部消して、
/etc/init.d/redis restart
:>nodes.conf (ファイルの中身消す)
で、
sudo ./redis-trib.rb create --replicas 1 IPアドレス:ポート IPアドレス:ポート IPアドレス:ポート IPアドレス:ポート IPアドレス:ポート IPアドレス:ポート
こんな感じで作れるはず
■redis.conf
こんな感じにした(自信なし)
=====
daemonize no
pidfile /var/run/redis.pid
port 6379
tcp-backlog 511
timeout 300
tcp-keepalive 60
loglevel notice
logfile /var/log/redis/redis.log
databases 16
### SNAPSHOTTING
save ""
dir /var/lib/redis/
####REPLICATION
slave-serve-stale-data yes
slave-read-only yes
repl-diskless-sync yes
repl-diskless-sync-delay 5
repl-disable-tcp-nodelay no
slave-priority 100
### SECURITY
### LIMITS
maxclients 10000
maxmemory 1g
maxmemory-policy volatile-ttl
maxmemory-samples 5
###APPEND ONLY MODE
appendonly no
appendfsync no
no-appendfsync-on-rewrite no
###LUA SCRIPTING
lua-time-limit 5000
###REDIS CLUSTER
cluster-enabled yes
cluster-config-file /etc/redis/nodes.conf
cluster-node-timeout 5000
###SLOW LOG
slowlog-log-slower-than 10000
slowlog-max-len 128
####LATENCY MONITOR
latency-monitor-threshold 0
###EVENT NOTIFICATION
notify-keyspace-events ""
### ADVANCED CONFIG
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
list-max-ziplist-entries 512
list-max-ziplist-value 64
set-max-intset-entries 512
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
hll-sparse-max-bytes 3000
activerehashing yes
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit slave 256mb 64mb 60
#client-output-buffer-limit pubsub 32mb 8mb 60
hz 10
aof-rewrite-incremental-fsync no
=====
■php-redisを利用してみる
define('REDIS_CONNECT_PORT' , 'srv101:6379,srv102:6379,srv103:6379,srv104:6379,srv105:6379,srv106:6379');
#アクセス情報をredisクラスタに格納
$port=explode( ',' , REDIS_CONNECT_PORT );
$redis_obj = new RedisCluster('cluster', $port);
$redis_obj->zadd(${KEY}, $unixtime_now, $value);
#最新のアクセス順で取得(スコアも一緒に取得)
$redis_obj->zrangebyscore(${KEY}, $unixtime_from, $unixtime_to, array('withscores' => TRUE));
■tips
・php-redis入れたら、apacheリスタート
・データの一括投入(クラスタ構成だと、一部しかはいらないよ)
perl -pe "s/\n/\r\n/g" ファイル | redis-cli --pipe -c
上記コマンド、ファイルの中身
set key_1 val1
set key_2 val2
・フェイルオーバー
マスターのクラスタの一台が死んだ場合、対応しているスレーブが自動でマスターに昇格。
死んだマスターを復活させたら、今度は、スレーブとして起動するようになる(すごいね)
・クラスタの構成確認
cluster nodes
・メモリ使用量の確認
infoで、used_memoryを確認
・日本語入れてみる
redis-cli -c
127.0.0.1:6383> get title
"\xa4\xa4\xa4\xa4\xa4\xa4"
ってなかんじで、日本語が文字化けてしまう
redis-cli -c --raw
127.0.0.1:6383> get title
いいい
ちゃんと出る
・hash型にデータの一括投入
$filed_values = array(
'id' => ${id},
'title' => ${title}
);
$redis_obj->hmset(${KEY}, $filed_values);
■アクセス解析に使った他のredisの型
zincrby(${KEY} . YYYYMMDDHH, 1, "/ページのurl");
これで、○時のアクセスランキング作れちゃう
以上、redis cluster x m-s構成でphp-redisを利用した、リアルタイムアクセス解析を作ってみる。でした。おしまい