redis-主从复制+哨兵守卫

前言

Redis是一个内存数据库,支持多样类型的数据存储和查询,而且采用了高效的算法把数据压缩到最小。一般测试环境,搭建一个Redis实例就可以满足需求,但是生产环境中,单个Redis实例一旦挂掉之后,就不能提供内存存储服务,所以需要部署多个实例来提高容错性,挂掉一个或多个也能正常提供服务,实现724无间断服务。那么多个Redis实例该怎样部署配合才能满足需求呢?

主从复制

既然有多个实例,就应该有主有次,不然还不乱套了,所以应该选择一个实例作为主服务器,其他作为从服务器和主服务器同步,这样数据就有多个副本了。

部署一个主服务器

主服务器的配置中,需要注意的有下面几个:

//为了能让其他容器访问,配置为接收所有网络接口的连接
bind 0.0.0.0
//明确自身身份
replica-announce-ip masterA

编写redis-master.yml文件

version: "3.7"
networks:
  xxl:
    external: true
services:
  masterA:
    image: redis:latest
    networks:
      - xxl
    volumes:
      - ./redis/masterA.conf:/etc/redis/redis.conf:ro
      - ./redis/masterA:/data:rw
    command: ["redis-server", "/etc/redis/redis.conf"]
    deploy:
      replicas: 1

使用swarm部署:

//部署服务栈
docker stack deploy -c docker-master.yml m
//移除服务栈
docker stack rm m

至此,一个主服务器就部署好了。如果swarm集群中部署了portainer的话,可以在portainer中看到实例。
在这里插入图片描述
进入到容器中,添加一个键值对:
redis-主从复制+哨兵守卫_第1张图片

部署三个从服务器

首先也是修改配置文件,有三个文件需要修改,需要注意的有:

//其他容器也可以访问
bind 0.0.0.0
//明确身份
replica-announce-ip replicaA1		//A1实例
replica-announce-ip replicaA2		//A2实例
replica-announce-ip replicaA3		//A3实例
//指定是谁的从服务器
replicaof masterA 6379

接着,编写从服务器的部署文件redis-replica.yml

version: "3.7"
networks:
  xxl:
    external: true
volumes:		//由于windows系统复制数据会有问题,所以使用命名卷。
  replicaA1:
    external: true
  replicaA2:
    external: true
  replicaA3:
    external: true
services:
  replicaA1:
    image: redis:latest
    networks:
      - xxl
    volumes:
      - ./redis/replicaA1.conf:/etc/redis/redis.conf:ro
      - replicaA1:/data:rw
    command: ["redis-server", "/etc/redis/redis.conf"]
    deploy:
      replicas: 1
  replicaA2:
    image: redis:latest
    networks:
      - xxl
    volumes:
      - ./redis/replicaA2.conf:/etc/redis/redis.conf:ro
      - replicaA2:/data:rw
    command: ["redis-server", "/etc/redis/redis.conf"]
    deploy:
      replicas: 1
  replicaA3:
    image: redis:latest
    networks:
      - xxl
    volumes:
      - ./redis/replicaA3.conf:/etc/redis/redis.conf:ro
      - replicaA3:/data:rw
    command: ["redis-server", "/etc/redis/redis.conf"]
    deploy:
      replicas: 1

同样,也用docker部署到swarm中:

//部署服务栈
docker stack deploy -c docker-replica.yml r
//移除服务栈
docker stack rm r

查看portainer,发现多了三个从服务器:
在这里插入图片描述
查看任一从服务器容器的log,可以看到从服务器已经连上主服务器并且进行了数据同步。
进入容器中,访问键“/”,得到期望的“better”。
redis-主从复制+哨兵守卫_第2张图片

两者关系

主服务器提供一般提供写入服务,而从服务器提供只读服务。

默认情况下,从服务器和主服务器断开连接后,从服务器会自动重连主服务器,并且进行数据同步。由于同步数据的过程是异步的,数据量较大时,会有短暂的时间窗口出现不同步的情况;但是无论怎么样,从服务器都尽最大的努力,保证和主服务器的数据一致。

如果说,从服务器挂了一个,对系统影响不大,还有其他的从服务器提供只读服务。但是如果主服务器挂了一个呢,整个系统将无法接收新的写入命令。如果此时不手动重启主服务器的话,系统将无法提供正常的服务。但是,作为开发人员,不可能724守着服务器,那么有没有一种方法当主服务器挂掉之后,主服务器能够自动重启呢?

答案是肯定的。docker swarm部署的服务,在挂掉的情况下,会自动重启。

那么如果不是使用docker swarm部署的服务呢?主服务器挂了之后,如果有一个从服务器变为主服务器,提供写入操作就好了。事实上,确实有这样的方案。Redis哨兵就是干这个事的。

哨兵守卫

启动哨兵一般有两种方式:

  • redis-sentinel
  • redis-server /path/to/sentinel.conf --sentinel

本文采用第二种方式部署。

首先修改配置文件,完整的选项列表参考sentinel.conf,最少需要下面四个选项:

sentinel monitor masterA masterA 6379 2	//名为 masterA 的主服务器, 这个主服务器的 IP 地址为 masterA , 端口号为 6379 , 而将这个主服务器判断为失效至少需要 2 个 Sentinel 同意
sentinel down-after-milliseconds masterA 60000	//Sentinel 认为服务器已经断线所需的毫秒数
sentinel failover-timeout masterA 30000		//故障转移超时时间
sentinel parallel-syncs masterA 1	//每次同时同步的从服务器个数

准备三个这样的文件:

  • sentinelA1.conf
  • sentinelA2.conf
  • sentinelA3.conf

接着,编写sentinelA.yml部署文件:

version: "3.7"
networks:
  xxl:
    external: true
volumes:		//由于windows系统复制数据会有问题,所以使用命名卷。
  sentinelA1:
    external: true
  sentinelA2:
    external: true
  sentinelA3:
    external: true
services:
  sentinelA1:
    image: redis:latest
    networks:
      - xxl
    volumes:
      - ./redis/sentinelA1.conf:/etc/redis/redis.conf:rw
      - sentinelA1:/tmp:rw
    command: ["redis-server", "/etc/redis/redis.conf", "--sentinel"]
    deploy:
      replicas: 1
  sentinelA2:
    image: redis:latest
    networks:
      - xxl
    volumes:
      - ./redis/sentinelA2.conf:/etc/redis/redis.conf:rw
      - sentinelA2:/tmp:rw
    command: ["redis-server", "/etc/redis/redis.conf", "--sentinel"]
    deploy:
      replicas: 1
  sentinelA3:
    image: redis:latest
    networks:
      - xxl
    volumes:
      - ./redis/sentinelA3.conf:/etc/redis/redis.conf:rw
      - sentinelA3:/tmp:rw
    command: ["redis-server", "/etc/redis/redis.conf", "--sentinel"]
    deploy:
      replicas: 1

使用swarm部署哨兵:

//部署服务栈
docker stack deploy -c docker-sentinel.yml s
//移除服务栈
docker stack rm s

查看portainer,多了三个哨兵服务:
在这里插入图片描述
查看任一个哨兵的日志如下:
redis-主从复制+哨兵守卫_第3张图片
可以看出,每个哨兵都有独立的ID,并且知道了主服务器的信息,三个从服务器的信息和另外两个哨兵的信息。

到这里,一个主服务器+三个从服务器+三个哨兵的Redis服务器系统就建好了。

为了验证主服务器挂掉之后,在哨兵的管理下能否成功进行故障转移,现在把主服务器的服务移除:

docker stack rm m

观察任一哨兵服务的日志,可以发现:哨兵观察到了主服务器的下线,选举了一个从服务器转变为新的主服务器,并把其他的从服务器连接到新的主服务器上。
redis-主从复制+哨兵守卫_第4张图片
最后,使用role查看每个从服务器的身份,一个master,两个slave。查看键“/”的值,依然是“better”。说明哨兵起到了在主服务器挂掉之后,自动故障迁移到其中一台从服务器上的作用。

你可能感兴趣的:(服务器,redis)