計划用 Docker 實現 Redis 的主從,簡單主從而已。主的名稱叫 redis-master
一步步來。
先新建個Dockerfile ,從alpine 開始,比較簡單。
FROM alpine:latest
MAINTAINER qufo qufo@163.com # 換源 RUN echo 'http://mirrors.ustc.edu.cn/alpine/edge/main' > /etc/apk/repositories RUN echo '@community http://mirrors.ustc.edu.cn/alpine/edge/community' >> /etc/apk/repositories RUN echo '@testing http://mirrors.ustc.edu.cn/alpine/edge/testing' >> /etc/apk/repositories RUN apk update # 修正時區 ENV TIMEZONE Asia/Shanghai RUN apk add tzdata RUN ln -snf /usr/share/zoneinfo/$TIMEZONE /etc/localtime RUN echo $TIMEZONE > /etc/timezone # 修改一些系統設置 RUN echo 'vm.overcommit_memory = 1' >> /etc/sysctl.conf RUN echo "echo never > /sys/kernel/mm/transparent_hugepage/enabled" >> /etc/rc.local # 開始安裝 redis RUN apk add redis COPY start_redis.sh /usr/local/ RUN chmod +x /usr/local/start_redis.sh RUN chown redis:redis /usr/local/start_redis.sh EXPOSE 6379 ENTRYPOINT ["sh","/usr/local/start_redis.sh"] CMD ["master"]
可以看到,我們還需要一個啟動腳本。start_redis.sh
redis_role=$1
sed -i 's/protected-mode yes/protected-mode no/g' /etc/redis.conf sed -i 's/daemonize yes/daemonize no/g' /etc/redis.conf sed -i 's/bind 127.0.0.1/bind 0.0.0.0/g' /etc/redis.conf echo "Start Redis by " if [ $redis_role = "master" ]; then echo "master" redis-server /etc/redis.conf elif [ $redis_role = "slave" ]; then echo "slave" sed -i 's/# slaveof <masterip> <masterport>/slaveof redis-master 6379/g' /etc/redis.conf redis-server /etc/redis.conf else echo "unknow role!" fi
這里修改了一些系統配置,然后根據傳進來的 role 區別啟動主或從模式。其中的主名稱是寫死了的 redis-master
好了,現在構建,在Dockerfile 和 start_redis.sh 所在的目錄下,執行
docker rmi qufo/redis
docker build -t="qufo/redis" .
我們就得到了一個名為 qufo/redis 的 image , 因為采用的是 alpine 的包,所以速度很快,在我的機器上大概7秒就完成了。
通過
docker images
看下鏡象的信息,只有9M多些。
好了,現在來啟動他們,啟運完后檢查一下是不是都在。
ufo@ubuntu:~$ docker run -d --name=redis-master -p=6379:6379 qufo/redis master
ad7c5a6e16a8d87f04240c7bcb20ef765eab832737f32457e956966a2f282179
ufo@ubuntu:~$ docker run -d --name=node1 --link=redis-master:redis-master -p=7001:6379 qufo/redis slave 8cef160881f59b017cd915775fa3f76d9456b510b300147779fd8ff4ba9f9a2c ufo@ubuntu:~$ docker run -d --name=node2 --link=redis-master:redis-master -p=7002:6379 qufo/redis slave 767011663ef8b93b5326bd4f9940762922ee4a685278806d42b8ce690164de48 ufo@ubuntu:~$ docker run -d --name=node3 --link=redis-master:redis-master -p=7003:6379 qufo/redis slave 6c4bb442d5adb6773301bac29e6a7a5b1f636d47c67dc21c9ec0ec28cf988602 ufo@ubuntu:~$ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 6c4bb442d5ad qufo/redis "sh /usr/local/start_" 38 seconds ago Up 37 seconds 0.0.0.0:7003->6379/tcp node3 767011663ef8 qufo/redis "sh /usr/local/start_" 48 seconds ago Up 47 seconds 0.0.0.0:7002->6379/tcp node2 8cef160881f5 qufo/redis "sh /usr/local/start_" 57 seconds ago Up 56 seconds 0.0.0.0:7001->6379/tcp node1 ad7c5a6e16a8 qufo/redis "sh /usr/local/start_" About a minute ago Up About a minute 0.0.0.0:6379->6379/tcp redis-master
可以看到有一主(redis-master)多從 node1,node2,node3。
現在來試一下,在主里 set ,從里 get
# 利用映射出來的端品直接連 redis-master
ufo@ubuntu:~/$ redis-cli 127.0.0.1:6379> info replication # Replication role:master connected_slaves:3 slave0:ip=172.17.0.3,port=6379,state=online,offset=239,lag=0 slave1:ip=172.17.0.4,port=6379,state=online,offset=239,lag=1 slave2:ip=172.17.0.5,port=6379,state=online,offset=239,lag=1 master_repl_offset:239 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:2 repl_backlog_histlen:238 127.0.0.1:6379> set username qufo OK 127.0.0.1:6379> get username "qufo" 127.0.0.1:6379> exit # 可見 為 master 模式,在里面設置和 username # 通過 7001 連接 node1 ufo@ubuntu:~/$ redis-cli -p 7001 127.0.0.1:7001> info replication # Replication role:slave master_host:redis-master master_port:6379 master_link_status:up master_last_io_seconds_ago:8 master_sync_in_progress:0 slave_repl_offset:327 slave_priority:100 slave_read_only:1 connected_slaves:0 master_repl_offset:0 repl_backlog_active:0 repl_backlog_size:1048576 repl_backlog_first_byte_offset:0 repl_backlog_histlen:0 127.0.0.1:7001> get username "qufo" 127.0.0.1:7001> set username nothing (error) READONLY You can't write against a read only slave. 127.0.0.1:7001> exit ufo@ubuntu:~/$ # 可見為 slave 模式,可以 get username ,但不能 set username 因為slave 是只讀的。
好吧,主從配置完成。