首页 > 云计算 > Docker/K8 > 基于docker环境下搭建redis主从集群
笔者给大家介绍基于docker环境下搭建Redis主从复制集群,如何让redis主从集群在docker容器上面良好运行,容器下发生故障时又如何对redis主从进行切换操作。
l 使用异步复制。
l 支持一主多从。一个master可以有多个slave。
l Slave可以接受来自其它slaves的连接。除了可以连接多个slaves到同一个master之外,slaves也可以连接到其它的slaves以类似级联的方式。
l Redis复制在master端是非阻塞的。这意味着,master可以继续处理(来自客户端的)请求当slave在执行初次同步时。
l Redis复制可以用于扩容,如使用多个slaves用于只读查询,也可以只是用于数据冗余。
l Redis复制也可能用来避免让master把整个数据集写入硬盘。该技术需要先配置master的redis.conf文件,然后连接一个slave,该slave必须被配置为不时地进行保存,或启用了AOF。
1、节省redis主从安装与配置工作;
2、能够以秒级速度启动redis容器;
3、能够快速扩展redis从节点;
4、能快速进行redis主从切换;
5、可迁移性强。

这里采用一主二从模式来测试
|
编号 |
节点名 |
IP 地址 |
用途 |
|
1 |
redis-master |
192.168.56.108 |
Redis主节点,节点数据可写读 |
|
2 |
redis-slave01 |
192.168.56.109 |
Redis从节点1,节点数据可读不可写 |
|
3 |
redis-slave02 |
192.168.56.110 |
Redis从节点2,节点数据可读不可写 |
1 、Redis镜像dockerfile脚本
|
FROM jaymarco/centos:7.3 MAINTAINER jaymarco ENV VERSION=3.2.5 ENV DOWN_URL=http://download.redis.io/releases/redis-${VERSION}.tar.gz \ TEMP_DIR=/tmp/redis \ DATA_DIR=/data/redis RUN mkdir -p ${TEMP_DIR} ${DATA_DIR} && \ yum install -y gcc gcc-c++ make cmake tar && \ groupadd redis && useradd -g redis -d ${DATA_DIR} -s /sbin/nologin redis && \ curl -Lk ${DOWN_URL} |tar xz -C ${TEMP_DIR} --strip-components=1 && \ cd ${TEMP_DIR} && \ make -C ${TEMP_DIR} -j $(awk '/processor/{i++}END{print i}' /proc/cpuinfo) && \ make -C ${TEMP_DIR} install && \ rm -rf ${TEMP_DIR} && \ /bin/cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime &&\ echo 'Asia/Shanghai' >/etc/timezone COPY entrypoint.sh /entrypoint.sh RUN chmod +x /entrypoint.sh VOLUME ${DATA_DIR} WORKDIR ${DATA_DIR} EXPOSE 6379/tcp ENTRYPOINT ["/entrypoint.sh"] |
2 、Redis初始化启动脚本
构建dockerfile时将操作系统参数进行优化。
|
#!/bin/bash if ! which redis-server >/dev/null 2>&1; then source /etc/profile.d/redis.sh fi set -e sysctl -w net.core.somaxconn=1024 >/dev/null 2>&1 sysctl -w vm.overcommit_memory=1 >/dev/null 2>&1 echo never > /sys/kernel/mm/transparent_hugepage/enabled echo never > /sys/kernel/mm/transparent_hugepage/defrag
# first arg is `-f` or `--some-option` # or first arg is `something.conf` if [ "${1#-}" != "$1" ] || [ "${1%.conf}" != "$1" ]; then set -- redis-server "$@" fi
# allow the container to be started with `--user` if [ "$1" = 'redis-server' -a "$(id -u)" = '0' ]; then chown -R redis . #exec gosu redis "$0" "$@" fi
if [ "$1" = 'redis-server' ]; then doProtectedMode=1 configFile= if [ -f "$2" ]; then configFile="$2" if grep -q '^protected-mode' "$configFile"; then doProtectedMode= fi fi if [ "$doProtectedMode" ]; then shift # "redis-server" if [ "$configFile" ]; then shift fi set -- --protected-mode no "$@" if [ "$configFile" ]; then set -- "$configFile" "$@" fi set -- redis-server "$@" fi fi
exec "$@" |
3 、构建redis基础镜像
在dockerfile文件同级目录下进行对redis镜像封装,最后会生成一个jaymarco/redis:3.2.5的镜像文件。可参考下面命令构建redis镜像:
|
docker build –t jaymarco/redis: 3.2.5 . |
4 、redis镜像导入其它节点
当Redis的docker镜像已经在其中一个节点封装好后需要将redisr的docker镜像同步到其它两台redis主机节点。
|
1 、查看redis镜像拿到镜像ID: 04fd033441e2。
2 、使用 docker save 命令将 redis 镜像以文件形式保存到宿主机磁盘。
3 、将 redis325.tar 文件远程拷贝到其他两个 redis 节点上面。 scp redis325.tar 192.168.56.109:/home scp redis325.tar 192.168.56.110:/home 4 、使用 docker load 命令将 redis325.tar 导入 docker 。
|
通过以上操作已经完成redis镜像封装,并将镜像同步到其它节点,说明redis三个节点上面都存在redis docker镜像。
关于Redis主从集群关键在于主从之间的redis.conf配置文件,它做了主从的参数设置与性能优化配置。前面我们已经将redis的软件以镜像方式安装在三台节点上面。接下来我们通过配置进行redis主从集群环境搭建。同时我们启动redis容器采用主机网络模式,分别将redis容器在三台虚拟主机上面运行。
接下来对redis-master主节点进行配置。
1、redis配置文件
|
bind 0.0.0.0 protected-mode yes port 6379 tcp-backlog 511 timeout 0 tcp-keepalive 300 daemonize no supervised no pidfile /var/run/redis_6379.pid loglevel notice logfile "" databases 8 save 900 1 save 300 10 save 60 10000 stop-writes-on-bgsave-error yes rdbcompression yes rdbchecksum yes dbfilename dump.rdb dir /data/redis slave-serve-stale-data yes slave-read-only yes repl-diskless-sync no repl-diskless-sync-delay 5 repl-disable-tcp-nodelay no slave-priority 100 appendonly no appendfilename "appendonly.aof" appendfsync everysec no-appendfsync-on-rewrite no auto-aof-rewrite-percentage 100 auto-aof-rewrite-min-size 64mb aof-load-truncated yes lua-time-limit 5000 slowlog-log-slower-than 10000 slowlog-max-len 128 latency-monitor-threshold 0 notify-keyspace-events "" hash-max-ziplist-entries 512 hash-max-ziplist-value 64 list-max-ziplist-size -2 list-compress-depth 0 set-max-intset-entries 512 zset-max-ziplist-entries 128 zset-max-ziplist-value 64 hll-sparse-max-bytes 3000 activerehashing yes client-output-buffer-limit normal 0 0 0 client-output-buffer-limit slave 256mb 64mb 60 client-output-buffer-limit pubsub 32mb 8mb 60 hz 10 aof-rewrite-incremental-fsync yes masterauth JayRedisHaZi requirepass JayRedisHaZi |
2、启动master redis容器
|
docker run -d \ --privileged --name redis-master \ --network host \ -v /etc/redis.conf:/etc/redis.conf \ -v /etc/localtime:/etc/localtime \ jaymarco/redis:3.2.5
看下面主节点的 redis 容器成功启动
|
接下来对redis-slave01从节点进行配置。
1、redis配置文件
|
bind 0.0.0.0 protected-mode yes port 6379 tcp-backlog 511 timeout 0 tcp-keepalive 300 daemonize no supervised no pidfile /var/run/redis_6379.pid loglevel notice logfile "" databases 8 save 900 1 save 300 10 save 60 10000 stop-writes-on-bgsave-error yes rdbcompression yes rdbchecksum yes dbfilename dump.rdb dir /data/redis slave-serve-stale-data yes slave-read-only yes repl-diskless-sync no repl-diskless-sync-delay 5 repl-disable-tcp-nodelay no slave-priority 100 appendonly no appendfilename "appendonly.aof" appendfsync everysec no-appendfsync-on-rewrite no auto-aof-rewrite-percentage 100 auto-aof-rewrite-min-size 64mb aof-load-truncated yes lua-time-limit 5000 slowlog-log-slower-than 10000 slowlog-max-len 128 latency-monitor-threshold 0 notify-keyspace-events "" hash-max-ziplist-entries 512 hash-max-ziplist-value 64 list-max-ziplist-size -2 list-compress-depth 0 set-max-intset-entries 512 zset-max-ziplist-entries 128 zset-max-ziplist-value 64 hll-sparse-max-bytes 3000 activerehashing yes client-output-buffer-limit normal 0 0 0 client-output-buffer-limit slave 256mb 64mb 60 client-output-buffer-limit pubsub 32mb 8mb 60 hz 10 aof-rewrite-incremental-fsync yes slaveof 192.168.56.108 6379 masterauth JayRedisHaZi requirepass JayRedisHaZi |
2 启动master redis容器
|
docker run -d \ --privileged --name redis-slave01 \ --network host \ -v /etc/redis.conf:/etc/redis.conf \ -v /etc/localtime:/etc/localtime \ jaymarco/redis:3.2.5 看下面主节点的 redis 容器成功启动
|
接下来对redis-slave02从节点进行配置。
1、redis配置文件
|
bind 0.0.0.0 protected-mode yes port 6379 tcp-backlog 511 timeout 0 tcp-keepalive 300 daemonize no supervised no pidfile /var/run/redis_6379.pid loglevel notice logfile "" databases 8 save 900 1 save 300 10 save 60 10000 stop-writes-on-bgsave-error yes rdbcompression yes rdbchecksum yes dbfilename dump.rdb dir /data/redis slave-serve-stale-data yes slave-read-only yes repl-diskless-sync no repl-diskless-sync-delay 5 repl-disable-tcp-nodelay no slave-priority 100 appendonly no appendfilename "appendonly.aof" appendfsync everysec no-appendfsync-on-rewrite no auto-aof-rewrite-percentage 100 auto-aof-rewrite-min-size 64mb aof-load-truncated yes lua-time-limit 5000 slowlog-log-slower-than 10000 slowlog-max-len 128 latency-monitor-threshold 0 notify-keyspace-events "" hash-max-ziplist-entries 512 hash-max-ziplist-value 64 list-max-ziplist-size -2 list-compress-depth 0 set-max-intset-entries 512 zset-max-ziplist-entries 128 zset-max-ziplist-value 64 hll-sparse-max-bytes 3000 activerehashing yes client-output-buffer-limit normal 0 0 0 client-output-buffer-limit slave 256mb 64mb 60 client-output-buffer-limit pubsub 32mb 8mb 60 hz 10 aof-rewrite-incremental-fsync yes slaveof 192.168.56.108 6379 masterauth JayRedisHaZi requirepass JayRedisHaZi |
2启动master redis容器
|
docker run -d \ --privileged --name redis-slave02 \ --network host \ -v /etc/redis.conf:/etc/redis.conf \ -v /etc/localtime:/etc/localtime \ jaymarco/redis:3.2.5
看下面主节点的 redis 容器成功启动
|
通过下面命令检查master和slave主从同步状态
|
1 、 redis-master 状态日志 docker exec -it redis-master redis-cli -h 192.168.56.108 -a JayRedisHaZi info replication # Replication role:master connected_slaves:2 slave0:ip=192.168.56.110,port=6379,state=online,offset=99,lag=0 slave1:ip=192.168.56.109,port=6379,state=online,offset=99,lag=1 master_repl_offset:113 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:2 repl_backlog_histlen:112
2 、 redis-slave01 状态日志 docker exec -it redis-slave01 redis-cli -h 192.168.56.109 -a JayRedisHaZi info replication # Replication role:slave master_host:192.168.56.108 master_port:6379 master_link_status:up master_last_io_seconds_ago:8 master_sync_in_progress:0 slave_repl_offset:253 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
3 、 redis-slave02 状态日志 docker exec -it redis-slave02 redis-cli -h 192.168.56.110 -a JayRedisHaZi info replication # Replication role:slave master_host:192.168.56.108 master_port:6379 master_link_status:up master_last_io_seconds_ago:9 master_sync_in_progress:0 slave_repl_offset:281 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 |
1、redis master主节点插入两个值
2、redis slave01从节点1上面可以正常查看到数据
3、redis slave01从节点1上面可以正常查看到数据
redis 两台slave从节点验证写入数据失败,提示只读模式。
接下了做一个这样的主从切换模拟测试,将redis master主节点(192.168.56.108)的redis服务停个,并将redis slave从节点1(192.168.56.109)切换成redis master主节点。也将原来的master主节点切换成slave从节点,最后再对主从进行验证。
以下是主从切换和从主切换的操作步骤:
|
1 、模拟主节点宕机 ( 192.168.56.108 操作) docker stop redis-master;
2 、将 slave 节点 1 切换成 master 主节点 (192.168.56.109 操作 ) docker exec -it redis-slave01 redis-cli -h 192.168.56.109 -a JayRedisHaZi CONFIG SET slave-read-only no docker exec -it redis-slave01 redis-cli -h 192.168.56.109 -a JayRedisHaZi SLAVEOF NO ONE
3 、将 slave 节点 2 加入新的 master 节点 (192.168.56.110 操作 ) docker exec -it redis-slave02 redis-cli -h 192.168.56.110 -a JayRedisHaZi SLAVEOF 192.168.56.109 6379
4 、将原来 master 主节点切换成 slave 从节点 (192.168.56.108 操作 ) docker exec -it redis redis-cli -h 192.168.56.108 -a JayRedisHaZi CONFIG SET slave-read-only no docker exec -it redis redis-cli -h 192.168.56.108 -a JayRedisHaZi SLAVEOF NO ONE |
从下面状态数据来看主机192.168.56.109上面的redis容器从原来的slave节点变成了master节点,而主机上面的192.168.56.108上面的redis容器从原来的master变成了slave,主从之间发生了切换,最后切换成功。
|
1 、主机192.168.56.109 [root@dcos-redis01 redis]# docker exec -it redis-slave01 redis-cli -h 192.168.56.109 -a JayRedisHaZi info replication # Replication role:master connected_slaves:2 slave0:ip=192.168.56.110,port=6379,state=online,offset=1601,lag=1 slave1:ip=192.168.56.108,port=6379,state=online,offset=1601,lag=1 master_repl_offset:1601 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:2 repl_backlog_histlen:1600
2 、主机192.168.56.108 [root@docker-build-env etc]# docker exec -it redis-master redis-cli -h 192.168.56.108 -a JayRedisHaZi info replication # Replication role:slave master_host:192.168.56.109 master_port:6379 master_link_status:up master_last_io_seconds_ago:0 master_sync_in_progress:0 slave_repl_offset:1713 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
3 、主机192.168.56.110 [root@dcos-redis02 redis]# docker exec -it redis-slave02 redis-cli -h 192.168.56.110 -a JayRedisHaZi info replication # Replication role:slave master_host:192.168.56.109 master_port:6379 master_link_status:up master_last_io_seconds_ago:6 master_sync_in_progress:0 slave_repl_offset:1755 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 |
1、检查到192.168.56.108和192.168.56.110这两台slave节点是只读模式

2、master节点192.168.56.109写数据,正常同步到两台slave节点。



有需要的朋友可以关注我的公众号,文章每日一更
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/28833846/viewspace-2699919/ ,如需转载,请注明出处,否则将追究法律责任。