单机版的Redis相信大家都比较熟悉了,这里介绍几种Redis的集群模式,并结合Docker来进行实践操作

abstract.png

准备工作

通过Docker下载最新的Redis镜像

# 获取redis镜像docker pull redis

下载后续所需的相关配置文件

# 下载Redis配置文件wget http://download.redis.io/redis-stable/redis.conf# 下载Redis哨兵配置文件wget http://download.redis.io/redis-stable/sentinel.conf

主从模式

众所周知,将数据放在一台服务器上风险巨大。为此Redis提供了Replication复制功能,可以将一台Redis服务器中的数据自动同步到其他多台Redis服务器中。在该模式下,存在两个角色:Master主数据库(主库)、Slave从数据库(从库)。主数据库可以进行读写操作,每次当主数据库发生变动即会自动同步至相应的从数据库中。故从数据库一般是只读的,不允许用户直接向其中写入数据。具体地,一个主数据库可以拥有多个从数据库,而一个从数据库只能拥有一个主数据库,即一对多的关系。可以看到在主从模式下,一方面降低了数据丢失的风险,另一方面通过读写分离(主库写、从库读),提高了服务器的负载能力。下面我们搭个一主一从的Redis集群进行演示

配置主库

按下图建立主库所需的相关目录,并将Redis配置文件复制到 /Users/zgh/Docker/Redis/Redis-Master/Config 路径下。如下图所示

figure 1.jpeg

修改主库的Redis配置文件,修改如下

...# 注释bind配置项# bind 127.0.0.1

# 设为no, 关闭保护模式protected-mode no

# 主库端口设为6379port 6379

# 修改数据库数量, 用于验证配置文件是否生效databases 10

# 设置工作目录dir "/data"

# 设置Redis密码requirepass 123456

# 设为no, 因为docker启动时会通过-d参数来让其实现后台运行daemonize no...

至此,就可以通过Docker来启动一个使用指定配置文件的Redis容器来作为主库了。命令如下所示

docker run \ -v /Users/zgh/Docker/Redis/Redis-Master/Config/redis.conf:/etc/redis/redis.conf \ -v /Users/zgh/Docker/Redis/Redis-Master/Data:/data \ -d -p 6379:6379 \ --name Redis-Master \ redis redis-server /etc/redis/redis.conf

命令选项说明如下

  • -v : 将宿主机的相关目录、文件挂载到容器中。具体地,冒号:前为宿主机目录,冒号:后为容器目录
  • -d : 指定容器后台运行
  • -p : 端口映射。将宿主机的端口映射到容器的端口。具体地,冒号:前为宿主机端口,冒号:后为容器端口
  • --name : 命名容器

从库配置

至此主库Redis—Master已经配置、启动完毕,现在让我们来配置一个从库。为了保证Redis从库能够自动同步主库中的数据,需要在从库的配置文件配置主库的IP、端口信息。这里,我们即可直接使用Docker分配Redis—Master容器的IP进行容器间通信,也可以通过宿主机IP(可通过ifconfig命令获取)来进行通信。这里我们选择前者,直接获取Docker分配给Redis—Master容器的IP

# 查看 Redis-Master 容器的详细信息docker inspect Redis-Master

下图命令结果的IPAddress即为Redis-Master容器的IP——172.17.0.2

figure 2.jpeg

好了,知道了主库的IP信息。现在我们可以来配置从库了。按下图建立从库所需的相关目录,并将Redis配置文件复制到 /Users/zgh/Docker/Redis/Redis-Slave1/Config 路径下。如下图所示

figure 3.jpeg

修改从库的Redis配置文件,修改如下。值得一提的是,当主库设置密码时,必须在从库的配置文件通过masterauth配置项设置主库密码。否则,从库将无法正确连接、访问主库以进行数据同步

...# 注释bind配置项# bind 127.0.0.1

# 设为 no, 关闭保护模式protected-mode no

# 从库端口设为6388port 6388

# 修改数据库数量, 用于验证配置文件是否生效databases 12

# 设置工作目录dir "/data"

# 设置Redis密码requirepass 123456

# 设为no, 因为docker启动时会通过-d参数来让其实现后台运行daemonize no

# 设置主库的IP地址、端口replicaof 172.17.0.2 6379

# 设置主库的密码masterauth "123456"...

至此,就可以通过Docker来启动一个使用指定配置文件的Redis容器来作为从库了。命令如下所示

docker run \ -v /Users/zgh/Docker/Redis/Redis-Slave1/Config/redis.conf:/etc/redis/redis.conf \ -v /Users/zgh/Docker/Redis/Redis-Slave1/Data:/data \ -d -p 6388:6388 \ --name Redis-Slave1 \ redis redis-server /etc/redis/redis.conf 

实践

至此,我们演示所需的两个Redis服务就分别创建、启动了,且为一主一从。现在让我们进入各Redis容器内,通过redis-cli连接后,通过info replication查看主从同步状态。结果如下图所示,可以看到在Redis-Master主库中显示有一个从库已经连接上了,而在Redis-Salve1从库中则显示其同步的主库也成功上线了

figure 4.jpeg

现在,让我们实际验证下,看看在主库Redis-Master下写入的数据,是否可以通过从库获取到。测试过程、结果如下所示,符合预期

figure 5.jpeg

运行时配置主从

通过slaveof命令实现运行时配置同步所需的主库信息。具体地,如果该库之前是一个主库,则此时会变为从库;如果该库之前是一个其他主库的从库,则此时会停止与原来主库的同步,转而和新的主库同步

slaveof  

特别地,还可通过下述命令将一个从库变为主库

# 将该库变为主库slaveof no one

figure 6.jpeg

哨兵模式

利用Redis的Replication来构建一主多从的Redis集群虽然方便,但是有一个明显的弊端。一旦主数据库宕机停止服务了,需要我们手动地从若干个从数据库中重新选择一个作为新的主库,并让剩余的从库指向新主库进行同步。以保障整个系统可以继续对外提供服务。显然这个过程需要人工干预,非常麻烦。为此,Redis提供了一个哨兵Sentinel的功能。其可对整个主、从库进行监控,并且在主库异常时自动地选择一个从库作为主库,以继续提供服务

配置从库Redis-Slave2

在上节,我们配置了两个Reids数据库——Redis-Master、Redis-Salve1,分别使用了6379、6388端口。为了后续演示方便,我们再配置一个从库——Redis-Salve2

按下图建立从库所需的相关目录,并将Redis配置文件复制到 /Users/zgh/Docker/Redis/Redis-Slave2/Config 路径下。如下图所示

figure 7.jpeg

类似地,我们修改从库的Redis配置文件。这里,对于Redis-Slave2从库,我们使用6399端口

...# 注释bind配置项# bind 127.0.0.1

# 设为 no, 关闭保护模式protected-mode no

# 从库端口设为6399port 6399

# 修改数据库数量, 用于验证配置文件是否生效databases 13

# 设置工作目录dir "/data"

# 设置Redis密码requirepass 123456

# 设为no, 因为docker启动时会通过-d参数来让其实现后台运行daemonize no

# 设置主库的IP地址、端口replicaof 172.17.0.2 6379

# 设置主库的密码masterauth "123456"...

然后可以通过Docker来启动一个使用指定配置文件的Redis容器来作为从库了。命令如下所示

docker run \ -v /Users/zgh/Docker/Redis/Redis-Slave2/Config/redis.conf:/etc/redis/redis.conf \ -v /Users/zgh/Docker/Redis/Redis-Slave2/Data:/data \ -d -p 6399:6399 \ --name Redis-Slave2 \ redis redis-server /etc/redis/redis.conf 

至此,主库Redis-Master(端口号:6379)下有两个从库:Redis-Slave1(端口号:6388)、Redis-Slave2(端口号:6399)。如下图所示

figure 8.jpeg

配置哨兵Sentinel

在配置哨兵前,我们先修改下Redis-Master的配置文件,修改完成后重启该容器即可生效新配置

...# 设置主库的密码masterauth "123456"...

按下图建立哨兵所需的相关目录,并将Sentinel的配置文件复制到 /Users/zgh/Docker/Redis/Redis-Sentinel1/Config 路径下。如下图所示

figure 9.jpeg

修改哨兵的配置文件,修改如下。值得一提的是,当主库设置密码时,必须在哨兵的配置文件通过sentinel auth-pass配置项设置主库密码。否则,哨兵将无法正确连接、访问主库以进行监控

...# 设为no, 因为docker启动时会通过-d参数来让其实现后台运行daemonize no

# 哨兵端口port 26379

# 设置日志文件路径logfile "/data/Log/sentinel.log"

# 设置哨兵所需监控的主库IP、端口, 并命名为myMaster# 最低通过票数设为1sentinel monitor myMaster 172.17.0.2 6379 1

# 设置哨兵访问myMaster所指示主库的密码sentinel auth-pass myMaster 123456...

然后可以通过Docker来启动一个使用指定配置文件的哨兵了。命令如下所示

docker run \ -v /Users/zgh/Docker/Redis/Redis-Sentinel1:/data \ -d -p 26379:26379 \ --name Redis-Sentinel1 \ redis redis-sentinel /data/Conifg/sentinel.conf

实践

现在,我们已经启动了一个Redis哨兵,用于监控我们的主库Redis-Master、从库Redis-Salve1、从库Redis-Salve2。现在,我们来看哨兵的日志输出

figure 10.jpeg

从上图可以看到,哨兵会自动发现主库下的所有从库。所以在哨兵的配置文件只需显式地配置需要被监控的各主库的信息即可。现在,我们人为停止主库Redis—Master容器,来看看会发生什么。通过哨兵的日志我们可以看出,哨兵发现使用6379端口的Redis-Master主库发生了异常,然后选择运行在6399端口的Redis-Slave2从库作为新的主库

figure 11.jpeg

同时对于使用6388端口的Redis-Slave1而言,其之前是以Redis-Master作为主库进行数据同步的,现在同样是以Redis-Slave2作为主库进行数据同步的,结果如下所示

figure 12.jpeg

可以看到,通过哨兵可以在主库发生异常时自动选择其中一个从库作为新的主库来继续提供服务,并让其他剩余的从库指向新主库进行数据同步。当然如果6379端口的Redis-Master恢复了,其同样也会作为新主库的从库来对外进行提供服务的。这一点可以从哨兵的日志看出。这也是为什么在前文我们需要在Redis-Master的配置文件中设置masterauth项,否则Redis-Master将无法访问、同步主库Redis-Salve2的数据。现在我们再次启动Redis-Master容器来验证下,哨兵的日志输出如下

figure 13.jpeg

现在,我们分别进入6379端口的Redis-Master容器、6399端口的Redis-Salve2容器验证下,结果如下

figure 14.jpeg

集群模式

主从+哨兵,看上去好像已经很完美了。但对于任意一个Redis服务而言,不论是主库还是从库,存储都是所有的数据。这样数据的总存储容量将会受到单台服务器内存容量的限制。换言之,我们需要对Redis进行水平扩容,为此集群模式应运而生。在Redis集群中共计有16384个Slot槽,集群下的每个节点负责若干个Slot槽。确定Key属于Redis哪个节点的具体过程:对键名Key使用CRC16算法计算出散列值,然后对16384取余。这样即可确定Key所在的Slot槽,进而确定到哪个Redis节点下进行处理。可以看到,在集群模式下,任何一个Redis节点都将不再存储全部的数据,而只是存储一部分。此举显然提高了容量上限。当然为了保证高可用,集群模式下还可以为Redis节点设置若干个从库。这样一旦主节点异常停机了,即选择其下的一个从节点自动切换为主库

配置节点

这里我们配置6个Redis节点,分别使用7001~7006端口。节点Redis-Cluster1的配置如下所示,其他节点配置同理

...# 注释bind配置项# bind 127.0.0.1

# 设为 no, 关闭保护模式protected-mode no

# 端口设为7001port 7001

# 修改数据库数量, 用于验证配置文件是否生效databases 5

# 设置工作目录dir "/data"

# 设置Redis密码requirepass 123456

# 设为no, 因为docker启动时会通过-d参数来让其实现后台运行daemonize no

# 使能集群模式cluster-enabled yes

# 设置访问主库时的密码masterauth "123456"...

各节点的目录结构如下所示

figure 15.jpeg

现在通过Docker启动各Redis节点。值得一提的是,对于各Redis节点,我们不仅仅开放、映射供客户端访问的端口,例如节点1的7001端口。还需要开放、映射一个供集群内部通讯的端口,端口号默认为 客户端访问的端口号+10000,故节点1还映射了17001端口。其他节点同理

# 启动节点1docker run \ -v /Users/zgh/Docker/Redis/Redis-Cluster1/Config/redis.conf:/etc/redis/redis.conf \ -v /Users/zgh/Docker/Redis/Redis-Cluster1/Data:/data \ -d -p 7001:7001 -p 17001:17001\ --name Redis-Cluster1 \ redis redis-server /etc/redis/redis.conf 

# 启动节点2docker run \ -v /Users/zgh/Docker/Redis/Redis-Cluster2/Config/redis.conf:/etc/redis/redis.conf \ -v /Users/zgh/Docker/Redis/Redis-Cluster2/Data:/data \ -d -p 7002:7002 -p 17002:17002\ --name Redis-Cluster2 \ redis redis-server /etc/redis/redis.conf

# 启动节点3docker run \ -v /Users/zgh/Docker/Redis/Redis-Cluster3/Config/redis.conf:/etc/redis/redis.conf \ -v /Users/zgh/Docker/Redis/Redis-Cluster3/Data:/data \ -d -p 7003:7003 -p 17003:17003\ --name Redis-Cluster3 \ redis redis-server /etc/redis/redis.conf

# 启动节点4docker run \ -v /Users/zgh/Docker/Redis/Redis-Cluster4/Config/redis.conf:/etc/redis/redis.conf \ -v /Users/zgh/Docker/Redis/Redis-Cluster4/Data:/data \ -d -p 7004:7004 -p 17004:17004\ --name Redis-Cluster4 \ redis redis-server /etc/redis/redis.conf

# 启动节点5docker run \ -v /Users/zgh/Docker/Redis/Redis-Cluster5/Config/redis.conf:/etc/redis/redis.conf \ -v /Users/zgh/Docker/Redis/Redis-Cluster5/Data:/data \ -d -p 7005:7005 -p 17005:17005 \ --name Redis-Cluster5 \ redis redis-server /etc/redis/redis.conf

# 启动节点6docker run \ -v /Users/zgh/Docker/Redis/Redis-Cluster6/Config/redis.conf:/etc/redis/redis.conf \ -v /Users/zgh/Docker/Redis/Redis-Cluster6/Data:/data \ -d -p 7006:7006  -p 17006:17006 \ --name Redis-Cluster6 \ redis redis-server /etc/redis/redis.conf

创建集群

在主从模式一章中,我们是通过Docker分配容器的IP进行容器间通信。这里,我们使用宿主机IP来进行通信。通过ifconfig命令获取宿主机IP为192.168.0.112。然后利用redis-cli来创建含有6个节点的集群,其中 --cluster-replicas 1 表示每个主库拥有的从库数量

docker exec -it Redis-Cluster1 \redis-cli -p 7001 -a 123456 --cluster create \192.168.0.112:7001 192.168.0.112:7002 \192.168.0.112:7003 192.168.0.112:7004 \192.168.0.112:7005 192.168.0.112:7006 \--cluster-replicas 1

执行命令后,会分配这个6个Redis节点各自的角色(主库,从库),及各主库所属的对应Slot范围。然后输入yes确认,即会创建一个含有6个节点(3主3从)的Redis集群

figure 16.jpeg

实践

集群已经搭建完毕,可从任意一个节点来获取集群的节点信息

# 查看集群的节点信息cluster nodes

效果如下所示

figure 17.jpeg

可通过下述命令查看各Slot所对应的节点

# 查看Slot分配情况cluster slots

效果如下所示,其中每个Slot范围的第一个节点信息为主库

figure 18.jpeg

通过redis-cli连接访问时,可通过添加-c参数实现自动重定向到Key所在的Redis节点,效果如下所示

figure 19.png

Note

  • 本文所使用的Redis版本为6.0.8
  • 在Windows系统下使用-v选项挂载目录时,需要注意路径的写法。例如,Windows系统的路径 D:\Docker\Redis 应该写为 /D/Docker/Redis
  • 挂载的宿主机目录前,需要先在Docker中进行如下设置

figure 20.jpeg

参考文献

  1. Redis入门指南·第2版 李子骅著

docker redis 删除集群_基于Docker的Redis集群实践相关推荐

  1. k8s redis集群_基于K8S部署redis哨兵集群

    本 文 主 要 内 容 什么是Kubernetes分布式容器管理平台 PaaS平台redis-sentinel集群架构简介 PaaS平台部署redis哨兵集群 redis-sentinel容器测试及验 ...

  2. docker搭建java测试环境_基于docker构建测试环境

    目录 0x01介绍 0x02 镜像基本操作 0x03 容器基本操作 0x04 容器的修改与保存 0x05 使用Dockerfile定制镜像 0x01介绍 Docker 是一个开源的应用容器引擎,基于 ...

  3. docker $PWD路径_基于Docker搭建Nacos集群

    准备机器3台 192.168.1.160 192.168.1.161 192.168.1.162 docker安装 CentOS 7下安装Docker及基础操作 安装 mysql 基于docker安装 ...

  4. centos7 docker删除端口映射_容器Docker详解

    概述 基本概念Docker是一个开源的应用容器引擎,基于Go语言并遵从Apache2.0协议开源.Docker可以让开发者打包他们的应用以及依赖包到一个轻量级.可移植的容器中,然后发布到任何流行的Li ...

  5. Redis Primer(1)基于JedisPool的Redis hset并发性能测试 - @钟超 · 技术博客专栏 - 博客频道 - CSDN.NET...

    Redis Primer(1)基于JedisPool的Redis hset并发性能测试 - @钟超 · 技术博客专栏 - 博客频道 - CSDN.NET Redis Primer(1)基于JedisP ...

  6. docker redis 配置文件_基于Docker搭建Redis一主两从三哨兵

    点击上方"Java知音",选择"置顶公众号" 技术文章第一时间送达! 作者:oscarwin juejin.im/post/5d26b03de51d454fa3 ...

  7. docker 镜像修改的配置文件自动还原_基于Docker搭建Redis一主两从三哨兵

    作者丨oscarwin来源:https://juejin.im/post/5d26b03de51d454fa33b1960 这段时间正在学习Redis和容器相关的内容,因此想通过docker搭建一套r ...

  8. hadoop集群_使用docker部署hadoop集群

    0. 写在前面 网上也已经有很多教程了,但是其中都有不少坑,在此记录一下自己安装的过程. 目标:使用docker搭建一个一主两从三台机器的hadoop2.7.7版本的集群 准备: 首先要有一台内存8G ...

  9. nginx nodejs环境配置_基于docker的nodejs、php开发环境,包含多种组合安装

    dnnmmp 基于docker的nodejs.php开发环境 (docker,nodejs,php,nginx,mongo,mysql,redis) Dnnmmp包含以下组合 dnm(Docker + ...

最新文章

  1. HDU 5119 Happy Matt Friends ——(背包DP)
  2. 使用UWA GOT优化Unity性能和内存
  3. Vue Router路由嵌套
  4. Spring模块化设计:Spring功能特性如何在不同模块中组织?
  5. 去除并替换hselect框右边的箭头的css方法
  6. asp.net core 从 3.1 到 5.0
  7. jetson nano 系统镜像制作_2.Jetson Nano烧写系统镜像
  8. 二叉树的遍历_递归实现
  9. Julia: 亿元估值AI网红代码的不同版本(readline与replace的用法)
  10. js实现浏览器打印PDF
  11. 交换机入门书籍推荐_网络工程学习方法/路线/专业书籍推荐
  12. Eclipse使用技巧--设置编辑器背景护眼色和设置字体
  13. java指纹识别+谷歌图片识别技术
  14. Ubuntu 图形桌面与命令行界面 切换快捷键
  15. java水仙花数编程_水仙花数java编程实现
  16. 自定义结构体及初始化
  17. 分而治之(Work Breakdown Structure, WBS)
  18. 【Python基础学习一】在OSX系统下搭建Python语言集成开发环境 附激活码
  19. 聚类之K-Means++算法
  20. LeetCode题目笔记——779. 第K个语法符号,从超时到0ms(bushi)

热门文章

  1. HTML笔记——bootstrap-select、table、tableExport、layer
  2. 80211n标准建链速率计算
  3. 【Python】【jupyter-notebook】
  4. 算法竞赛入门 第2版 习题3-3 UVa1225
  5. Android 安全架构及权限控制机制剖析
  6. Linux之ab命令
  7. 记录一次奇葩的sleep(15)引起的Too many connections
  8. c语言蓝色字体,C 语言输出不同颜色字体
  9. 【毕业答辩】毕业论文答辩有技巧!
  10. 你会处理圆周率吗?----- Python操作文件应用举例