動くものをgithubに上げとります。
一般的な方法だと一度コンテナを立ち上げた後にコマンドで実行する必要がありますが、面倒くさいので自動化することに。
キモはネットワークの設定でipを割り当ててやることと、起動時にnode.confの指定をしてやることかと。
まずは docker-compose.yml の説明
version: '2'
services:
#nginxの設定
cluster-test-web:
build: docker/web
container_name: cluster-test-web
ports:
- 80:80
links:
- cluster-test-app:php
volumes_from:
- cluster-test-app
#redisと同じネットワークに
networks:
app_net:
#phpの設定
cluster-test-app:
build: docker/app
container_name: cluster-test-app
volumes:
- ./:/var/www/html
links:
#redisと接続するのでその設定
- cluster-test-redis:redis
#redisと同じネットワークに
networks:
app_net:
#redisの設定
cluster-test-redis:
image: redis:latest
container_name: cluster-test-redis
# ./docker/redis の内容を /data/conf にマウント
volumes:
- ./docker/redis/:/data/conf
# コンテナが起動したら、
# redis-serverとクラスター・レプリケーションの設定を行うshellスクリプトを実行。
# その後、常時起動のコマンドを走らせる。
command: bash -c "/bin/bash /data/conf/redis.sh && while true; do echo 1; sleep 1; done"
ports:
- 7000:7000
- 7001:7001
- 7002:7002
- 7003:7003
- 7004:7004
- 7005:7005
#shellスクリプト内でipを使用するのでここで設定。
networks:
app_net:
ipv4_address: 172.16.239.10
networks:
app_net:
driver: bridge
ipam:
driver: default
config:
- subnet: 172.16.239.0/24
gateway: 172.16.239.1
redis-server の起動は docker-compose.yml の command で実行している redis.sh 内で行っている。
# !/bin/bash
# 邪魔なファイルを削除。
rm -f \
/data/conf/r7000i.log \
/data/conf/r7001i.log \
/data/conf/r7002i.log \
/data/conf/r7003i.log \
/data/conf/r7004i.log \
/data/conf/r7005i.log \
/data/conf/nodes.7000.conf \
/data/conf/nodes.7001.conf \
/data/conf/nodes.7002.conf \
/data/conf/nodes.7003.conf \
/data/conf/nodes.7004.conf \
/data/conf/nodes.7005.conf ;
# redisを6台クラスターモードで(クラスターモードの設定はredis.conf)起動。
# nodes.****.conf はそれぞれ別々のファイルを指定する必要がある。
redis-server /data/conf/redis.conf --port 7000 --cluster-config-file /data/conf/nodes.7000.conf --daemonize yes ;
redis-server /data/conf/redis.conf --port 7001 --cluster-config-file /data/conf/nodes.7001.conf --daemonize yes ;
redis-server /data/conf/redis.conf --port 7002 --cluster-config-file /data/conf/nodes.7002.conf --daemonize yes ;
redis-server /data/conf/redis.conf --port 7003 --cluster-config-file /data/conf/nodes.7003.conf --daemonize yes ;
redis-server /data/conf/redis.conf --port 7004 --cluster-config-file /data/conf/nodes.7004.conf --daemonize yes ;
redis-server /data/conf/redis.conf --port 7005 --cluster-config-file /data/conf/nodes.7005.conf --daemonize yes ;
REDIS_LOAD_FLG=true;
# 全てのredis-serverの起動が完了するまでループ。
while $REDIS_LOAD_FLG;
do
sleep 1;
redis-cli -p 7000 info 1> /data/conf/r7000i.log 2> /dev/null;
if [ -s /data/conf/r7000i.log ]; then
:
else
continue;
fi
redis-cli -p 7001 info 1> /data/conf/r7001i.log 2> /dev/null;
if [ -s /data/conf/r7001i.log ]; then
:
else
continue;
fi
redis-cli -p 7002 info 1> /data/conf/r7002i.log 2> /dev/null;
if [ -s /data/conf/r7002i.log ]; then
:
else
continue;
fi
redis-cli -p 7003 info 1> /data/conf/r7003i.log 2> /dev/null;
if [ -s /data/conf/r7003i.log ]; then
:
else
continue;
fi
redis-cli -p 7004 info 1> /data/conf/r7004i.log 2> /dev/null;
if [ -s /data/conf/r7004i.log ]; then
:
else
continue;
fi
redis-cli -p 7005 info 1> /data/conf/r7005i.log 2> /dev/null;
if [ -s /data/conf/r7005i.log ]; then
:
else
continue;
fi
#redis-serverの起動が終わったらクラスター・レプリカの割り当てる。
#ipを127.0.0.1で割り当てるとphpで不具合が起こるのでpublic ipを指定。
yes "yes" | redis-cli --cluster create 172.16.239.10:7000 172.16.239.10:7001 172.16.239.10:7002 172.16.239.10:7003 172.16.239.10:7004 172.16.239.10:7005 --cluster-replicas 1;
REDIS_LOAD_FLG=false;
done
redis.conf の中身は↓
# クラスターモードON
cluster-enabled yes
cluster-node-timeout 5000
# 接続のip制限を解除
bind 0.0.0.0
動作確認用のphpを組む。
<?php
# 接続は docker-compose.yml の link の設定で繋がる
$rc = new \RedisCluster(null, [
'redis:7000',
]);
# php7だと RedisCluster::FAILOVER_DISTRIBUTE_SLAVES が動かないので、ランダムで replica にアクセスの RedisCluster::FAILOVER_DISTRIBUTE を設定。
# https://github.com/phpredis/phpredis/blob/develop/cluster.markdown#automatic-slave-failover--distribution
# https://github.com/phpredis/phpredis/issues/937
$rc->setOption(\RedisCluster::OPT_SLAVE_FAILOVER, \RedisCluster::FAILOVER_DISTRIBUTE);
echo "<pre>";
# master系のnodeのリストが表示できます
print_r($rc->_masters());
# replica(slave)も含めて全てのnodeを表示
print_r($rc->rawcommand(['172.16.239.10', 7000], 'cluster', 'nodes'));
$t = microtime();
$k = md5($t);
# 適当の値をセットして
$rc->set($k, $t);
# とりあえずゲットしてみる。ゲットできていれば万事上手く動いているんじゃないんですかね
print_r($rc->get($k));
docker-compose up -d --build
で起動したならhttp://localhost/redis_test.php
をブラウザで表示してみる。

こんな感じで master のリストと node のリストが表示されます。
ちゃんと均等にクラスターが割り当てられレプリケーションもできてますね。
以上。