俺です。
Redisバージョン: 3.0.5
Redis内のデータがnGB超えていたのでチューニングする。
repl-timeoutはRedisのデータサイズに応じて長めに設定したものの、
slave再接続時にmasterで実行されるdisk出力のbgsaveを抑える方法があったので検証した。
参考 m(__)m
検証結果
- nGB超のデータを扱う際はディスクレスレプリケーションが有効です。
- ディスクレスレプリケーションであればmasterで一時ダンプは出力されないので
cached memory
は消費しません - デフォルトのレプリケーションに比べてFull syncの時間が1/2になりました。
- 本例(master/slave関係)ではmasterのノードにのみディスクレスレプリケーションのパラメータをセットしましたが、Sentinelを利用する場合は全Redisノードに対して設定しておくのが良いと思います
準備
ターゲットインスタンス
- r3.xlarge
データサイズ
RedisのデータはYCSBで作ったダミーデータ.サイズ 20GB
カーネルパラメータ
master/slave共に下記が有効
vm.swappiness=1
vm.overcommit_memory=1
- redis.conf(master/slave)
デフォルト値にrepl-timeoutを追加
repl-timeout 1800
- redis.conf(slave)
slaveof <master ipaddr> 6379
通常のreplication
- 検証手順
Redis masterを起動し、20GBのデータをロードする
Redis slaveを起動し、Redis masterとレプリケーションする
ps aux|grep redis
, redis-cli info
とredis.log
を確認する
masterの挙動
- slaveを起動してmasterへ接続する時にmasterでbgsaveを実行する
Full resync target: disk
となっている
一度masterでrdbファイルを出力/作成し、slaveのrdbディレクトリへ転送している模様
- masterのプロセス確認
masterではbgsaveが動作している
[root@ip-172-31-5-23 lib]# ps aux|grep redis
redis 6921 13.3 64.8 20516304 20375152 ? Ssl 02:34 1:18 /usr/bin/redis-server *:6379
root 6958 0.0 0.0 107932 616 pts/1 S+ 02:39 0:00 tail -f redis.log
redis 6969 95.4 64.8 20516692 20374780 ? R 02:43 0:42 redis-rdb-bgsave *:6379
root 6975 0.0 0.0 114632 920 pts/0 S+ 02:43 0:00 grep redis
6921:M 30 Nov 02:43:08.540 - Accepted 172.31.13.112:34156
6921:M 30 Nov 02:43:08.541 * Slave 172.31.13.112:6379 asks for synchronization
6921:M 30 Nov 02:43:08.541 * Full resync requested by slave 172.31.13.112:6379
6921:M 30 Nov 02:43:08.541 * Starting BGSAVE for SYNC with target: disk
6921:M 30 Nov 02:43:08.778 * Background saving started by pid 6969
..省略
6921:M 30 Nov 02:51:40.880 * Synchronization with slave 172.31.13.112:6379 succeeded
slaveの挙動
- redis.log
3099:S 30 Nov 02:43:08.530 * Connecting to MASTER 172.31.5.23:6379
3099:S 30 Nov 02:43:08.530 * MASTER <-> SLAVE sync started
3099:S 30 Nov 02:43:08.530 * Non blocking connect for SYNC fired the event.
3099:S 30 Nov 02:43:08.530 * Master replied to PING, replication can continue...
3099:S 30 Nov 02:43:08.530 * Partial resynchronization not possible (no cached master)
3099:S 30 Nov 02:43:08.769 * Full resync from master: 61865c4afa66868ceee549a5fb1ebfc1020e934a:1
..省略
3099:S 30 Nov 02:51:40.977 * MASTER <-> SLAVE sync: Flushing old data
3099:S 30 Nov 02:51:54.437 * MASTER <-> SLAVE sync: Loading DB in memory
3099:S 30 Nov 02:53:56.212 - Accepted 127.0.0.1:42239
3099:S 30 Nov 02:53:56.225 - Client closed connection
3099:S 30 Nov 02:54:40.104 * MASTER <-> SLAVE sync: Finished with success
diskless replication
事前に下記パラメータをセットする
パラメータドキュメントはgithubを参照
レプリケーションタイムアウトの調整
redis-cli CONFIG SET repl-timeout "1800"
ディスクレスレプリケーションの有効化
redis-cli CONFIG SET repl-diskless-sync "yes"
repl-diskless-sync-delayを0にする
スレーブ接続時の待ち時間をなしにする。
redis-cli CONFIG SET repl-diskless-sync-delay 0
バッファリミットを無効化
クライアント(slave)が強制切断されないようにバッファリミットを無効にする
redis-cli CONFIG SET client-output-buffer-limit "slave 0 0 0"
masterの挙動
slaveを起動してmasterへ接続する時にmasterでbgsaveを実行する
masterのプロセス確認
masterではredis-rdb-to-slaves
が動作している
[root@ip-172-31-5-23 lib]# ps aux|grep redis
redis 6921 5.1 64.8 20516304 20375188 ? Ssl 02:34 1:31 /usr/bin/redis-server *:6379
redis 7103 79.4 64.8 20516688 20374632 ? R 03:01 1:48 redis-rdb-to-slaves *:6379
root 7115 0.0 0.0 114632 924 pts/0 R+ 03:03 0:00 grep redis
- redis.log
Starting BGSAVE for SYNC with target: slaves sockets
となっている
slaveのsocketへ直接BGSAVEのダンプを転送している模様
6921:M 30 Nov 03:01:34.496 # Connection with slave client id #33 lost.
6921:M 30 Nov 03:01:34.522 - Accepted 172.31.13.112:34189
6921:M 30 Nov 03:01:34.522 * Slave 172.31.13.112:6379 asks for synchronization
6921:M 30 Nov 03:01:34.522 * Full resync requested by slave 172.31.13.112:6379
6921:M 30 Nov 03:01:35.220 * Starting BGSAVE for SYNC with target: slaves sockets
6921:M 30 Nov 03:01:35.459 * Background RDB transfer started by pid 7103
6921:M 30 Nov 03:05:03.333 * Background RDB transfer terminated with success
6921:M 30 Nov 03:05:03.333 # Slave 172.31.13.112:6379 correctly received the streamed RDB file.
6921:M 30 Nov 03:05:03.333 * Streamed RDB transfer with slave 172.31.13.112:6379 succeeded (socket). Waiting for REPLCONF ACK from slave to
enable streaming
..省略..
6921:M 30 Nov 03:06:19.609 * Synchronization with slave 172.31.13.112:6379 succeeded
slaveのredis.log
3305:S 30 Nov 03:01:34.514 * Connecting to MASTER 172.31.5.23:6379
3305:S 30 Nov 03:01:34.514 * MASTER <-> SLAVE sync started
3305:S 30 Nov 03:01:34.515 * Non blocking connect for SYNC fired the event.
3305:S 30 Nov 03:01:34.515 * Master replied to PING, replication can continue...
3305:S 30 Nov 03:01:34.515 * Partial resynchronization not possible (no cached master)
3305:S 30 Nov 03:01:35.213 * Full resync from master: 61865c4afa66868ceee549a5fb1ebfc1020e934a:1429
3305:S 30 Nov 03:01:35.454 * MASTER <-> SLAVE sync: receiving streamed RDB from master
..省略..
3305:S 30 Nov 03:05:02.855 * MASTER <-> SLAVE sync: Flushing old data
3305:S 30 Nov 03:05:02.855 * MASTER <-> SLAVE sync: Loading DB in memory
3305:S 30 Nov 03:06:19.096 * MASTER <-> SLAVE sync: Finished with success
参考 Redis Full resync中のslaveステータス遷移
redis-cli info replication
の結果
- masterで実行
Master bgsave中のステータス
slaveはwait_bgsaveになっている
# Replication
role:master
connected_slaves:1
slave0:ip=172.31.13.112,port=6379,state=wait_bgsave,offset=0,lag=0
master_repl_offset:253
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2
repl_backlog_histlen:252
↓
bgsave完了後、バルクロードが開始される。
send_bulkに変更される
[root@ip-172-31-5-23 lib]# redis-cli info replication
# Replication
role:master
connected_slaves:1
slave0:ip=172.31.13.112,port=6379,state=send_bulk,offset=0,lag=0
master_repl_offset:337
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2
repl_backlog_histlen:336
↓
onlineに変更される
[root@ip-172-31-5-23 lib]# redis-cli info replication
# Replication
role:master
connected_slaves:1
slave0:ip=172.31.13.112,port=6379,state=online,offset=1051,lag=1
master_repl_offset:1051
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2
repl_backlog_histlen:1050