Docker Compose——搭建Redis集群
环境配置
Docker 18.x
Docker-Compose 3.7
Redis 6.2.5
主从(Master-Slave)模式
主从复制模式中包含一个主数据库实例(master)与一个或多个从数据库实例(slave),如下图
客户端可对主数据库进行读写操作,对从数据库进行读操作,主数据库写入的数据会实时自动同步给从数据库。
主从模式的具体工作机制
- slave启动后,向master发送SYNC命令,master接收到SYNC命令后通过bgsave保存快照(即上文所介绍的RDB持久化),并使用缓冲区记录保存快照这段时间内执行的写命令
- master将保存的快照文件发送给slave,并继续记录执行的写命令
- slave接收到快照文件后,加载快照文件,载入数据
- master快照发送完后开始向slave发送缓冲区的写命令,slave接收命令并执行,完成复制初始化
- 此后master每次执行一个写命令都会同步发送给slave,保持master与slave之间数据的一致性
主从模式的特点
- 主服务器负责接收写请求
- 从服务器负责接收读请求
- 从服务器的数据由主服务器复制过去。主从服务器的数据是一致的
主从模式的优点
- 读写分离(主服务器负责写,从服务器负责读)
- 高可用(某一台从服务器挂了,其他从服务器还能继续接收请求,不影响服务)
- 处理更多的并发量(每台从服务器都可以接收读请求,读QPS就上去了)
主从模式的缺点
- 不具备自动容错与恢复功能,master或slave的宕机都可能导致客户端请求失败,需要等待机器重启或手动切换客户端IP才能恢复
- master宕机,如果宕机前数据没有同步完,则切换IP后会存在数据不一致的问题
- 难以支持在线扩容,Redis的容量受限于单机配置
主从同步
主从架构的特点之一:主服务器和从服务器的数据是一致的。
主从同步的2种情况
完整的同步
从服务器向主服务器发送PSYNC命令
收到PSYNC命令的主服务器执行BGSAVE命令,在后台生成一个RDB文件。并用一个缓冲区来记录从现在开始执行的所有写命令。
当主服务器的BGSAVE命令执行完后,将生成的RDB文件发送给从服务器,从服务器接收和载入RBD文件。将自己的数据库状态更新至与主服务器执行BGSAVE命令时的状态。
主服务器将所有缓冲区的写命令发送给从服务器,从服务器执行这些写命令,达到数据最终一致性。
部分重同步
主从服务器的复制偏移量 主服务器每次传播N个字节,就将自己的复制偏移量加上N
从服务器每次收到主服务器的N个字节,就将自己的复制偏移量加上N
通过对比主从复制的偏移量,就很容易知道主从服务器的数据是否处于一致性的状态!
Docker-Compose
https://gitee.com/shentuzhigang/mini-project/tree/master/docker-compose/redis-master-slave
version: "3.7"
services: redis1:image: redis:latestcontainer_name: redis1command: /bin/bash -c "redis-server /usr/local/etc/redis/redis.conf"environment:REDIS_PASSWORD: 123456ports:- 6376:6379volumes:- type: bindsource: /root/redis-cluster/redistarget: /usr/local/etc/redisnetworks:redis-cluster-net:ipv4_address: 192.168.88.81redis2:image: redis:latestcontainer_name: redis2command: /bin/bash -c "redis-server /usr/local/etc/redis/redis.conf --replicaof 192.168.88.81 6379"depends_on:- redis1environment:REDIS_PASSWORD: 123456ports:- 6377:6379volumes:- type: bindsource: /root/redis-cluster/redistarget: /usr/local/etc/redisnetworks:redis-cluster-net:ipv4_address: 192.168.88.82redis3:image: redis:latestcontainer_name: redis3command: /bin/bash -c "redis-server /usr/local/etc/redis/redis.conf --replicaof 192.168.88.81 6379"depends_on:- redis1environment:REDIS_PASSWORD: 123456ports:- 6378:6379volumes:- type: bindsource: /root/redis-cluster/redistarget: /usr/local/etc/redisnetworks:redis-cluster-net:ipv4_address: 192.168.88.83
networks:redis-cluster-net:external: truename: redis-cluster-net
哨兵 Sentinel 模式
Redis 的 Sentinel 系统用于管理多个 Redis 服务器(instance), 该系统执行以下三个任务:
- 监控(Monitoring): Sentinel 会不断地检查你的主服务器和从服务器是否运作正常。
- 提醒(Notification): 当被监控的某个 Redis 服务器出现问题时, Sentinel 可以通过 API 向管理员或者其他应用程序发送通知。
- 自动故障迁移(Automatic failover): 当一个主服务器不能正常工作时, Sentinel 会开始一次自动故障迁移操作, 它会将失效主服务器的其中一个从服务器升级为新的主服务器, 并让失效主服务器的其他从服务器改为复制新的主服务器; 当客户端试图连接失效的主服务器时, 集群也会向客户端返回新主服务器的地址, 使得集群可以使用新主服务器代替失效服务器。
Redis Sentinel 是一个分布式系统, 你可以在一个架构中运行多个 Sentinel 进程(progress), 这些进程使用流言协议(gossip protocols)来接收关于主服务器是否下线的信息, 并使用投票协议(agreement protocols)来决定是否执行自动故障迁移, 以及选择哪个从服务器作为新的主服务器。
哨兵模式基于主从复制模式,只是引入了哨兵来监控与自动处理故障。如图
Docker-Compose
哨兵容器应该等待redis容器先启动,使用depends_on控制
version: "3.7"
services: redis1:image: redis:latestcontainer_name: redis1command: /bin/bash -c "redis-server /usr/local/etc/redis/redis.conf"environment:REDIS_PASSWORD: 123456ports:- 6376:6379volumes:- type: bindsource: /root/redis-cluster/redistarget: /usr/local/etc/redisnetworks:redis-cluster-net:ipv4_address: 192.168.88.81redis2:image: redis:latestcontainer_name: redis2command: /bin/bash -c "redis-server /usr/local/etc/redis/redis.conf --replicaof 192.168.88.81 6379"depends_on:- redis1environment:REDIS_PASSWORD: 123456ports:- 6377:6379volumes:- type: bindsource: /root/redis-cluster/redistarget: /usr/local/etc/redisnetworks:redis-cluster-net:ipv4_address: 192.168.88.82redis3:image: redis:latestcontainer_name: redis3command: /bin/bash -c "redis-server /usr/local/etc/redis/redis.conf --replicaof 192.168.88.81 6379"depends_on:- redis1environment:REDIS_PASSWORD: 123456ports:- 6378:6379volumes:- type: bindsource: /root/redis-cluster/redistarget: /usr/local/etc/redisnetworks:redis-cluster-net:ipv4_address: 192.168.88.83redis-sentinel1:image: redis:latestcontainer_name: redis-sentinel1command: /bin/bash -c "redis-sentinel /usr/local/etc/redis/redis-sentinel.conf"depends_on:- redis1- redis2- redis3environment:REDIS_PASSWORD: 123456ports:- 6373:6379volumes:- type: bindsource: /root/redis-cluster/redistarget: /usr/local/etc/redisnetworks:redis-cluster-net:ipv4_address: 192.168.88.84redis-sentinel2:image: redis:latestcontainer_name: redis-sentinel2command: /bin/bash -c "redis-sentinel /usr/local/etc/redis/redis-sentinel.conf"depends_on:- redis1- redis2- redis3environment:REDIS_PASSWORD: 123456ports:- 6374:6379volumes:- type: bindsource: /root/redis-cluster/redistarget: /usr/local/etc/redisnetworks:redis-cluster-net:ipv4_address: 192.168.88.85redis-sentinel3:image: redis:latestcontainer_name: redis-sentinel3command: /bin/bash -c "redis-sentinel /usr/local/etc/redis/redis-sentinel.conf"depends_on:- redis1- redis2- redis3environment:REDIS_PASSWORD: 123456ports:- 6375:6379volumes:- type: bindsource: /root/redis-cluster/redistarget: /usr/local/etc/redisnetworks:redis-cluster-net:ipv4_address: 192.168.88.86
networks:redis-cluster-net:external: truename: redis-cluster-net
redis-sentinel.conf
sentinel monitor mymaster 192.168.88.81 6379 2
设置哨兵监控的主服务器和odown数(sdown数累计达到odown即开启故障转移主从切换) sentinel monitor
mymaster 192.168.11.128 6379 2
x秒不回应即单sentinel判定为sdown sentinel down-after-milliseconds
单次故障转移最长时间,超过则认定为故障转移失败 sentinel failover-timeout mymaster 10000
当发生failover主备切换时最多可以有多少个slave同时对新的master同步,数字越小favilover越快.通常设为1
sentinel parallel-syncs <master-name> <numslaves>
哨兵启动后自动写入的唯一id,每个sentinel不一样,故不能用同一份配置文件 sentinel myid
Redis Cluster 集群模式
Redis 集群是一个可以在多个 Redis 节点之间进行数据共享的设施(installation)。
Redis 集群不支持那些需要同时处理多个键的 Redis 命令, 因为执行这些命令需要在多个 Redis 节点之间移动数据, 并且在高负载的情况下, 这些命令将降低 Redis 集群的性能, 并导致不可预测的行为。
Redis 集群通过分区(partition)来提供一定程度的可用性(availability): 即使集群中有一部分节点失效或者无法进行通讯, 集群也可以继续处理命令请求。
Redis 集群提供了以下两个好处:
- 将数据自动切分(split)到多个节点的能力。
- 当集群中的一部分节点失效或者无法进行通讯时, 仍然可以继续处理命令请求的能力。
Docker-Compose
version: "3.7"
services: redis1:image: redis:latestcontainer_name: redis1command: /bin/bash -c "redis-server /usr/local/etc/redis/redis.conf"environment:REDIS_PASSWORD: 123456ports:- 6376:6379volumes:- type: bindsource: /root/redis-cluster/redistarget: /usr/local/etc/redisnetworks:redis-cluster-net:ipv4_address: 192.168.88.81redis2:image: redis:latestcontainer_name: redis2command: /bin/bash -c "redis-server /usr/local/etc/redis/redis.conf"environment:REDIS_PASSWORD: 123456ports:- 6377:6379volumes:- type: bindsource: /root/redis-cluster/redistarget: /usr/local/etc/redisnetworks:redis-cluster-net:ipv4_address: 192.168.88.82redis3:image: redis:latestcontainer_name: redis3command: /bin/bash -c "redis-server /usr/local/etc/redis/redis.conf"environment:REDIS_PASSWORD: 123456ports:- 6378:6379volumes:- type: bindsource: /root/redis-cluster/redistarget: /usr/local/etc/redisnetworks:redis-cluster-net:ipv4_address: 192.168.88.83redis4:image: redis:latestcontainer_name: redis4command: /bin/bash -c "redis-server /usr/local/etc/redis/redis.conf"environment:REDIS_PASSWORD: 123456ports:- 6373:6379volumes:- type: bindsource: /root/redis-cluster/redistarget: /usr/local/etc/redisnetworks:redis-cluster-net:ipv4_address: 192.168.88.84redis5:image: redis:latestcontainer_name: redis5command: /bin/bash -c "redis-server /usr/local/etc/redis/redis.conf"environment:REDIS_PASSWORD: 123456ports:- 6374:6379volumes:- type: bindsource: /root/redis-cluster/redistarget: /usr/local/etc/redisnetworks:redis-cluster-net:ipv4_address: 192.168.88.85redis6:image: redis:latestcontainer_name: redis6command: /bin/bash -c "redis-server /usr/local/etc/redis/redis.conf"environment:REDIS_PASSWORD: 123456ports:- 6375:6379volumes:- type: bindsource: /root/redis-cluster/redistarget: /usr/local/etc/redisnetworks:redis-cluster-net:ipv4_address: 192.168.88.86
networks:redis-cluster-net:external: truename: redis-cluster-net
启动后执行命令
docker exec -it redis1 \
redis-cli --cluster create \
192.168.88.81:6379 \
192.168.88.82:6379 \
192.168.88.83:6379 \
192.168.88.84:6379 \
192.168.88.85:6379 \
192.168.88.86:6379 \
--cluster-replicas 1
Keepalived监控
通过 keepalived 的虚拟 IP,提供主从的统一访问,在主出现问题时, 通过 keepalived 运行脚本将从提升为主,待主恢复后先同步后自动变为主,该方案的好处是主从切换后,应用程序不需要知道(因为访问的虚拟 IP 不变),坏处是引入 keepalived 增加部署复杂性,在有些情况下会导致数据丢失。
Zookeeper监控
通过 zookeeper 来监控主从实例, 维护最新有效的 IP, 应用通过 zookeeper 取得 IP,对 Redis 进行访问,该方案需要编写大量的监控代码
常见问题
- [ERR] Node 192.168.162.132:7001 is not configured as a cluster node.
- Docker can’t connect to redis from another service
- Could not connect to Redis at 127.0.0.1:6379: Connection refused with homebrew
- Node 172.168.63.202:7001 is not empty. Either the nodealready knows other nodes (check with CLUSTER NODES) or contains some
参考文章
- redis集群搭建(非常详细,适合新手)
- Redis - Official Image | Docker Hub
- Docker下redis的主从、持久化配置
- docker-compose编排redis集群
- Sentinel — Redis 命令参考
- 六、Redis 主从复制 Replicaof、哨兵 Sentinel
- 一文掌握Redis主从复制、哨兵、Cluster三种集群模式
- redis replicaof命令的使用
- 2021-Java后端工程师面试指南-(Redis)
Docker Compose——搭建Redis集群相关推荐
- Docker Compose搭建TDengine集群
文章目录 1. Linux上安装Docker 2. 安装Docker Compose 3. 自定义Docker 网络 4. 搭建集群 4.1 基础配置 4.2 查看启动效果 4.3 测试节点 4.3. ...
- docker compose搭建NACOS集群
使用docker搭建NACOS集群 SpringCloud Alibaba,必然会使用Nacos进行服务注册与配置管理.然而,在实际的生产环境中,使用单服务器搭建nacos服务器是十分危险的,如若发生 ...
- docker compose安装redis集群、集群扩容、集群收缩
目录 一.redis 配置信息模板 二.编写批量生成配置文件脚本 三.批量生成配置文件 四.编写 docker-compose 文件 五.做集群.分配插槽 六.测试: 七.手动扩容 八.添加主从节点 ...
- docker搭建redis集群
#!/bin/bash #Author: 臆想的一只猫 #Created: 2022-04-06 17:42:33 #Description: 搭建redis集群function menu() {cl ...
- 使用docker搭建redis集群
使用docker搭建redis集群有两种,一种是单机多个docker容器,一种是多个机器的集群 基础知识 每个Redis集群中的节点都需要打开两个TCP连接.一个连接用于正常的给Client提供服务, ...
- 理解并从头搭建redis集群
部分开发人员工作当中只是在应用中使用redis,比如用来做数据结果的缓存.而且现在有很多不错的redis客户端工具(redisson),基本上可以不用关注redis命令就可以完成相当部分的功能.所以可 ...
- docker环境搭建redis-cluster集群(多台机器)
docker环境搭建redis-cluster集群(多机) Docker多台主机安装Redis集群 Docker安装Redis Cluster 三主三从
- 手把手搭建redis集群-三台虚拟机(三主三从)
Redis集群环境搭建: Redis 集群简介: Redis 是一个开源的 key-value 分布式存储系统,由于其出众的性能,大部分互联网企业将其用来作为服务端分布式缓存使用.Redis 在 3. ...
- [转]redis 5.0.5 5分钟搭建redis集群
环境:centos 7 1:下载并安装redis $ wget http://download.redis.io/releases/redis-5.0.5.tar.gz$ tar xzf ...
最新文章
- optparse模块
- 电费竟然占了数据中心运维总成本的7成?
- 减少Java垃圾收集开销的5条提示
- 什么叫做展望_开学季:有一种爱, 叫做爸妈给你塞的行李箱!(附大学新生行李箱应怎么选?)...
- LastPass 的开源替代品
- Eclipse 工具的安装和配置
- oracle文件名乱码,如何rename datafile name中存在乱码的数据文件
- docker打包informix镜像
- 手机麦克风结构原理图_驻极体电容式麦克风结构和工作原理
- ZZULIOJ部分题目解答
- matlab给元素排序,matlab排序及元素统计
- 使用echarts生成海友网企业全国分布地图
- 集成支付宝,跳转到支付宝后显示的不是支付页面
- 三种近距离通信技术(WIFI、蓝牙、NFC)简述
- 数据结构与算法基础(王卓)(22):哈夫曼树
- python怎么编辑excel_python 修改excel表格数据-关于如何用python 编辑 excel表格
- 【微信开发】---- 公众号支付
- usb摄像头设备名重复的问题
- 视频教程-征服Node.js 7.x视频课程(5):使用Buffer处理二进制数据-Node.js
- 百度阿拉丁计划 - 看上去很美
热门文章
- CG笔记之一——透视投影
- android 首选项框架,Android:创建自定义首选项
- android恶意扣费类程序,10款APP违法有害 主要危害涉及恶意扣费等5类
- php事务处理深入学校,php事务处理实例详解
- android builder模式 插件,如何在Kotlin中实现Builder模式?
- android listview 列加id,Android实战开发之ListView同一个item显示2列的实现方法
- inrange函数_Python 初学者必备的常用内置函数
- java求100以内的a2 b2=c2,Java语言程序设计Ⅱ-中国大学mooc-试题题目及答案
- 最大流最小割经典例题_C/C++知识点之最大流最小割C++实现
- tornado函数和类的导入和ui_modules , ui_methods