Redisでレプリケーション(多段スレーブも試してみる)

Redisのreplication機能を使って↓のような構成を組んでみます。
(諸事情により一つの筐体の中でレプリケーションさせます。数字はポート番号です)

 
■ Masterを起動
デフォルトのredis.confをそのまま使用して起動させます。ポートはデフォルトの6379になります。

$ ./redis-server redis.conf
[19390] 09 Dec 10:22:29 * Server started, Redis version 2.0.4
[19390] 09 Dec 10:22:29 # WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
[19390] 09 Dec 10:22:29 * DB loaded from disk: 0 seconds
[19390] 09 Dec 10:22:29 * The server is now ready to accept connections on port 6379
[19390] 09 Dec 10:22:29 - DB 0: 10 keys (0 volatile) in 24 slots HT.
[19390] 09 Dec 10:22:29 - 0 clients connected (0 slaves), 534360 bytes in use

データは以下の要領で突っ込みました。

irb(main):004:0* require 'rubygems'
=> true
irb(main):005:0> require 'redis'
=> true
irb(main):006:0> redis = Redis.new(:host => 'localhost', :port => 6379)
=> #<Redis client v2.1.1 connected to redis://localhost:6379/0 (Redis v2.0.4)>
irb(main):007:0> redis.set "one", "hoge"
=> "OK"
irb(main):008:0> redis.set "two", "hage"
=> "OK"
irb(main):009:0> redis.set "three", "kabe"
=> "OK"
irb(main):010:0> redis.set "four", "bare"
=> "OK"
irb(main):011:0> redis.set "six", "sake"
=> "OK"
irb(main):012:0> redis.set "seven", "make"
=> "OK"
irb(main):013:0> redis.set "eight", "dare"
=> "OK"
irb(main):014:0> redis.set "nine", "mage"
=> "OK"
irb(main):015:0> redis.set "ten", "abe"
=> "OK"
irb(main):016:0> redis.set "eleven", "shake"
=> "OK"

 
■ Slave_1を起動
redis_slave.conf を コピーして redis_slave_01.conf を作ります。
24行目でポート番号を 6380 にしてセットして、
98行目でレプリケーションを 『slaveof localhost 6379』 にします。

$ ./redis-server redis_slave_01.conf
[19393] 09 Dec 10:22:37 * Server started, Redis version 2.0.4
[19393] 09 Dec 10:22:37 # WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
[19393] 09 Dec 10:22:37 * DB loaded from disk: 0 seconds
[19393] 09 Dec 10:22:37 * The server is now ready to accept connections on port 6380
[19393] 09 Dec 10:22:37 - DB 0: 10 keys (0 volatile) in 24 slots HT.
[19393] 09 Dec 10:22:37 - 0 clients connected (0 slaves), 534384 bytes in use
[19393] 09 Dec 10:22:37 * Connecting to MASTER...
[19393] 09 Dec 10:22:37 * Receiving 124 bytes data dump from MASTER
[19393] 09 Dec 10:22:37 * MASTER  SLAVE sync succeeded
[19393] 09 Dec 10:22:42 - DB 0: 10 keys (0 volatile) in 16 slots HT.

Slave_1を起動したときにMaster側は以下のようにSlave_1を受け入れています。

[19390] 09 Dec 10:22:37 - Accepted 127.0.0.1:36801
[19390] 09 Dec 10:22:37 * Slave ask for synchronization
[19390] 09 Dec 10:22:37 * Starting BGSAVE for SYNC
[19390] 09 Dec 10:22:37 * Background saving started by pid 19394
[19394] 09 Dec 10:22:37 * DB saved on disk
[19390] 09 Dec 10:22:37 * Background saving terminated with success
[19390] 09 Dec 10:22:37 * Synchronization with slave succeeded
[19390] 09 Dec 10:22:39 - DB 0: 10 keys (0 volatile) in 16 slots HT.
[19390] 09 Dec 10:22:39 - 0 clients connected (1 slaves), 534708 bytes in use

データは以下のように取れました。レプリケーションうまくいきました。

irb(main):001:0> require 'rubygems'
=> true
irb(main):002:0> require 'redis'
=> true
irb(main):003:0> redis = Redis.new(:host => 'localhost', :port => 6380)
=> #<Redis client v2.1.1 connected to redis://localhost:6380/0 (Redis v2.0.4)>
irb(main):004:0> redis.get "eleven"
=> "shake"
irb(main):005:0> redis.get "six"
=> "sake"
irb(main):006:0> redis.get "one"
=> "hoge"

 
■ Slave_2を起動
Slave_1と同様に、Slave_2を立てます。ポートは6381です。

$ ./redis-server redis_slave_02.conf
[19395] 09 Dec 10:22:54 * Server started, Redis version 2.0.4
[19395] 09 Dec 10:22:54 # WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
[19395] 09 Dec 10:22:54 * DB loaded from disk: 0 seconds
[19395] 09 Dec 10:22:54 * The server is now ready to accept connections on port 6381
[19395] 09 Dec 10:22:54 - DB 0: 10 keys (0 volatile) in 24 slots HT.
[19395] 09 Dec 10:22:54 - 0 clients connected (0 slaves), 534384 bytes in use
[19395] 09 Dec 10:22:54 * Connecting to MASTER...
[19395] 09 Dec 10:22:54 * Receiving 124 bytes data dump from MASTER
[19395] 09 Dec 10:22:54 * MASTER  SLAVE sync succeeded
[19395] 09 Dec 10:22:59 - DB 0: 10 keys (0 volatile) in 16 slots HT.

Slave_2を起動したときにMaster側は以下のようにSlave_2を受け入れています。

[19390] 09 Dec 10:22:54 - Accepted 127.0.0.1:36802
[19390] 09 Dec 10:22:54 * Slave ask for synchronization
[19390] 09 Dec 10:22:54 * Starting BGSAVE for SYNC
[19390] 09 Dec 10:22:54 * Background saving started by pid 19396
[19396] 09 Dec 10:22:54 * DB saved on disk
[19390] 09 Dec 10:22:54 * Background saving terminated with success
[19390] 09 Dec 10:22:54 * Synchronization with slave succeeded
[19390] 09 Dec 10:22:54 - DB 0: 10 keys (0 volatile) in 16 slots HT.
[19390] 09 Dec 10:22:54 - 0 clients connected (2 slaves), 535024 bytes in use

こちらもレプリケーションされたデータがちゃんと取れました。

irb(main):001:0> require 'rubygems'
=> true
irb(main):002:0> require 'redis'
=> true
irb(main):003:0> redis = Redis.new(:host => 'localhost', :port => 6381)
=> #<Redis client v2.1.1 connected to redis://localhost:6381/0 (Redis v2.0.4)>
irb(main):004:0> redis.get "two"
=> "hage"

 
■ 多段スレーブSlave_Slave_1(Slave_1に対するスレーブ)
ポートは6382にして、マスタをSlave_1に指定します⇒『slaveof localhost 6380』。

$ ./redis-server redis_slave_slave_01.conf
[19400] 09 Dec 10:23:42 * Server started, Redis version 2.0.4
[19400] 09 Dec 10:23:42 # WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
[19400] 09 Dec 10:23:42 * DB loaded from disk: 0 seconds
[19400] 09 Dec 10:23:42 * The server is now ready to accept connections on port 6382
[19400] 09 Dec 10:23:42 - DB 0: 10 keys (0 volatile) in 24 slots HT.
[19400] 09 Dec 10:23:42 - 0 clients connected (0 slaves), 534384 bytes in use
[19400] 09 Dec 10:23:42 * Connecting to MASTER...
[19400] 09 Dec 10:23:42 * Receiving 124 bytes data dump from MASTER
[19400] 09 Dec 10:23:42 * MASTER  SLAVE sync succeeded
[19400] 09 Dec 10:23:47 - DB 0: 10 keys (0 volatile) in 16 slots HT.
[19400] 09 Dec 10:23:47 - 1 clients connected (0 slaves), 534672 bytes in use

Slave_1側も受け入れています。

[19393] 09 Dec 10:23:42 - Accepted 127.0.0.1:41482
[19393] 09 Dec 10:23:42 * Slave ask for synchronization
[19393] 09 Dec 10:23:42 * Starting BGSAVE for SYNC
[19393] 09 Dec 10:23:42 * Background saving started by pid 19401
[19401] 09 Dec 10:23:42 * DB saved on disk
[19393] 09 Dec 10:23:42 * Background saving terminated with success
[19393] 09 Dec 10:23:42 * Synchronization with slave succeeded
[19393] 09 Dec 10:23:47 - DB 0: 10 keys (0 volatile) in 16 slots HT.
[19393] 09 Dec 10:23:47 - 1 clients connected (1 slaves), 535020 bytes in use

Slave_Slave_1からデータを取得したらちゃんとMasterの情報反映されてます。

irb(main):001:0> require 'rubygems'
=> true
irb(main):002:0> require 'rubygems'
=> false
irb(main):003:0> require 'redis'
=> true
irb(main):004:0> redis = Redis.new(:host => 'localhost', :port => 6382)
=> #<Redis client v2.1.1 connected to redis://localhost:6382/0 (Redis v2.0.4)>
irb(main):005:0> redis.get "three"
=> "kabe"

 
■ Slave_1にデータをセット
MasterとSlave_2には影響なくて、Slave_Slave_1からはデータが取れて欲しいところです。
まずSlave_1に突っ込んでみます。

irb(main):003:0> redis = Redis.new(:host => 'localhost', :port => 6380)
=> #<Redis client v2.1.1 connected to redis://localhost:6380/0 (Redis v2.0.4)>
~略~
irb(main):007:0> redis.set "dogg", "bowwow"
=> "OK"

Slave_1は今までkeyは10だったのが11になってます。

[19393] 09 Dec 10:34:03 - DB 0: 10 keys (0 volatile) in 16 slots HT.
[19393] 09 Dec 10:34:03 - 2 clients connected (1 slaves), 535400 bytes in use
[19393] 09 Dec 10:34:08 - DB 0: 11 keys (0 volatile) in 16 slots HT.
[19393] 09 Dec 10:34:08 - 2 clients connected (1 slaves), 535560 bytes in use

MasterとSlave_1はkeyは10のままです。
・Master

[19390] 09 Dec 10:34:09 - DB 0: 10 keys (0 volatile) in 16 slots HT.
[19390] 09 Dec 10:34:09 - 0 clients connected (2 slaves), 535024 bytes in use
irb(main):017:0> redis.get "bowwow"
=> nil

・Slave_2

[19395] 09 Dec 10:34:09 - DB 0: 10 keys (0 volatile) in 16 slots HT.
[19395] 09 Dec 10:34:09 - 2 clients connected (0 slaves), 535084 bytes in use
irb(main):005:0> redis.get "dogg"
=> nil

Slave_Slave_1はkeyが11になってて、irbからも値が取れました。

[19400] 09 Dec 10:34:03 - DB 0: 10 keys (0 volatile) in 16 slots HT.
[19400] 09 Dec 10:34:03 - 2 clients connected (0 slaves), 535088 bytes in use
[19400] 09 Dec 10:34:08 - DB 0: 11 keys (0 volatile) in 16 slots HT.
[19400] 09 Dec 10:34:08 - 2 clients connected (0 slaves), 535152 bytes in use
 
irb(main):006:0> redis.get "dogg"
=> "bowwow"

さらに、、、、
Masterにデータを突っ込んでみます。

irb(main):018:0> redis.set "rerere", "nore"
=> "OK"
irb(main):019:0> redis.set "gegege", "noge"
=> "OK"
irb(main):020:0> redis.set "pepepe", "nopay"
=> "OK"

Masterのkeyは13になりました。

[19390] 09 Dec 12:42:39 - Accepted 127.0.0.1:50701
[19390] 09 Dec 12:42:40 * 1 changes in 900 seconds. Saving...
[19390] 09 Dec 12:42:40 * Background saving started by pid 19929
[19929] 09 Dec 12:42:40 * DB saved on disk
[19390] 09 Dec 12:42:40 * Background saving terminated with success
[19390] 09 Dec 12:42:43 - DB 0: 11 keys (0 volatile) in 16 slots HT.
[19390] 09 Dec 12:42:43 - 1 clients connected (2 slaves), 535596 bytes in use
[19390] 09 Dec 12:42:48 - DB 0: 12 keys (0 volatile) in 16 slots HT.
[19390] 09 Dec 12:42:48 - 1 clients connected (2 slaves), 535684 bytes in use
[19390] 09 Dec 12:42:53 - DB 0: 12 keys (0 volatile) in 16 slots HT.
[19390] 09 Dec 12:42:53 - 1 clients connected (2 slaves), 535684 bytes in use
[19390] 09 Dec 12:42:58 - DB 0: 13 keys (0 volatile) in 16 slots HT.
[19390] 09 Dec 12:42:58 - 1 clients connected (2 slaves), 535772 bytes in use
 
irb(main):021:0> redis.get "bowwow"
=> nil

Slave_1はkeyが14になって、先ほどいれた”dogg”,”bowwow”がちゃんと残ってます。

[19393] 09 Dec 12:42:37 - DB 0: 11 keys (0 volatile) in 16 slots HT.
[19393] 09 Dec 12:42:37 - 1 clients connected (1 slaves), 535236 bytes in use
[19393] 09 Dec 12:42:39 * 1 changes in 900 seconds. Saving...
[19393] 09 Dec 12:42:39 * Background saving started by pid 19927
[19927] 09 Dec 12:42:40 * DB saved on disk
[19393] 09 Dec 12:42:40 * Background saving terminated with success
[19393] 09 Dec 12:42:42 - DB 0: 12 keys (0 volatile) in 16 slots HT.
[19393] 09 Dec 12:42:42 - 1 clients connected (1 slaves), 535360 bytes in use
[19393] 09 Dec 12:42:47 - DB 0: 12 keys (0 volatile) in 16 slots HT.
[19393] 09 Dec 12:42:47 - 1 clients connected (1 slaves), 535360 bytes in use
[19393] 09 Dec 12:42:52 - DB 0: 13 keys (0 volatile) in 16 slots HT.
[19393] 09 Dec 12:42:52 - 1 clients connected (1 slaves), 535448 bytes in use
[19393] 09 Dec 12:42:57 - DB 0: 14 keys (0 volatile) in 16 slots HT.
[19393] 09 Dec 12:42:57 - 1 clients connected (1 slaves), 535536 bytes in use
 
irb(main):008:0> redis.get "dogg"
=> "bowwow"

Slave_2はMasterのデータが反映されて

[19395] 09 Dec 12:42:38 - 1 clients connected (0 slaves), 534768 bytes in use
[19395] 09 Dec 12:42:40 * 1 changes in 900 seconds. Saving...
[19395] 09 Dec 12:42:40 * Background saving started by pid 19928
[19928] 09 Dec 12:42:40 * DB saved on disk
[19395] 09 Dec 12:42:40 * Background saving terminated with success
[19395] 09 Dec 12:42:43 - DB 0: 11 keys (0 volatile) in 16 slots HT.
[19395] 09 Dec 12:42:43 - 1 clients connected (0 slaves), 534828 bytes in use
[19395] 09 Dec 12:42:48 - DB 0: 12 keys (0 volatile) in 16 slots HT.
[19395] 09 Dec 12:42:48 - 1 clients connected (0 slaves), 534916 bytes in use
[19395] 09 Dec 12:42:53 - DB 0: 12 keys (0 volatile) in 16 slots HT.
[19395] 09 Dec 12:42:53 - 1 clients connected (0 slaves), 534916 bytes in use
[19395] 09 Dec 12:42:58 - DB 0: 13 keys (0 volatile) in 16 slots HT.
[19395] 09 Dec 12:42:58 - 1 clients connected (0 slaves), 535004 bytes in use
 
irb(main):006:0> redis.get "dogg"
=> nil

Slave_Slave_1はSlave_1と同期が取れています。

[19400] 09 Dec 12:42:37 - 1 clients connected (0 slaves), 534896 bytes in use
[19400] 09 Dec 12:42:39 * 1 changes in 900 seconds. Saving...
[19400] 09 Dec 12:42:39 * Background saving started by pid 19926
[19926] 09 Dec 12:42:40 * DB saved on disk
[19400] 09 Dec 12:42:40 * Background saving terminated with success
[19400] 09 Dec 12:42:42 - DB 0: 12 keys (0 volatile) in 16 slots HT.
[19400] 09 Dec 12:42:42 - 1 clients connected (0 slaves), 534916 bytes in use
[19400] 09 Dec 12:42:47 - DB 0: 12 keys (0 volatile) in 16 slots HT.
[19400] 09 Dec 12:42:47 - 1 clients connected (0 slaves), 534916 bytes in use
[19400] 09 Dec 12:42:52 - DB 0: 13 keys (0 volatile) in 16 slots HT.
[19400] 09 Dec 12:42:52 - 1 clients connected (0 slaves), 535004 bytes in use
[19400] 09 Dec 12:42:57 - DB 0: 14 keys (0 volatile) in 16 slots HT.
[19400] 09 Dec 12:42:57 - 1 clients connected (0 slaves), 535092 bytes in use
 
irb(main):007:0> redis.get "dogg"
=> "bowwow"

 
なるほど。いやー良く出来てんな~
  
■ ということで
今回狙ってたことは確認できました。ただ、↓のRedisのWikiを読んでると、
http://code.google.com/p/redis/wiki/ReplicationHowto
↓みたいな興味深いやりとりとかもあったりして。

Slaveをリードオンリーに出来ないの?⇒今後取り入れる予定
部分的にレプリケーション出来ないの?⇒レス無し。。

自分も業務で使ってるうちに、どハマリしてこういうコミュニティに貢献出来たりしたらアツイんだろうな~
 

コメント

  1. […] ・Redisに500万レコード突っ込んで複数クライアントからGETしてみる ・Redisでレプリケーション(多段スレーブも試してみる) ・Redisの設定ファイル(redis.conf)の和訳    […]

タイトルとURLをコピーしました