3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Redisでレプリケーションを設定する

Last updated at Posted at 2019-09-18

TL;DR

  • Redisは、データのレプリケーションが可能
  • 永続化を有効にしていない場合、マスターの自動再起動設定を行わないこと
  • マスターのフェイルオーバーを行いたい場合は、Redis ClusterやRedis Sentinelを検討すること

Redisのレプリケーション

文字通り、Redisにマスター、レプリカの役割を持たせることができます。

ドキュメントは、こちらです。

Replication

いくつか、ポイントが書かれています。

まずは、動作について。

  • マスター・レプリカ間が接続できている場合、マスターからレプリカへデータの変更(書き込み、有効期限切れなど)の更新コマンドを送信する
  • ネットワーク的に、マスターとレプリカが分断されても、復旧して接続できればレプリカは部分的な同期を試みる
    • 部分的な同期が不可能な場合、レプリカは完全な再同期が必要となり、マスターにデータのスナップショットの作成と送信、以後の継続的な更新イベントの送信を要求する

マスター障害時のフェイルオーバーなど、いわゆるHA的なことはできません。こちらが必要な場合は、Redis ClusterまたはRedis Sentinelを検討することになります。

その他、レプリケーションの特徴や注意点はこんな感じです。

  • 非同期で動作する
  • マスターに対して、レプリカは複数存在することができる
  • レプリケーションは、マスター、レプリカそれぞれでノンブロッキングで動作する
    • レプリケーション中に、マスターは継続してクエリを処理可能
    • レプリカ側で、大きなデータセットをロードする必要が出てきた場合は、ブロックが発生するパターンがある
  • マスターが再起動した時に、空のデータセットで処理を受け付けられるようになった場合、空のデータセットがレプリカへ同期され、レプリカ側も空になることになるので注意

とりあえず、こんなところまで調べてみたので、実際に動かしてみましょう。

環境

今回の確認環境。

$ cat /etc/redhat-release 
CentOS Linux release 7.6.1810 (Core)


$ uname -a
Linux localhost.localdomain 3.10.0-957.12.2.el7.x86_64 #1 SMP Tue May 14 21:24:32 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux


$ redis-server -v
Redis server v=5.0.5 sha=00000000:0 malloc=jemalloc-5.1.0 bits=64 build=619d60bfb0a92c36

サーバーは2台用意し、以下とします。

  • マスター … 192.168.33.10
  • レプリカ … 192.168.33.11

CentOSへRedisをインストールする

Remi Repositoryから、可能な限り新しいRedisをインストールします。

$ sudo yum install epel-release
$ sudo yum install https://rpms.remirepo.net/enterprise/remi-release-7.rpm
$ sudo yum --enablerepo=remi install redis

マスターの設定

/etc/redis.confを修正。

今回は、まずはバインドするIPアドレスのみ修正します。

bind 0.0.0.0

ちなみに、Remi RepositoryからインストールしたRedis 5.0.5のデフォルト設定はこんな感じでした。

$ sudo grep -v '#' /etc/redis.conf | grep -v '^$'
bind 127.0.0.1
protected-mode yes
port 6379
tcp-backlog 511
timeout 0
tcp-keepalive 300
daemonize no
supervised no
pidfile /var/run/redis_6379.pid
loglevel notice
logfile /var/log/redis/redis.log
databases 16
always-show-logo yes
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb
dir /var/lib/redis
replica-serve-stale-data yes
replica-read-only yes
repl-diskless-sync no
repl-diskless-sync-delay 5
repl-disable-tcp-nodelay no
replica-priority 100
lazyfree-lazy-eviction no
lazyfree-lazy-expire no
lazyfree-lazy-server-del no
replica-lazy-flush no
appendonly no
appendfilename "appendonly.aof"
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
aof-load-truncated yes
aof-use-rdb-preamble yes
lua-time-limit 5000
slowlog-log-slower-than 10000
slowlog-max-len 128
latency-monitor-threshold 0
notify-keyspace-events ""
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
list-max-ziplist-size -2
list-compress-depth 0
set-max-intset-entries 512
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
hll-sparse-max-bytes 3000
stream-node-max-bytes 4096
stream-node-max-entries 100
activerehashing yes
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit replica 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60
hz 10
dynamic-hz yes
aof-rewrite-incremental-fsync yes
rdb-save-incremental-fsync yes

Redis起動。

$ sudo systemctl start redis

接続。

$ redis-cli -h 192.168.33.10

データを入れて、確認。

192.168.33.10:6379> set key1 value1
OK

192.168.33.10:6379> set key2 value2
OK

192.168.33.10:6379> keys *
1) "key1"
2) "key2"

レプリカを設定する

レプリカ側では、/etc/redis.confbind以外にreplicaofを指定します。

replicaof 192.168.33.10 6379

replicaofに指定するのは、マスターのIPアドレス(またはホスト名)とポートです。

レプリカ側のRedis起動。

$ sudo systemctl start redis

接続。

$ redis-cli -h 192.168.33.11

すでにデータが入っています。

192.168.33.11:6379> get key1
"value1"
192.168.33.11:6379> get key2
"value2"

Remi RepositoryからインストールしたRedisでは、デフォルト設定でreplica-read-onlyyesになっているのでレプリカ側で書き込みを行うことができません。

192.168.33.11:6379> set key3 value3
(error) READONLY You can't write against a read only replica.

レプリケーションの情報を見るには、info replicationで。

マスター側で実行した場合。

$ redis-cli -h 192.168.33.10
192.168.33.10:6379> info replication
# Replication
role:master
connected_slaves:1
slave0:ip=192.168.33.11,port=6379,state=online,offset=135,lag=1
master_replid:0bff47e7ae6b3513e56f6f7f1b571fdc8b668418
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:135
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:135

レプリカ側で実行した場合。

$ redis-cli -h 192.168.33.11 
192.168.33.11:6379> info replication
# Replication
role:slave
master_host:192.168.33.10
master_port:6379
master_link_status:up
master_last_io_seconds_ago:3
master_sync_in_progress:0
slave_repl_offset:135
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:0bff47e7ae6b3513e56f6f7f1b571fdc8b668418
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:135
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:135

永続化をオフにして、マスターを再起動してみる

試しに、設定ファイルをこれくらいシンプルにしてRDBファイルは1度削除。

マスター側。

bind 0.0.0.0
pidfile /var/run/redis_6379.pid
loglevel notice
logfile /var/log/redis/redis.log
dbfilename dump.rdb
dir /var/lib/redis

レプリカ側。

bind 0.0.0.0
pidfile /var/run/redis_6379.pid
loglevel notice
logfile /var/log/redis/redis.log
dbfilename dump.rdb
dir /var/lib/redis
replica-read-only yes
replicaof 192.168.33.10 6379

マスターにデータを入れます。

$ redis-cli -h 192.168.33.10
192.168.33.10:6379> keys *
(empty list or set)
192.168.33.10:6379> set key1 value1
OK
192.168.33.10:6379> set key2 value2
OK

レプリカを確認します。

$ redis-cli -h 192.168.33.11
192.168.33.11:6379> keys *
1) "key2"
2) "key1"

マスターを再起動します。

$ sudo systemctl stop redis
$ sudo systemctl start redis

マスターを確認します。永続化していないので、データがなくなりました。

$ redis-cli -h 192.168.33.10
192.168.33.10:6379> keys *
(empty list or set)

レプリカを確認します。

$ redis-cli -h 192.168.33.11
192.168.33.11:6379> keys *
(empty list or set)

こちらも、キレイになくなりましたね。

ところで、設定にRDBファイルを定義しているのは、

dbfilename dump.rdb
dir /var/lib/redis

データのフル転送が必要な時に、一時的にダンプファイルを作成する必要があるからみたいです。この設定を外すと、完全な同期が必要になった際にスナップショットが作れなくてエラーになるみたいです。

Opening the temp file needed for MASTER <-> REPLICA synchronization: Permission denied

データの永続化自体は、元のファイルにあった以下を削除したので、定期的な保存を行わなくなっています。

save 900 1
save 300 10
save 60 10000

Redis 5.0 Configuration

この場合は、Redisを再起動してもデータはなくなりません。

永続化設定と、再起動設定には気をつけましょうね、と。

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?