今回はDockerコンテナでRedisクラスタを構築した際の手順について書きます。 「set
, get
などが問題なく実行できればよい」という状況での作業メモ的なものなので、レプリケーションやバックアップなどはまったく考慮してません。
環境 OS Mac OS X 10.9.2 Docker 1.8.2 DockerMachine 0.4.1
やってみる Redis Cluster Tutorial によると、配布されているソースコードにはredis-tribやcreate-clusterというユーティリティが同梱されていて、以下のようなコマンドでノードの追加やスロットの割当てができるらしいです。便利ですね。
clustering by redis-trib 1 $ ./redis-trib.rb create 127.0.0.1:7000 127.0.0.1:7001 ...
clustering by create-cluster 1
2 $ create-cluster start
$ create-cluster create
ですが、公式のDockerコンテナではRedisのビルド後にソースコードを削除している ため、これらに頼ることはできません。 仕方ないので手動でやります。
設定ファイル デフォルトの設定ではクラスタリングできないので、まずは設定ファイルを用意します。
./redis.conf 1
2
3 cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
イメージの作成・起動 --volume
オプションで設定ファイルのあるディレクトリをマウントします。 上記の設定ファイルでredis-server
を実行すると、/data/nodes.conf
が生成されます。 このファイルの所有者はredis:redis
です。 --volume $(pwd):/data
とすると/data
の所有者が1000:staff
になってしまってnodes.conf
を生成できないので、--volume $(pwd):/data/conf
としておきます。
create containers 1
2
3
4 $ docker create --name node_6379 -p 6379:6379 --volume $( pwd ) :/data/conf redis:3 redis-server /data/conf/redis.conf
$ docker create --name node_6380 -p 6380:6379 --volume $( pwd ) :/data/conf redis:3 redis-server /data/conf/redis.conf
$ docker create --name node_6381 -p 6381:6379 --volume $( pwd ) :/data/conf redis:3 redis-server /data/conf/redis.conf
$ docker start node_6379 node_6380 node_6381
クラスタリング スロットの割当 まず各ノードにスロットを割当てます。
add slot to each nodes 1
2
3
4
5
6 $ docker exec node_6379 redis-cli cluster addslots { 0..5500}
OK
$ docker exec node_6380 redis-cli cluster addslots { 5501..11000}
OK
$ docker exec node_6381 redis-cli cluster addslots { 11001..16383}
OK
OKっぽいですね、確認しましょう。
allocated slot 1
2
3
4
5
6 $ docker exec node_6379 redis-cli cluster nodes
cf2e950621381be04ea1031ae80cb945f9743b83 :6379 myself,master - 0 0 0 connected 0-5500
$ docker exec node_6380 redis-cli cluster nodes
0969adb771d38a49e70f235b39665156ded5a43a :6379 myself,master - 0 0 0 connected 5501-11000
$ docker exec node_6381 redis-cli cluster nodes
d9c4125051222bbc36cd0d0172e406baa9d89579 :6379 myself,master - 0 0 0 connected 11001-16383
ちゃんと割当てできてるように見えます。
ノードの追加 クラスタにノードを追加していきます。
add nodes to cluster 1
2
3
4 $ docker exec node_6380 redis-cli cluster meet ` docker-machine ip $DOCKER_MACHINE_NAME ` 6379
OK
$ docker exec node_6381 redis-cli cluster meet ` docker-machine ip $DOCKER_MACHINE_NAME ` 6379
OK
OKっぽいですね。
cluster nodes 1
2
3
4
5
6 $ docker exec node_6379 redis-cli cluster nodes
cf2e950621381be04ea1031ae80cb945f9743b83 :6379 myself,master - 0 0 0 connected 0-5500
$ docker exec node_6380 redis-cli cluster nodes
0969adb771d38a49e70f235b39665156ded5a43a :6379 myself,master - 0 0 0 connected 5501-11000
$ docker exec node_6381 redis-cli cluster nodes
d9c4125051222bbc36cd0d0172e406baa9d89579 :6379 myself,master - 0 0 0 connected 11001-16383
変わってません。
やりなおす どうもNAT越しだとうまくいかない(?) ようです。
--net host
を追加して、ブリッジしないようにしてみます。 ついでに各ノードで異なるポートを使用するようにしておきます。
1
2
3
4
5
6
7
8
9
10
11
12 $ for n in ` seq 6379 6381` ; do mkdir $n && echo "port $n" > $n /redis.conf && cat redis.conf >> & n/redis.conf; done
$ docker stop node_6379 node_6380 node_6381
$ docker rm node_6379 node_6380 node_6381
$ docker create --name node_6379 --volume $( pwd ) /6379:/data/conf --net host redis:3 redis-server /data/conf/redis.conf
$ docker create --name node_6380 --volume $( pwd ) /6380:/data/conf --net host redis:3 redis-server /data/conf/redis.conf
$ docker create --name node_6381 --volume $( pwd ) /6381:/data/conf --net host redis:3 redis-server /data/conf/redis.conf
$ docker start node_6379 node_6380 node_6381
$ docker exec node_6379 redis-cli -p 6379 cluster addslots { 0..5500}
$ docker exec node_6380 redis-cli -p 6380 cluster addslots { 5501..11000}
$ docker exec node_6381 redis-cli -p 6381 cluster addslots { 11001..16383}
$ docker exec node_6380 redis-cli -p 6380 cluster meet ` docker-machine ip $DOCKER_MACHINE_NAME ` 6379
$ docker exec node_6381 redis-cli -p 6381 cluster meet ` docker-machine ip $DOCKER_MACHINE_NAME ` 6379
1
2
3
4
5
6
7
8
9
10
11
12 $ docker exec node_6379 redis-cli -p 6379 cluster nodes
ca0a4f11069103e902ea83de9023b34a7aa01d06 192.168.99.100:6379 myself,master - 0 0 0 connected 0-5500
465ab243a99efec4e7cfa00491304b8dcffd0701 192.168.99.100:6381 master - 0 1444015783288 2 connected 11001-16383
c185ffd045e2ce324dce43ae5374253df8da2af2 192.168.99.100:6380 master - 0 1444015784307 1 connected 5501-11000
$ docker exec node_6380 redis-cli -p 6380 cluster nodes
465ab243a99efec4e7cfa00491304b8dcffd0701 192.168.99.100:6381 master - 0 1444015806729 2 connected 11001-16383
ca0a4f11069103e902ea83de9023b34a7aa01d06 192.168.99.100:6379 master - 0 1444015805713 0 connected 0-5500
c185ffd045e2ce324dce43ae5374253df8da2af2 192.168.99.100:6380 myself,master - 0 0 1 connected 5501-11000
$ docker exec node_6381 redis-cli -p 6381 cluster nodes
c185ffd045e2ce324dce43ae5374253df8da2af2 192.168.99.100:6380 master - 0 1444015823353 1 connected 5501-11000
465ab243a99efec4e7cfa00491304b8dcffd0701 192.168.99.100:6381 myself,master - 0 0 2 connected 11001-16383
ca0a4f11069103e902ea83de9023b34a7aa01d06 192.168.99.100:6379 master - 0 1444015824374 0 connected 0-5500
先ほどとは違い、どのノードも他のノードを認識できてるようです。
実際にset
とかget
してみる -c
は必須です。忘れるとリダイレクトせずにエラーを返します。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 $ docker exec -it node_6379 redis-cli -c -p 6379
127.0.0.1:6379> set hoge 1
OK
127.0.0.1:6379> set hoge2 2
-> Redirected to slot [ 11000] located at 192.168.99.100:6380
OK
192.168.99.100:6380> set hoge3 3
-> Redirected to slot [ 15065] located at 192.168.99.100:6381
OK
192.168.99.100:6381> get hoge
-> Redirected to slot [ 1525] located at 192.168.99.100:6379
"1"
192.168.99.100:6379> get hoge2
-> Redirected to slot [ 11000] located at 192.168.99.100:6380
"2"
192.168.99.100:6380> get hoge3
-> Redirected to slot [ 15065] located at 192.168.99.100:6381
"3"
きちんと他のノードにリダイレクトしてくれてますね。