Redis Clusterã䜿ã£ãŠã¿ããã®ãšãåãããŠãã®Dockerã€ã¡ãŒãžãäœããããªãšæã£ãŠã¡ãã£ãšéãã§ã¿ãŸããã
Redis 3ãããã¯ã©ã¹ã¿ãçµããããã«ãªã£ãããã§ãããããã詊ããŠã¿ãããšã
åèïŒ
ãªãã£ã·ã£ã«ãµã€ããã¥ãŒããªã¢ã«
Redis cluster tutorial
公式のDockerコンテナでRedis Clusterを構築する - Maverick Techlab
Redis cluster - おさかな日誌
http://tech.albert2005.co.jp/blog/2015/04/28/redis-cluster/
Redis Cluster のリシャーディングとorphaned masterの話 - CyberAgent エンジニア Advent Calendar 2014 2日目 · GitHub
ããããåèã«ãRedis Clusterç°å¢ãæ§ç¯ããããã®Dockerã€ã¡ãŒãžãäœã£ãŠãã£ãŠã¿ãŸãã
Redis Clusterã£ãŠïŒ
ãããããRedis Clusterã«ã€ããŠã§ããããã£ããèšããš
- Redisãè€æ°ããŒãã§æ§æãããã«ããã¹ã¿ãçµãã
- ããŒã¿ã¯ããŒãéã§ã·ã£ãŒãã£ã³ã°
- ã¹ã¬ãŒããäœã£ãŠèé害æ§ã®åäžãå¯èœ
ãšãã£ã代ç©ãããã§ãã
Dockerã€ã¡ãŒãžã®äœæ
ããã§ã¯ãDockerã€ã¡ãŒãžãèªåã§äœã£ãŠã¿ãŸãã
ãŸãããªãã£ã·ã£ã«ã®ãã¥ãŒããªã¢ã«ãèªããš
Redis Cluster and Docker
Currently Redis Cluster does not support NATted environments and in general environments where IP addresses or TCP ports are remapped.
Docker uses a technique called port mapping: programs running inside Docker containers may be exposed with a different port compared to the one the program believes to be using. This is useful in order to run multiple containers using the same ports, at the same time, in the same server.
In order to make Docker compatible with Redis Cluster you need to use the host networking mode of Docker. Please check the --net=host option in the Docker documentation for more information.
http://redis.io/topics/cluster-tutorial
ãšããæãã§NATã¯ãµããŒãããŠãªããã--net=hostã§äœ¿ããããšæžããŠããã®ã§ããã®åæã§äœããŸãã
å¿ èŠãªã®ã¯ã
- Redis
- Redisãã³ã³ãã€ã«ããç°å¢ïŒmakeãgccïŒ
- RubyïŒredis-trib.rbã¹ã¯ãªããã䜿çšããããïŒ
ãšãã£ããšããã
Redisã®ã€ã³ã¹ããŒã«å
ã/opt/redisãšããŠãäœæããã®ããã¡ãã
Dockerfile
FROM ubuntu:latest ENV REDIS_VERSION 3.0.6 ENV REDIS_HOME /opt/redis WORKDIR ${REDIS_HOME} RUN mkdir -p ${REDIS_HOME} RUN apt-get update RUN apt-get install -y apt-file && \ apt-file update && \ apt-file search add-apt-repository && \ apt-get install -y software-properties-common RUN apt-add-repository ppa:brightbox/ruby-ng && \ apt-get update && \ apt-get install -y ruby2.2 RUN gem install redis RUN cd /opt && \ apt-get install -y \ wget \ gcc \ make \ && \ wget -q http://download.redis.io/releases/redis-${REDIS_VERSION}.tar.gz && \ tar -zxvf redis-${REDIS_VERSION}.tar.gz && \ mv redis-${REDIS_VERSION} redis-src && \ cd redis-src && \ make && \ make PREFIX=${REDIS_HOME} install EXPOSE 6379 RUN mkdir conf ADD redis.conf.template conf/redis.conf.template ADD start-redis.sh start-redis.sh RUN chmod a+x start-redis.sh ENTRYPOINT ["./start-redis.sh"]
ã ãã«Ruby 2.2ã䜿ãããã«èšå®ã
RUN apt-get install -y apt-file && \ apt-file update && \ apt-file search add-apt-repository && \ apt-get install -y software-properties-common RUN apt-add-repository ppa:brightbox/ruby-ng && \ apt-get update && \ apt-get install -y ruby2.2
gemã§redisãå¿ èŠã¿ããã§ãã
RUN gem install redis
ãŸããã--net=hostãã䜿ãã®ãåæãªã®ã§ãããŒããDockerèµ·åæã«åŒæ°ã§åããšããããªæ§æã«ããŸããã
ãšããããã§ãèšå®ãã¡ã€ã«ã®ãã³ãã¬ãŒããçšæã
redis.conf.template
port %PORT% cluster-enabled yes cluster-config-file conf/nodes.conf cluster-node-timeout 5000 appendonly yes
å 容ã¯ããã¥ãŒããªã¢ã«ã«ããæå°æ§æã®èšå®ã§ãã
èµ·åã¹ã¯ãªããããã¡ããENTRYPOINTã«èšå®ã
start-redis.sh
#!/bin/bash if [ "$1" != "" ]; then PORT=$1 else PORT=7000 fi perl -wp -e "s!%PORT%!${PORT}!" conf/redis.conf.template > conf/redis.conf bin/redis-server conf/redis.conf
åŒæ°ã«ããŒããæå®ãããšããã®å€ã§èšå®ãã¡ã€ã«ãäœã£ãŠèµ·åããŸãããšã
ã§ããã«ãã
$ docker build -t kazuhira/redis-cluster:3.0.6 .
ããã§ãæºåå®äºã
Redisã®åããŒãã®èµ·å
ããã§ã¯ãRedisãèµ·åããŸãããŸãã¯3ããŒãã
## Node1 $ docker run -it --rm --net=host --name redis-server1 kazuhira/redis-cluster:3.0.6 7000 ## Node2 $ docker run -it --rm --net=host --name redis-server2 kazuhira/redis-cluster:3.0.6 7001 ## Node3 $ docker run -it --rm --net=host --name redis-server3 kazuhira/redis-cluster:3.0.6 7002
ããã ãã ãšãåã«3ã€ããŒããããã ãã§ãã
ã¯ã©ã¹ã¿ãæ§æãã
ã§ã¯ããã®3ããŒããã¯ã©ã¹ã¿ãšããŠæ§æããŸãã
ã²ãšã€ãDockerã³ã³ããã«å ¥ã£ãŠ
$ docker exec -it redis-server1 bash
Redisã®ãœãŒã¹ã³ãŒãã®äžã«ããããredis-trib.rbããšããã¹ã¯ãªããã䜿çšããŸãã
â»ã/opt/redis-srcããã£ã¬ã¯ããªã¯ããã®ãšã³ããªã§ã®RedisãœãŒã¹ã³ãŒãã®å±éå
ã§ã
# /opt/redis-src/src/redis-trib.rb
çŽæ¥å®è¡ãããšããã«ããåºãŠããŸãã
# /opt/redis-src/src/redis-trib.rb /opt/redis-src/src/redis-trib.rb:1573: warning: duplicated key at line 1573 ignored: "threshold" Usage: redis-trib <command> <options> <arguments ...> create host1:port1 ... hostN:portN --replicas <arg> check host:port info host:port fix host:port --timeout <arg> reshard host:port --from <arg> --to <arg> --slots <arg> --yes --timeout <arg> --pipeline <arg> rebalance host:port --weight <arg> --auto-weights --threshold <arg> --use-empty-masters --timeout <arg> --simulate --pipeline <arg> add-node new_host:new_port existing_host:existing_port --slave --master-id <arg> del-node host:port node_id set-timeout host:port milliseconds call host:port command arg arg .. arg import host:port --from <arg> --copy --replace help (show this help) For check, fix, reshard, del-node, set-timeout you can specify the host and port of any working node in the cluster.
ãã®ã¹ã¯ãªããã䜿çšããŠã3ã€ã®ããŒããã¯ã©ã¹ã¿ã«åå ãããŸãã
â»ä»åã¯ãå
šéšãã¹ã¿ãŒããŒããšããŠäœæããŸã
# /opt/redis-src/src/redis-trib.rb create 127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002 /opt/redis-src/src/redis-trib.rb:1573: warning: duplicated key at line 1573 ignored: "threshold" >>> Creating cluster >>> Performing hash slots allocation on 3 nodes... Using 3 masters: 127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002 M: 73878b5b59102996acf8c1acaba831a022cdcdcc 127.0.0.1:7000 slots:0-5460 (5461 slots) master M: 3c95936f29dd29eb32f34a8b1bfacd5e477e3360 127.0.0.1:7001 slots:5461-10922 (5462 slots) master M: 4ca10031c591cee679e1007d201f8066992af608 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: 73878b5b59102996acf8c1acaba831a022cdcdcc 127.0.0.1:7000 slots:0-5460 (5461 slots) master M: 3c95936f29dd29eb32f34a8b1bfacd5e477e3360 127.0.0.1:7001 slots:5461-10922 (5462 slots) master M: 4ca10031c591cee679e1007d201f8066992af608 127.0.0.1:7002 slots:10923-16383 (5461 slots) master [OK] All nodes agree about slots configuration. >>> Check for open slots... >>> Check slots coverage... [OK] All 16384 slots covered.
ã¯ã©ã¹ã¿ã®ç¶æ ã確èªããŠã¿ãŸãããã¡ãã¯ãredis-cliã§å¯èœã§ãã
# bin/redis-cli -p 7000 cluster info cluster_state:ok cluster_slots_assigned:16384 cluster_slots_ok:16384 cluster_slots_pfail:0 cluster_slots_fail:0 cluster_known_nodes:3 cluster_size:3 cluster_current_epoch:3 cluster_my_epoch:1 cluster_stats_messages_sent:167 cluster_stats_messages_received:167
ã¯ã©ã¹ã¿ã«åå ããŠããããŒãã
# bin/redis-cli -p 7000 cluster nodes 3c95936f29dd29eb32f34a8b1bfacd5e477e3360 127.0.0.1:7001 master - 0 1452952573411 2 connected 5461-10922 4ca10031c591cee679e1007d201f8066992af608 127.0.0.1:7002 master - 0 1452952572405 3 connected 10923-16383 73878b5b59102996acf8c1acaba831a022cdcdcc 127.0.0.1:7000 myself,master - 0 0 1 connected 0-5460
ã§ãããŒãã«æ¥ç¶ããŠsetããŠã¿ããš
# bin/redis-cli -p 7000 127.0.0.1:7000> set key1 value1 (error) MOVED 9189 127.0.0.1:7001
æãããŸãã
ããã¯ãã-cããä»ããŠèµ·åãããšãªãã€ã¬ã¯ãããŠãããããã§ãã
# bin/redis-cli -p 7000 -c 127.0.0.1:7000> set key1 value1 -> Redirected to slot [9189] located at 127.0.0.1:7001 OK
ããå°ãç»é²ã
127.0.0.1:7001> set key2 value2 -> Redirected to slot [4998] located at 127.0.0.1:7000 OK 127.0.0.1:7000> set key3 value3 OK
key3ã¯ãèªåã«å²ãåœãŠãããŠããããã§ãã
ã¡ãªã¿ã«ãæåã«ã¡ãã£ãšããã£ãã®ããããŒããæžãæã«
127.0.0.1:7000
ã¿ããã«IPã¢ãã¬ã¹ã§ã¯ãªãã
localhost:7000
ã¿ããã«ãã¹ãåã§æžããšãã¯ã©ã¹ã¿ã®æ§æã«å€±æããŸãã
ãããªãšã©ãŒãåãåã£ãŠã
call': ERR Invalid node address specified: localhost:7000 (Redis::CommandError)
ã©ãããããã¹ãåã¯äœ¿çšäžå¯ã§ãIPã¢ãã¬ã¹ã§æžãå¿ èŠããããããã§ãã
Redis-trib by using hostnames fails to join cluster · Issue #2071 · antirez/redis · GitHub
ããŒãã远å ãã
ç¶ããŠãããŒãã远å ããŠã¿ãŸããæ°ããRedisãèµ·åã
$ docker run -it --rm --net=host --name redis-server4 kazuhira/redis-cluster:3.0.6 7003
åœç¶ããŸã ã¯ã©ã¹ã¿ã«ã¯åå ããŠããŸããã
ã¯ã©ã¹ã¿ã«è¿œå ããã«ã¯ããredis-trib.rb add-nodeãã䜿çšããŸãã
# /opt/redis-src/src/redis-trib.rb add-node 127.0.0.1:7003 127.0.0.1:7000
ã127.0.0.1:7003ãã¯æ°ããããŒããã127.0.0.1:7000ãã¯æ¢åã®ããŒãã§ãã
å®è¡ã
# /opt/redis-src/src/redis-trib.rb add-node 127.0.0.1:7003 127.0.0.1:7000 /opt/redis-src/src/redis-trib.rb:1573: warning: duplicated key at line 1573 ignored: "threshold" >>> 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: 73878b5b59102996acf8c1acaba831a022cdcdcc 127.0.0.1:7000 slots:0-5460 (5461 slots) master 0 additional replica(s) M: 3c95936f29dd29eb32f34a8b1bfacd5e477e3360 127.0.0.1:7001 slots:5461-10922 (5462 slots) master 0 additional replica(s) M: 4ca10031c591cee679e1007d201f8066992af608 127.0.0.1:7002 slots:10923-16383 (5461 slots) master 0 additional replica(s) [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ããŸãã
# /opt/redis-src/src/redis-trib.rb reshard 127.0.0.1:7003 /opt/redis-src/src/redis-trib.rb:1573: warning: duplicated key at line 1573 ignored: "threshold" >>> Performing Cluster Check (using node 127.0.0.1:7003) M: 93af9513be1feb3f1088b003737c1f7ab80a8681 127.0.0.1:7003 slots: (0 slots) master 0 additional replica(s) M: 3c95936f29dd29eb32f34a8b1bfacd5e477e3360 127.0.0.1:7001 slots:5461-10922 (5462 slots) master 0 additional replica(s) M: 4ca10031c591cee679e1007d201f8066992af608 127.0.0.1:7002 slots:10923-16383 (5461 slots) master 0 additional replica(s) M: 73878b5b59102996acf8c1acaba831a022cdcdcc 127.0.0.1:7000 slots:0-5460 (5461 slots) master 0 additional replica(s) [OK] All nodes agree about slots configuration. >>> Check for open slots... >>> Check slots coverage... [OK] All 16384 slots covered. How many slots do you want to move (from 1 to 16384)?
ã¹ãããïŒ1ã16384ïŒã®ç¯å²ãã©ãå²ãæ¯ããèãããã®ã§ãä»å㯠16384 / 4ã§4096ã§ãããŸãã
How many slots do you want to move (from 1 to 16384)? 4096
次ã«ãããŒã¿ãåãåãããŒãïŒä»å远å ããããŒãïŒãæå®ããŸãã
What is the receiving node ID? 93af9513be1feb3f1088b003737c1f7ab80a8681
ãããŠã©ã®ããŒãããã¹ããããåãããèãããã®ã§ãããä»åã¯å šäœããåããããšã«ããŠãallããšçããŸãã
Please enter all the source node IDs. Type 'all' to use all the nodes as source nodes for the hash slots. Type 'done' once you entered all the source nodes IDs. Source node #1:all Ready to move 4096 slots. Source nodes: M: 3c95936f29dd29eb32f34a8b1bfacd5e477e3360 127.0.0.1:7001 slots:5461-10922 (5462 slots) master 0 additional replica(s) M: 4ca10031c591cee679e1007d201f8066992af608 127.0.0.1:7002 slots:10923-16383 (5461 slots) master 0 additional replica(s) M: 73878b5b59102996acf8c1acaba831a022cdcdcc 127.0.0.1:7000 slots:0-5460 (5461 slots) master 0 additional replica(s) Destination node: M: 93af9513be1feb3f1088b003737c1f7ab80a8681 127.0.0.1:7003 slots: (0 slots) master 0 additional replica(s)
ãããšããªã·ã£ãŒãã®ãã©ã³ã衚瀺ãããã®ã§
Resharding plan: Moving slot 5461 from 3c95936f29dd29eb32f34a8b1bfacd5e477e3360 Moving slot 5462 from 3c95936f29dd29eb32f34a8b1bfacd5e477e3360 Moving slot 5463 from 3c95936f29dd29eb32f34a8b1bfacd5e477e3360 Moving slot 5464 from 3c95936f29dd29eb32f34a8b1bfacd5e477e3360 Moving slot 5465 from 3c95936f29dd29eb32f34a8b1bfacd5e477e3360 ãããçç¥ã
ãyesããšçããŸãã
Do you want to proceed with the proposed reshard plan (yes/no)? yes
ããšã¯ããªã·ã£ãŒããããæ§åãç¶ããŸãâŠã
çµäºãããšãã¯ã©ã¹ã¿ã«åå ããŠããã€ã¹ããããå²ãåœãŠãããããšã確èªã§ããŸãã
# bin/redis-cli -p 7000 cluster nodes 3c95936f29dd29eb32f34a8b1bfacd5e477e3360 127.0.0.1:7001 master - 0 1452953663376 2 connected 6827-10922 93af9513be1feb3f1088b003737c1f7ab80a8681 127.0.0.1:7003 master - 0 1452953661865 4 connected 0-1364 5461-6826 10923-12287 4ca10031c591cee679e1007d201f8066992af608 127.0.0.1:7002 master - 0 1452953662369 3 connected 12288-16383 73878b5b59102996acf8c1acaba831a022cdcdcc 127.0.0.1:7000 myself,master - 0 0 1 connected 1365-5460
ã¯ã©ã¹ã¿ã®æ å ±ã
# bin/redis-cli -p 7000 cluster info cluster_state:ok cluster_slots_assigned:16384 cluster_slots_ok:16384 cluster_slots_pfail:0 cluster_slots_fail:0 cluster_known_nodes:4 cluster_size:4 cluster_current_epoch:4 cluster_my_epoch:1 cluster_stats_messages_sent:2932 cluster_stats_messages_received:2934
確èª
redis-cliã§æ¥ç¶ããŠãããŒã¿ç»é²ããŠã¿ãŸãã
# bin/redis-cli -p 7000 -c 127.0.0.1:7000> set key4 value4 -> Redirected to slot [13120] located at 127.0.0.1:7002 OK 127.0.0.1:7002> set key5 value5 -> Redirected to slot [9057] located at 127.0.0.1:7001 OK 127.0.0.1:7001> set key6 value6 -> Redirected to slot [4866] located at 127.0.0.1:7000 OK 127.0.0.1:7000> set key7 value7 -> Redirected to slot [803] located at 127.0.0.1:7003 OK
远å ããããŒãããkey7ã§çŸããŸããã
ããŒããåé€ãã
ããŒããåé€ããã«ã¯ããredis-trib.rb del-nodeãã䜿çšããŸãã
# /opt/redis-src/src/redis-trib.rb del-node 127.0.0.1:7003 93af9513be1feb3f1088b003737c1f7ab80a8681
åé€ã«ã¯ãIPã¢ãã¬ã¹ãããŒããšããŒãã®IDãå¿ èŠã§ãã
ãšãããããããå®è¡ãããšãããŒãã空ãããªããïŒããšæãããŸãã
# /opt/redis-src/src/redis-trib.rb del-node 127.0.0.1:7003 93af9513be1feb3f1088b003737c1f7ab80a8681 /opt/redis-src/src/redis-trib.rb:1573: warning: duplicated key at line 1573 ignored: "threshold" >>> Removing node 93af9513be1feb3f1088b003737c1f7ab80a8681 from cluster 127.0.0.1:7003 [ERR] Node 127.0.0.1:7003 is not empty! Reshard data away and try again.
ããŒããåé€ããã«ã¯ãããŒãã空ã§ãªããŠã¯ãªããªãããã§ãã
ããã§ãreshardããŠããŒã7003ã®ããŒãããããŒã¿ã远ãåºããŠã¿ãŸãã
â»FLUSHALLã§ããããšãæžããŠãããšã³ããªã¯èŠãã®ã§ããâŠè©ŠããŠããŸãã
# /opt/redis-src/src/redis-trib.rb reshard 127.0.0.1:7003 /opt/redis-src/src/redis-trib.rb:1573: warning: duplicated key at line 1573 ignored: "threshold" >>> Performing Cluster Check (using node 127.0.0.1:7003) M: 93af9513be1feb3f1088b003737c1f7ab80a8681 127.0.0.1:7003 slots:0-1364,5461-6826,10923-12287 (4096 slots) master 0 additional replica(s) M: 3c95936f29dd29eb32f34a8b1bfacd5e477e3360 127.0.0.1:7001 slots:6827-10922 (4096 slots) master 0 additional replica(s) M: 4ca10031c591cee679e1007d201f8066992af608 127.0.0.1:7002 slots:12288-16383 (4096 slots) master 0 additional replica(s) M: 73878b5b59102996acf8c1acaba831a022cdcdcc 127.0.0.1:7000 slots:1365-5460 (4096 slots) master 0 additional replica(s) [OK] All nodes agree about slots configuration. >>> Check for open slots... >>> Check slots coverage... [OK] All 16384 slots covered.
ããã§ãã¹ãããã®ç¯å²ã¯16384ã3ã§å²ã£ã5462ïŒåãäžãïŒã«ããŸãã
How many slots do you want to move (from 1 to 16384)? 5462
ç§»åå ã®ããŒãã¯ãã¯ã©ã¹ã¿ã«æ®ãããŒãã«ããŠ
What is the receiving node ID? 73878b5b59102996acf8c1acaba831a022cdcdcc
ç§»åå ã¯ãåé€å¯Ÿè±¡ã®ããŒãã«ããŸãã
Please enter all the source node IDs. Type 'all' to use all the nodes as source nodes for the hash slots. Type 'done' once you entered all the source nodes IDs. Source node #1:93af9513be1feb3f1088b003737c1f7ab80a8681
2ã€ç®ã¯ãªãã®ã§ããdoneãã
Source node #2:done
ãããšãä»åºŠã¯ããŒããåé€ããããšãã§ããããã«ãªããŸãã
# /opt/redis-src/src/redis-trib.rb del-node 127.0.0.1:7003 93af9513be1feb3f1088b003737c1f7ab80a8681 /opt/redis-src/src/redis-trib.rb:1573: warning: duplicated key at line 1573 ignored: "threshold" >>> Removing node 93af9513be1feb3f1088b003737c1f7ab80a8681 from cluster 127.0.0.1:7003 >>> Sending CLUSTER FORGET messages to the cluster... >>> SHUTDOWN the node.
åé€ããåã«ããcluster nodesãã§èŠããšã¹ããããå€ããŠããŸãã
â»çµæãåãçŽããã®ã§Node IDãå€ãã£ãŠãŸããããæ°ã«ãªãããâŠ
# bin/redis-cli -p 7000 cluster nodes 8766435737ca2b3b64b536fc8c5b27ba771f622b 127.0.0.1:7003 master - 0 1452954698203 6 connected 3c95936f29dd29eb32f34a8b1bfacd5e477e3360 127.0.0.1:7001 master - 0 1452954697701 2 connected 7851-10922 4ca10031c591cee679e1007d201f8066992af608 127.0.0.1:7002 master - 0 1452954697198 3 connected 13312-16383 73878b5b59102996acf8c1acaba831a022cdcdcc 127.0.0.1:7000 myself,master - 0 0 7 connected 0-7850 10923-13311
ãšããããããªããšãéããæãã§ãã