Why not login to Qiita and try out its useful features?

We'll deliver articles that match you.

You can read useful information later.

6
6

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.

docker で redis-cluster を自動起動させる。ついでにPHP7で使う。

Last updated at Posted at 2018-12-29

動くものをgithubに上げとります。

一般的な方法だと一度コンテナを立ち上げた後にコマンドで実行する必要がありますが、面倒くさいので自動化することに。
キモはネットワークの設定でipを割り当ててやることと、起動時にnode.confの指定をしてやることかと。

まずは docker-compose.yml の説明

./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 内で行っている。

./docker/redis/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 の中身は↓

./docker/redis/redis.conf
# クラスターモードON
cluster-enabled      yes
cluster-node-timeout 5000
# 接続のip制限を解除
bind 0.0.0.0

動作確認用のphpを組む。

./redis_test.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をブラウザで表示してみる。

SS.png

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

以上。

6
6
1

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

Qiita Conference 2025 will be held!: 4/23(wed) - 4/25(Fri)

Qiita Conference is the largest tech conference in Qiita!

Keynote Speaker

ymrl、Masanobu Naruse, Takeshi Kano, Junichi Ito, uhyo, Hiroshi Tokumaru, MinoDriven, Minorun, Hiroyuki Sakuraba, tenntenn, drken, konifar

View event details
6
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?