8
4

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のCluster構成でPubSubを試す

Last updated at Posted at 2015-11-13

Redisをクラスタ構成で動かす

構築メモにて。

環境

  • Ubuntu 14.04

実験

redis-cliでいろいろ実験してみる。なお、redis-cliに、-cオプションをつけないと、値の設定や取得でエラーになる。(-cはクラスタモード。)
-cをつけずに値の設定や取得を行うと、以下のようなエラーになる。

127.0.0.1:7000> set key1 100
(error) MOVED 9189 127.0.0.1:7001
127.0.0.1:7000> get key1
(error) MOVED 9189 127.0.0.1:7001

GET/SET

key1に値100を設定してみた。
key1は、ハッシュスロット9189に保存されたようだ。Redisが自動的に振り分けて7001のノードにリダイレクトしている。

127.0.0.1:7000> set key1 100
-> Redirected to slot [9189] located at 127.0.0.1:7001
OK
127.0.0.1:7001> get key1
"100"

MGET

今度は、MGETで複数の値を取得してみる。
まずは新たに値key2:200を追加する。すると、今度は7000のノードに保存した。

127.0.0.1:7001> set key2 200
-> Redirected to slot [4998] located at 127.0.0.1:7000
OK
127.0.0.1:7000> get key2
"200"

この時点で、key17001のノードに、key2のノードは7000のノードに保存されている。この状態で、MGETを実行して正常に取得できるか?
実行してみると、スロットを跨いで取得することは出来ない。

127.0.0.1:7001> mget key1 key2
(error) CROSSSLOT Keys in request don't hash to the same slot

では、どのようにすればMGETすることが出来るようになるか?ここで、ハッシュタグの出番。ハッシュタグとは、キーに{foo}のようにブラケットで囲んだ文字列を付与することにより、同じハッシュスロットに割り当てる機能である。

では実際にやってみるとどうなるか?以下は、{tag}というハッシュタグを、key1/key2に付与してMGETしてみる。
正常に動作しているようである。

127.0.0.1:7001> set {tag}key1 1000
OK
127.0.0.1:7001> get {tag}key1
"1000"
127.0.0.1:7001> set {tag}key2 2000
OK
127.0.0.1:7001> get {tag}key2
"2000"
127.0.0.1:7001> mget {tag}key1 {tag}key2
1) "1000"
2) "2000"

では、ハッシュタグ{tag}を付与した値が保存されたノードは7001であるが、7000のノードで、{tag}を付与した値をSETするとどうなるか?
7001のノードにリダイレクトした後、SETしてくれている。

127.0.0.1:7000> set {tag}key3 3000
-> Redirected to slot [8338] located at 127.0.0.1:7001
OK

このように、ハッシュタグを付与した値は、同じノードに対してSETしてくれることがわかった。
MGETなどのように、複数のキーに対して何かを行うようなコマンドを使う場合は、予めハッシュタグを考慮して設計する必要がありそうだ。

Pub/Sub

同じノードでPub/Sub

まずは簡単に、同一ノードに接続したPublisherとSubscriberで正常に動作するか確認してみる。以下のコマンドを2つターミナルを立ち上げ実行する。

  • Subscriber
127.0.0.1:7000> SUBSCRIBE 'channel:7000'
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "channel:7000"
3) (integer) 1
  • Publisher
127.0.0.1:7000> PUBLISH 'channel:7000' 'Hello from 7000'
(integer) 1

結果、Subscriberに正常に通知された。

127.0.0.1:7000> SUBSCRIBE 'channel:7000'(snip) …
1) "message"
2) "channel:7000"
3) "Hello from 7000"

異なるノードでPub/Sub

今度は、Publisherを異なるノードに接続し、Publishしてみる。

127.0.0.1:7001> PUBLISH 'channel:7000' 'Hello from 7001'
(integer) 0
127.0.0.1:7001>

結果、Subscriberに正常に通知された。

127.0.0.1:7000> SUBSCRIBE 'channel:7000'(snip) …
1) "message"
2) "channel:7000"
3) "Hello from 7001"

PubをSlaveに接続してPub/Sub

今度は、Publisherをスレーブに接続してPublishしてみる。

127.0.0.1:7004> PUBLISH 'channel:7000' 'Hello from 7004'
(integer) 0

結果、Subscriberに正常に通知された。

127.0.0.1:7000> SUBSCRIBE 'channel:7000'(snip) …
1) "message"
2) "channel:7000"
3) "Hello from 7004"

アクティブなチャネル一覧の取得

PUBSUB CHANNELS [pattern]で、アクティブなチャネル一覧を取得できるが、クラスタ環境で取得可能か確かめる。
Subscriberは、7000でチャネルchannel:7000をSubscribeしている状態である。

127.0.0.1:7000> SUBSCRIBE 'channel:7000'
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "channel:7000"
3) (integer) 1

まずは同じノードから。正常に取得できた。

127.0.0.1:7000> PUBSUB CHANNELS 'channel:7000'
1) "channel:7000"

次に、異なるノード7001から。取得できない。
どうやら、PUBSUB CHANNELSは、PubとSubが異なるノードの場合、期待通りに動作しないようだ。

127.0.0.1:7001> PUBSUB CHANNELS 'channel:7000'
(empty list or set)

ちなみに、ハッシュタグをつけても無駄である。

アクティブなチャネル数の取得

PUBSUB NUMSUB [channel]で、アクティブなチャネル数を取得することが出来るが、クラスタ環境で正常に動作するか試す。PUBSUB CHANNELSの場合と同様、7000のノードでSUBしている状態で試した。

まずは同じノードから。正常に取得できた。

127.0.0.1:7000> PUBSUB NUMSUB 'channel:7000'
1) "channel:7000"
2) (integer) 1

次に、異なるノードから。取得できない。

127.0.0.1:7001> PUBSUB NUMSUB 'channel:7000'
1) "channel:7000"
2) (integer) 0

ちなみに、ハッシュタグをつけても無駄である。

8
4
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
8
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?