概要
これまで Redis Sentinel を試してきました
Redis には Cluster の機能もありこれを使えばノードを増やすことでスケールアウトすることができます
今回は Mac 上に Redis Cluster 環境を構築しついでに Ruby からも操作してみました
環境
- macOS 10.14.4
- Redis 5.0.5
- Ruby 2.6.2p47
各ノードの作成
プロセスであれば OK なので適当にディレクトリを作成して redis-server
プロセスを起動します
mkdir 7000 7001 7002
touch 7000/redis.conf 7001/redis.conf 7002/redis.conf
vim 7000/redis.conf
port 7000
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes
redis.conf
は 7001, 7002 ディレクトリ配下でも作成しましょう
また port
の部分は 7001, 7002 に書き換えましょう
cd 7000
redis-server redis.conf
あとは各ディレクトリに移動して conf ファイルを指定して起動します
クラスタの構築
起動した各プロセスを元にクラスタを構築します
クラスタを構築するには redis-cli --cluster create
コマンドを使います
redis-cli --cluster create 127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002
>>> Performing hash slots allocation on 3 nodes...
Master[0] -> Slots 0 - 5460
Master[1] -> Slots 5461 - 10922
Master[2] -> Slots 10923 - 16383
M: ad0cd036fa5cc5e87f3c46efeda4efa06ac866da 127.0.0.1:7000
slots:[0-5460] (5461 slots) master
M: 7da858c6200f22ec2b8395a56e6f950e8c72685e 127.0.0.1:7001
slots:[5461-10922] (5462 slots) master
M: c99ba957f8d81c4a38e77a275043730ab77aeb33 127.0.0.1:7002
slots:[10923-16383] (5461 slots) master
Can I set the above configuration? (type 'yes' to accept): yes
>>> Nodes configuration updated
>>> Assign a different config epoch to each node
>>> Sending CLUSTER MEET messages to join the cluster
Waiting for the cluster to join
...
>>> Performing Cluster Check (using node 127.0.0.1:7000)
M: ad0cd036fa5cc5e87f3c46efeda4efa06ac866da 127.0.0.1:7000
slots:[0-5460] (5461 slots) master
M: c99ba957f8d81c4a38e77a275043730ab77aeb33 127.0.0.1:7002
slots:[10923-16383] (5461 slots) master
M: 7da858c6200f22ec2b8395a56e6f950e8c72685e 127.0.0.1:7001
slots:[5461-10922] (5462 slots) master
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
16384 スロットが均等に割り振られれば OK です
localhost
で指定すると ERR Invalid node address specified: localhost:7000
になるので IP で指定します
また --cluster-replicas 1
を指定すると各 master に対する slave ノードを作成することができます
今回は master 用の 3 台しかプロセスを用意していないので指定できません
動作確認
クラスタが構築できたら動作確認してみましょう
redis-cli -c -p 7000 set a a
=> OK
redis-cli -c -p 7001 get a
=> "a"
redis-cli -c -p 7002 set b b
=> OK
redis-cli -c -p 7000 get b
=> "b"
どこからも set/get
ができることを確認しましょう
またノードの状態も確認できます
redis-cli -p 7000 cluster nodes
新しいノードの追加
ノードを 4 台に増やしてみます
reshard
する点がポイントです
mkdir 7003
touch 7003/redis.conf
vim 7003/redis.conf
port 7003
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes
cd 7003
redis-server redis.conf
プロセスを起動したら追加します
redis-cli --cluster add-node 127.0.0.1:7003 127.0.0.1:7000
コマンドは redis-cli --cluster add-node
を使います
新ノードのIP:ポート
、既存ノードのIP:ポート
のフォーマットで指定します
>>> Adding node 127.0.0.1:7003 to cluster 127.0.0.1:7000
>>> Performing Cluster Check (using node 127.0.0.1:7000)
M: ad0cd036fa5cc5e87f3c46efeda4efa06ac866da 127.0.0.1:7000
slots:[0-5460] (5461 slots) master
M: c99ba957f8d81c4a38e77a275043730ab77aeb33 127.0.0.1:7002
slots:[10923-16383] (5461 slots) master
M: 7da858c6200f22ec2b8395a56e6f950e8c72685e 127.0.0.1:7001
slots:[5461-10922] (5462 slots) master
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
>>> Send CLUSTER MEET to node 127.0.0.1:7003 to make it join the cluster.
[OK] New node added correctly.
これでノードの追加ができました
が、このままではデータが保存されません
reshard
することで新しいノードにもデータが分散されるようにします
redis-cli --cluster reshard 127.0.0.1:7000
いろいろと聞かれます
まずは「4096」を入力しましょう
これは 16384 / 4
の値になります
4 は 4 台で分散しているためです
次に「0eb468ab4a1766f2e9c31ba75a9ae880563ae462」を入力します
これは新規に追加した redis-server
の ID になります
各ノードの ID は redis-cli -p 7000 cluster nodes
などで確認できます
3 つ目に「all」を入力します
これはデータをノード全体で reshard
することを意味します
最後に「yes」で reshard
が始まります
reshard
が始まるとずらーっとログが流れ始めるので待ちます
完了すると 4096 スロットずつに分散されていることが確認できます
redis-cli --cluster info 127.0.0.1:7000
127.0.0.1:7000 (ad0cd036...) -> 1 keys | 4096 slots | 0 slaves.
127.0.0.1:7002 (c99ba957...) -> 1 keys | 4096 slots | 0 slaves.
127.0.0.1:7003 (0eb468ab...) -> 0 keys | 4096 slots | 0 slaves.
127.0.0.1:7001 (7da858c6...) -> 0 keys | 4096 slots | 0 slaves.
[OK] 2 keys in 4 masters.
0.00 keys per slot on average.
ノードの削除
削除する際も reshard
が必要です
コマンドは redis-cli --cluster del-node
を使います
redis-cli --cluster del-node 127.0.0.1:7003 0eb468ab4a1766f2e9c31ba75a9ae880563ae462
フォーマットは 削除するノードのIP:ポート
削除するノードID
という感じで指定します
おそらく以下のようなエラーが出ると思います
[ERR] Node 172.17.0.5:6379 is not empty! Reshard data away and try again.
ようするにデータがあるから指定のノードをクラスタから削除できないよというエラーになります
削除したいノードからデータを移すのも reshard
を使います
redis-cli --cluster reshard 127.0.0.1:7000
入力する情報が異なります
まずは「4096」を入力します
これは移したいノードが持つスロット数になります
そして「ad0cd036fa5cc5e87f3c46efeda4efa06ac866da」を入力します
これはデータの移し先のノードになるので削除するノードではなく残すノードの ID を指定しましょう
そして「0eb468ab4a1766f2e9c31ba75a9ae880563ae462」->「done」を入力します
ここに削除するノードの ID を入力します
今回は 1 台だけなので 1 ID 分入力したら done で終了します
そして「yes」で reshard
を開始します
完了するとノードが削除されて redis-server
プロセスが停止します
redis-cli --cluster info 127.0.0.1:7000
127.0.0.1:7000 (ad0cd036...) -> 1 keys | 8192 slots | 0 slaves.
127.0.0.1:7002 (c99ba957...) -> 1 keys | 4096 slots | 0 slaves.
127.0.0.1:7001 (7da858c6...) -> 1 keys | 4096 slots | 0 slaves.
[OK] 3 keys in 3 masters.
0.00 keys per slot on average.
スロットのバランスがかなり悪いので再度 5461
で reshard
してあげると良いかなと思います
クラスタ解体
--cluster create
コマンドはありますが delete
コマンドはないようです
もし丁寧にやるのであれば最後の 1 台になるまで reshard
して最後に 1 台のプロセスを kill する感じかなと思います
もうすでにアクセスがなくデータが飛んでもいいのであればいきなり kill でも良いと思います
Ruby から操作する
せっかくなので Ruby から操作してみました
redis-rb を使います
bundle init
vim Gemfile
gem "redis"
bundle install --path vendor
vim app.rb
require 'redis'
nodes = (7000..7002).map { |port| "redis://127.0.0.1:#{port}" }
redis = Redis.new(cluster: nodes)
puts redis.get('c')
bundle exec ruby app.rb
=> c
こんな感じです
Redis オブジェクトを初期化する際にクラスタ内に存在するノードを指定する必要があります
なので add-node
や del-node
でノード数が変わる場合はアプリケーションも変更する必要がありそうです
最後に
Redis Cluster を試してみました
各 redis-server
プロセスを立ち上げてあとは redis-cli --cluster create
で構築すれば使えるといった感じです
基本は master で上がって来ます
必要であれば slave を用意することもできます
Sentinel に比べてスケーラビリティは高いと思います
サーバのスペックが足りなくなったら新規で redis-server
プロセスを追加すれば良いだけだからです
ただ reshard
など管理する項目も増えるので運用は大変になりそうなイメージです
master が一定数存在する必要もあります
例えば今回は 3 台構成を紹介しましたが最低 3 台必要になります (1, 2 台でもクラスタは組めますが公式でも3 台以上を推奨しています)
なので 1 台ダウンするとクラスタが壊れてしまうためうまく読み書きできなくなってしまいます
slave を用意すれば Cluster でも failover させることができるので可用性を担保することはできますが管理する台数は増えます
この辺りは用途に合わせた使い分けかなと思うのでどっちが良い悪いという話ではないかなと思います
0 件のコメント:
コメントを投稿