おぼえがき

おぼえがき

redisクラスタxマスタースレーブ構成でリアルタイムアクセス解析

2015-06-16 | php
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を利用した、リアルタイムアクセス解析を作ってみる。でした。おしまい