搭建Redis主从复制的集群
在主从复制模式的集群里,主节点一般是一个,从节点一般是两个或多个,写入主节点的数据会被复制到从节点上,这样一旦主节点出现故障,应用系统能切换到从节点去读写数据,这样能提升系统的可用性。而且如果再采用主从复制模式里默认的读写分离的机制,更能提升系统的缓存读写性能。所以对性能和实时性不高的系统而言,主从复制模式足以满足一般的性能和安全性方面的需求。
1 概述主从复制模式
在实际应用中,如果有相应的设置,在向一台Redis服务器里写数据后,这个数据可以复制到另外一台(或多台)Redis服务器,这里数据源服务器叫主服务器(Master Server),而复制数据目的地所在的服务器叫从服务器(Slave Server)。
这种主从复制模式能带来两个好处,第一,可以把写操作集中在主服务器上,把读操作集中到从服务器上,这样能提升读写性能;第二,由于出现了数据备份,所以能提升数据安全性,比如当主Redis服务器失效后,能很快切换到从服务器上读数据。
如果在项目,并发要求不高,或者说哪怕从Redis缓存里读不到数据对性能也不会有太大的损害,那么可以用一主一从的复制模式,效果图如下图所示。
也可以设置一主多从的复制效果,在下图里,给出对应的效果图,即写到主节点的数据会同步到两个从节点上,其它一主多从的模式和这很相似。
关于主从复制模式,请大家注意如下的要点。
第一, 一个主服务器可以带一个或多个从服务器,甚至从服务器也可以再带从服务器,但在复制数据时,只能把主服务器的数据复制到从服务器上,反之不能。
第二, 一台从服务器只能跟随一台主服务器,而不能出现一从多主的模式。
第三, 在 Redis 2.8以后的版本里,是采用异步的复制模式,即进行主从复制时,不会影响主服务器上的读写数据操作。
2 用命令搭建主从集群
这里将用Docker容器来搭建一主二从模式的集群,在配置主从关系时,需要在从节点上使用slaveof命令,具体的步骤如下。
第一步,打开一个命令窗口,在其中运行如下命令创建一个名为redis-master的Redis容器,请注意它的端口是6379。
docker run -itd --name redis-master -p 6379:6379 redis:latest
第二步,再新开一个命令窗口,在其中运行如下命令创建一个名为redis-slave1的容器,请注意它的端口是6380。请注意这里是在一台电脑上运行,所以用端口号来区别一台主Redis容器和另外两台从Redis容器。如果在真实项目里,多台Redis会部署在不同的服务器上,所以可以都用6379端口。
docker run -itd --name redis-slave1 -p 6380:6380 redis:latest
第三步,回到包含redis-master容器的命令窗口,在其中运行docker inspect redis-master命令,查看redis-master容器的信息,在其中能通过IPAddress项看到改容器的IP地址,这里是172.17.0.2。如果在真实项目里,Redis服务器所在的IP地址是固定的,而通过Docker容器启动的Redis服务器的IP地址是动态的,所以这里要用上述命令来获取IP地址。
第四步,在redis-master容器的命令窗口里,运行docker exec -it redis-master /bin/bash命令,进入到命令行窗口,在其中用redis-cli命令进入到Redis客户端命令行后,再通过info replication命令查看当前的主从模式的状态,能看到如下所示的部分结果。
1 c:\work>docker exec -it redis-master /bin/bash
2 root@9433cd584d80:/data# redis-cli
3 127.0.0.1:6379> info replication
4 # Replication
5 role:master
6 connected_slaves:0
从第5行的输出里能看到,当前reids-master容器在主从模式里的角色是“主服务器”,从第6行的输出里能看到,当前该主服务器没有携带从服务器。
同样再到redis-slave1容器的命令窗口里,通过docker exec -it redis-slave1 /bin/bash命令进入容器的命令行窗口,也通过redis-cli命令进入客户端命令行,也再通过info replication命令查看该Redis服务器的主从模式的状态,部分结果如下所示。
1 c:\work>docker exec -it redis-slave1 /bin/bash
2 root@2e3237c60211:/data# redis-cli
3 127.0.0.1:6379> info replication
4 # Replication
5 role:master
6 connected_slaves:0
由于此时还没有通过命令行设置主从模式,所以从第5行和第6行的输出结果里,依然看到当前服务器是“主服务器”,同时没有携带从服务器。
第五步,在redis-slave1容器的命令窗口里,运行如下的slaveof命令,指定当前Redis服务器为从服务器。该命令的格式是slaveof IP地址 端口号,这里是指向172.17.0.2:6379所在的主服务器。
slaveof 172.17.0.2 6379
运行完该命令后,还是在redis-slave1客户端里,再次运行info replication,会看到如下所示的部分结果。从第3行的结果里能看到,该redis-slave1服务器已经成为从服务器,并能从第4行和第5行的输出里能确认,该从服务器是从属于172.17.0.2:6379所在的Redis主服务器。
1 127.0.0.1:6379> info replication
2 # Replication
3 role:slave
4 master_host:172.17.0.2
5 master_port:6379
此时再回到redis-master容器的命令窗口里,在Redis客户端里再次运行info replication命令查看主从状态,能看到如下所示的部分结果。从第4行的输出里能看到,该Redis主服务器已经携带了一个从服务器。
1 127.0.0.1:6379> info replication
2 # Replication
3 role:master
4 connected_slaves:1
第六步,再打开一个新的命令窗口,在其中运行如下命令,开启一个新的名为redis-slave2的Redis容器,请注意它的端口是6381。
docker run -itd --name redis-slave2 -p 6381:6381 redis:latest
随后再运行docker exec -it redis-slave2 /bin/bash命令进入该容器的命令行窗口,再通过redis-cli命令进入客户端,运行slaveof 172.17.0.2 6379命令,把这个Redis服务器也设为从服务器,并连到redis-master这个容器所在的主Redis服务器上。
连接完成后,再回到redis-master容器所在的命令行窗口,再运行info replication命令,此时能看到如下的部分输出,从第4行的输出里能看到,当前该主服务器连接着两台从服务器。
1 127.0.0.1:6379> info replication
2 # Replication
3 role:master
4 connected_slaves:2
至此配置完成一主两从模式的主从模式,此时如果到两台从服务器里运行get name命令,返回是空,如果到redis-master容器所在的命令行窗口,在其中运行set name Peter后,再到两台从服务器里运行get name命令,就能看到返回值。这说明主从模式配置成功,主服务器里的数据会自动同步到各从服务器上。
3 通过配置搭建主从集群
在项目里可以用slaveof命令搭建主从模式的集群外,还可以用配置参数的方式来搭建,具体的步骤如下。
第一步,搭建主服务器redis-master的命令不变,依然用如下的命令,这里还是用6379端口。
docker run -itd --name redis-master -p 6379:6379 redis:latest
用docker inspect redis-master命令确认该Redis服务器所在容器的IP地址依然是172.17.0.2。
第二步,到C:\work\redis\redisConf目录里,创建配置文件redisSlave1.conf,并在其中编写如下内容。
port 6380
slaveof 172.17.0.2 6379
通过第1行的命令,设置该Redis的端口为6380,通过第2行的slaveof配置,把该Redis服务器设置成“从模式”,并连接到redis-master所在的主服务器上。
第三步,在新的命令窗口里运行如下的命令,创建名为redids-slave1的Redis服务器。该服务器的工作端口是6380,并且用redis-server后的参数指定在启动Redis服务器时加载redisSlave1.conf配置文件,
docker run -itd --name redis-slave1 -v C:\work\redis\redisConf:/redisConfig:rw -p 6380:6380 redis:latest redis-server /redisConfig/redisSlave1.conf
随后再通过docker exec -it redis-slave1 /bin/bash命令进入到该容器的命令行,由于这里Redis工作端口已经变成6380,所以需要通过redis-cli -h 127.0.0.1 -p 6380命令来进入Redis客户端,如果在其中运行info replication命令,能看到如下的部分结果,由此能进一步确认redis-slave1服务器已经从属于redis-master服务器。
1 root@80e7ae14a322:/data# redis-cli -h 127.0.0.1 -p 6380
2 127.0.0.1:6380> info replication
3 # Replication
4 role:slave
5 master_host:172.17.0.2
6 master_port:6379
第四步,到C:\work\redis\redisConf目录里,创建配置文件redisSlave2.conf,并在其中编写如下内容。
port 6381
slaveof 172.17.0.2 6379
这里用到了6381端口,同样也通过slaveof命令连接到redis-master服务器上。随后在新的命令窗口里运行如下的命令,创建名为redids-slave2的Redis服务器。该服务器的工作端口是6381,并且用redis-server后的参数指定在启动Redis服务器时加载redisSlave2.conf配置文件,
docker run -itd --name redis-slave2 -v C:\work\redis\redisConf:/redisConfig:rw -p 6381:6381 redis:latest redis-server /redisConfig/redisSlave2.conf
随后再通过docker exec -it redis-slave2 /bin/bash命令进入到该容器的命令行,由于这里Redis工作端口已经变成6381,所以需要通过redis-cli -h 127.0.0.1 -p 6381命令来进入Redis客户端,这里可以再通过info replication命令确认配置效果,部分运行结果如下所示。
1 root@6017108b97c4:/data# redis-cli -h 127.0.0.1 -p 6381
2 127.0.0.1:6381> info replication
3 # Replication
4 role:slave
5 master_host:172.17.0.2
6 master_port:6379
至此完成了以配置文件设置主从复制集群的设置,此时如果到主服务器redis-master所在的客户端里运行set age 18命令,再到redis-slave1和redis-slave2这两台从服务器里运行get age命令,能看到age的值,由此能再次确认主从服务器之间能同步数据。
4 配置读写分离效果
如果在上文里配置的redis-slave1和redis-slave2这两台从服务器里,运行info replication命令,还能看到“slave_read_only:1”这项配置,说明从服务器默认是“只读”的,如果到redis-slave1的Redis客户端命令行里输入set val 1,会看到如下第2行所示的错误,从而能进一步验证该Redis服务器的“只读”属性。
127.0.0.1:6380> set val 1
(error) READONLY You can't write against a read only replica.
对于Redis从服务器而言,建议采用默认的“只读”配置,因为在项目里,一般不会向作为数据同步目的地的“从服务器”上写数据。如果业务上确实需要,可以通过如下的步骤设置“可读可写”的效果。
第一步,在上文提到的redisSlave2.conf配置文件里再加入一行“slave-read-only no”的配置,指定该服务器可读可写。
第二步,如果上文提到的redis-slave2容器还处于活动状态,则需要先用docker stop redis-slave2停止该容器,随后再用docker rm redis-slave2命令删除该容器,之后可以再用如下的命令再次创建redis-slave2容器。
docker run -itd --name redis-slave2 -v C:\work\redis\redisConf:/redisConfig:rw -p 6381:6381 redis:latest redis-server /redisConfig/redisSlave2.conf
在redis-server命令后所带的redisSlave2.conf配置文件里,已经用“slave-read-only no”配置项设置了“可读可写”的模式。
第三步,再通过docker exec -it redis-slave2 /bin/bash命令进入到该容器的命令行,再通过redis-cli -h 127.0.0.1 -p 6381命令进入Redis客户端, 此时如果再运行set val 1命令,就能成功写入数据。
5 用心跳机制提升主从复制可靠性
在Redis主从复制模式里,如果主从服务器之间有数据同步的情况,那么从服务器会默认以一秒一次的频率,向主服务器发送REPLCONF ACK命令,依次来确保两者间连接通畅。这种定时交互命令确保连接的机制就叫“心跳”机制。在上文开启的redis-master这个主服务器的命令行里,如果运行info replication命令,能看到它从属服务器的“心跳”状况。
1 127.0.0.1:6379> info replication
2 # Replication
3 role:master
4 connected_slaves:2
5 slave0:ip=172.17.0.3,port=6380,state=online,offset=16185,lag=1
6 slave1:ip=172.17.0.4,port=6381,state=online,offset=16185,lag=1
其中在第5行和第6行里,能通过lag表示该从属服务器发送REPLCONF ACK命令的时间,这里均是1秒,这表示两台从服务器和主服务器的连接均属通畅。
这里大家可以想象下,如果从服务器宕机,那么主从复制就没有意义了。对此,可以通过如下的步骤来关联心跳机制和主动复制的动作。
第一步,在C:\work\redis\redisConf目录里新建redisMaster.conf文件,在其中编写如下的代码。
min-slaves-to-write 2
min-slaves-max-lag 15
第1行的参数表示实现主从复制的从服务器个数最少是2台,第2行的参数表示,如果有第1行参数指定的从服务器个数(这里是2台)的心跳延迟时间(即lag值)大于15秒,不执行主从复制。
这两个条件是“或者”的关系,即只要出现从服务器个数小于2,或者2台从服务器的心跳延迟时间大于15秒,主服务器即停止主从复制的操作。
第二步,通过如下的命令启动redis-master容器,由于此时启动Redis服务器时已经加载了上述配置,所以该Redis主服务器在执行主从复制时,会检测第一步所设置的条件。从而能提升主从复制的可靠性。
docker run -itd --name redis-master -v C:\work\redis\redisConf:/redisConfig:rw -p 6379:6379 redis:latest redis-server /redisConfig/redisMaster.conf
6 用偏移量检查数据是否一致
在上文开启的redis-master主服务器的命令行里,如果运行info replication命令,还能看到表示复制数据偏移量的master_repl_offset数据,效果如下第6行所示。这里数据是276,表示主服务器向从服务器发送数据的字节数。
1 127.0.0.1:6379> info replication
2 # Replication
3 role:master
4 connected_slaves:1
5 …
6 master_repl_offset:276
同样如果到redis-slave1从服务器的命令行里,也能通过info replication查看该偏移量,效果如下第7行所示。
1 127.0.0.1:6380> info replication
2 # Replication
3 role:slave
4 master_host:172.17.0.2
5 master_port:6379
6 …
7 slave_repl_offset:276
在从服务器里,该数据表示从主服务器中接收到的数据字节数,如果主从服务器中两者数据一致,这说明主从服务器间的数据是同步的。
当在主服务器redis-master里运行set nextVal 1命令后,再用info replication查看master_repl_offset数值,会发现有变化,而此时再到redis-slave1从服务器运行info replication命令,会发现从服务器的master_repl_offset数值依然和主服务器一致,这说明用set nextVal 1命令在主服务器里增加的数据已经成功同步到从服务器。也就是说,如果出现Redis问题,可以通过master_repl_offset数值来检查同步数据是否正确,由此再进一步排查问题。
版权声明:本文谢绝转载
搭建Redis主从复制的集群的更多相关文章
- CentOS中搭建Redis伪分布式集群【转】
解压redis 先到官网https://redis.io/下载redis安装包,然后在CentOS操作系统中解压该安装包: tar -zxvf redis-3.2.9.tar.gz 编译redis c ...
- Redis进阶实践之十 Redis主从复制的集群模式
一.引言 Redis的基本数据类型,高级特性,与Lua脚本的整合等相关知识点都学完了,说是学完了,只是完成了当前的学习计划,在以后的时间还需继续深入研究和学习.从今天开始来讲一下有关Re ...
- Redis实战——redis主从复制和集群实现原理
出自:https://blog.csdn.net/nuli888/article/details/52136822 redis主从复制redis主从配置比较简单,基本就是在从节点配置文件加上:slav ...
- Window平台搭建Redis分布式缓存集群 (一)server搭建及性能測试
百度定义:Redis是一个key-value存储系统.和Memcached类似,它支持存储的value类型相对很多其它.包含string(字符串).list(链表).set(集合).zset(sort ...
- redis 主从复制 和集群
redis集群最少三个节点 之间相互通信ping-pong 投票选举机制 主从复制 的话 最少六个节点 ,主三从三
- 基于Docker-compose搭建Redis高可用集群-哨兵模式(Redis-Sentinel)
原文转载自「刘悦的技术博客」https://v3u.cn/a_id_110 我们知道,Redis的集群方案大致有三种:1)redis cluster集群方案:2)master/slave主从方案:3) ...
- 超详细的 Redis Cluster 官方集群搭建指南
今天从 0 开始搭建 Redis Cluster 官方集群,解决搭建过程中遇到的问题,超详细. 安装ruby环境 因为官方提供的创建集群的工具是用ruby写的,需要ruby2.2.2+版本支持,rub ...
- Redis进阶实践之十一 Redis的Cluster集群搭建
一.引言 本文档只对Redis的Cluster集群做简单的介绍,并没有对分布式系统的详细概念做深入的探讨.本文只是提供了有关如何设置集群.测试和操作集群的说明,而不涉及Redis集群规范中涵 ...
- redis主从、集群、哨兵
redis的主从.集群.哨兵 参考: https://blog.csdn.net/robertohuang/article/details/70741575 https://blog.csdn.net ...
随机推荐
- 读CSAPP第二章的收获
一:一道很有意思的位运算题目:你只有两种操作 bis(x, y): 在y为1的每个位置上,将x的对应的位设为1bic(x, y): 在y为1的每个位置上,将x的对应的位设为0 简单的化简一下bis(x ...
- 在java中捕获异常时,使用log4j打印出错误堆栈信息
当java捕获到异常时,把详细的堆栈信息打印出来有助于我们排查异常原因,并修复相关bug,比如下面两张图,是打印未打印堆栈信息和打印堆栈信息的对比: 那么在使用log4j输出日志时,使用org.apa ...
- 一文梳理Web存储,从cookie,WebStorage到IndexedDB
前言 HTTP是无状态的协议,网络早期最大的问题之一是如何管理状态.服务器无法知道两个请求是否来自同一个浏览器.cookie应运而生,开始出现在各大网站,然而随着前端应用复杂度的提高,Cookie 也 ...
- System.Timers.Timer(定时器)
1.System.Timers命名空间下的Timer类.System.Timers.Timer类:定义一个System.Timers.Timer对象,然后绑定Elapsed事件,通过Start()方法 ...
- LintCode笔记 - 145.大小写转换 - 极简之道 - 最短代码
这道题目一眼就能看出是送分题,当然在这里也不谈高难度的实现逻辑,肯定有同学会想直接用自带函数实现不就可以了吗? 对的,就是这么简单,然而今天的重点是如何把代码简写到最短. 本文章将带你把代码长度从 一 ...
- ArrayList源码分析-jdk11 (18.9)
目录 1.概述 2.源码分析 2.1参数 2.2 构造方法 2.2.1 无参构造方法 2.2.2 构造空的具有特定初始容量值方法 2.2.3构造一个包含指定集合元素的列表,按照集合的迭代器返回它们的顺 ...
- python处理json总结
一.首先,了解下什么是JSON? JSON:JavaScript Object Notation [JavaScript 对象表示法] JSON 是一种轻量级的数据交换格式,完全独立于任何程序语言的文 ...
- Spring的学习与实战(续)
@ 目录 背景 JavaMailSender Spring集成邮件发送功能 1. 添加maven依赖 2. 添加Spring邮件配置 3. 创建邮件管理Bean并注入Spring应用上下文 4. 修改 ...
- 【Python学习笔记六】获取百度搜索结果以及百度返回“百度安全验证”问题解决
1.获取百度搜索结果页面主要是修改百度搜索url中的参数实现,例如查询的关键字为wd: 举例:https://www.baidu.com/s?wd=python",这样就可以查询到‘pyth ...
- Shell基本语法---while语句
while语句 格式 while [ 条件判断式 ] do 执行动作 done 例子 i= while [ $i -gt ] do echo $i i=$((i - )) done