主从复制简介
互联网“三高”架构 |
高并发 |
高性能 |
高可用 |
为了避免单点Redis服务器故障 ,准备多台服务器,互相连通。将数据复制多个副本保存在不同的服务器上,连接在一起 ,并保证数据是同步的。即使有其中一台服务器宕机 ,其他服务器依然可以继续提供服务 ,实现Redis的高可用,同时实现数据冗余(褒义)备份。
主从复制即将master中的数据即时、有效的复制到slave中
特征: 一个master可以拥有多个slave ,一个slave只对应一个master
职责
master | slave |
写数据 | 写数据 (禁止) |
读数据 (可忽略) | 读数据 |
执行写操作时,将出现变化的数据自动同步到slave |
主从复制的作用
作用 | 介绍 |
读写分离 | master写、slave读,提高服务器的读写负载能力 |
负载均衡 | 基于主从结构,配合读写分离,由slave分担master负载 ,并根据需求的变化,改变slave的数量 ,通过多个从节点分担数据读取负载,大大提高Redis服务器并发量与数据吞吐量 |
故障恢复 | 当master出现问题时,由slave提供服务,实现快速的故障恢复 |
数据冗余 | 实现数据热备份,是持久化之外的一种数据冗余方式 |
高可用 | 基于主从复制,构建哨兵模式与集群,实现Redis的高可用方案 |
主从复制搭建
准备三台搭建好的redis,搭建方法在这里
方式一:客户端发送命令
开启6379和6380服务端
tail -f 查看日志文件
进入6379和6380客户端
主机有密码,修改从机的配置文件,设置主机密码:从机需要同步主机的数据,需要主机的密码
masterauth 123
slaveof <masterip> <masterport>
重启6380,进入客户端,挂到6379
方式二:启动服务器参数
开启6380服务端,启动服务端添加参数直接挂到主机
redis-server --slaveof <masterip> <masterport>
方式三:服务器配置(推荐)
直接修改配置,启动服务端不需要加--slaveof
参数
使用IP地址,不要用127.0.0.1
,Windows
的Java
程序无法连接
masterauth 123
slaveof <masterip> <masterport>
启动6379 和 6380 两个redis
./bin/redis-server ./conf/redis-6379.conf
./bin/redis-server ./conf/redis-6380.conf
观察两个redis的日志文件
tail -f 6379.log
tail -f 6380.log
6379.log
6380.log
我们就可以看到6380和6379就建立了主从关系,79是主机、80是从机,我们测试对从机进行写的操作。
可以发现从机是不能写的
我们把6381也绑定到6379,建立一主两从的集群
[root@localhost redis]# ./bin/redis-server ./conf/redis-6381.conf
启动即可,看日志文件可以发现建立成功
但是我们现在是只有主模式,这就会存在一些问题,如果主机挂了,从机正常(只能读),选一个从当主机,从机6380中执行slave of no one,这个从机切换成主机,下面没有从机,从机6381还是挂着原来的主机6379,挂掉的主机6379修复,正常上线,能够和6381正常的主从,无法挂载6380(是一个独立的主机),重启6380,一主两从,正常,这种不智能,所以我们还需要搭建哨兵模式。
哨兵模式
原理
1、sentinel 每秒发送ping命令给主、从所有节点。进行检测。
2、ping不通,标记主观下线;所有sentinel节点发送ping命等给主节点。
3、当有对半以上的节点ping不通,标记客观下线。
4、选举新的主节点井通知其他所有节点,原来的redis恢复,会变成从节点。
优点:解决主从模式宕机后停止服务的问题。满足redis集群的高可用性。
缺点:
1、额外部署多个哨兵服务,增加服务器负担。
2、主从切换的瞬间存在访问瞬断的情况。
3、单个主节点不能存配置过大的内存,以免导致RDB文件过大。
4、并发不是特别高。
哨兵模式是在主从模式基础上增加了哨兵服务,主从复制与主从集群一致。哨兵实例可以监控多个主从实例,并在主服务器下线后自动加主服务器下的某个从服务器升级为新的主服务器继续提供服务。
搭建哨兵模式
先将安装目录下哨兵配置文件复制出来
cp opt/redis-6.2.1/sentinel.conf ./mydata/
里面大多数都是注释,我们可以使用下面的命令将注释以及空行去掉,然后将文件写入sentinel-26379.conf
文件中(高级的复制)
grep -v "#"
:去掉以#开头的
grep -v "^$"
:去掉空行,这里是正则表达式^代表开头,$代表结尾,中间没有东西就代表空行
cat sentinel.conf | grep -v "#" | grep -v "^$" > sentinel-26379.conf
这是我们重写写入的配置文件
这里我们一样复制三份,因为哨兵一定是奇数,当有对半以上的节点ping不通,标记客观下线,避免偶数的对半情况。复制好的配置文件
然后我们去改配置文件,下面是参数对应的意思
port 26379
daemonize yes
pidfile /var/run/redis-sentinel-26379.pid
logfile "26379.log"
dir /opt/redis/data
sentinel monitor mymaster 192.168.195.157 6379 2
sentinel down-after-milliseconds mymaster 30000
acllog-max-len 128
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000
sentinel deny-scripts-reconfig yes
SENTINEL resolve-hostnames no
SENTINEL announce-hostnames no
sentinel auth-pass mymaster 123
这个是6380的配置文件,因为这里是三台哨兵监视一台主机所以还是要配主机的地址,其它改变,26381同理这里就不写了 ;
这里还要给主机6379也配一个密码,因为主机如果挂了,哨兵会自动把从机变成新的主机,修好了过后它会变成从机去挂新的主机,这个时候就需要密码,所以我们需要给主机配主从确认密码。
然后把我们三个哨兵配置文件复制进redis中的conf文件夹中
批量复制
cp /home/usr/dir/{file1,file2,file3,file4} /home/usr/destination/
启动三个哨兵
./bin/redis-sentinel ./conf/sentinel-26379.conf
可以监控三个哨兵的配置文件,可以从监控文件中看到80和81与79的主从关系等等。
进入哨兵客户端,他的作用只是监视,不能去读写
输入Info
可以去看基本信息
模拟主机出故障的情况
看日志文件,可以清楚的发现6380变成的了主机
我们去查看6380的信息,可以发现他已经是主机了有一台从机是6381,6379还是故障状态
我们修复6379(重启),然后去看6379的信息,可以发现他已经是从机了,主机是6380
再看6380的信息,发现他有两台从机。
即6379主机挂了,哨兵自动切换主机,6379修好上线后变成从机,
至此搭建完成。
Java连接哨兵
配置文件
spring.redis.host=192.168.195.157
spring.redis.port=6379
spring.redis.password=123
spring.redis.database=0
spring.redis.jedis.pool.max-active=20
spring.redis.jedis.pool.max-idle=10
测试代码
@Autowired
RedisTemplate<String, Object> redisTemplate;
@Test
void test() {
ValueOperations<String, Object> opsForValue = redisTemplate.opsForValue();
opsForValue.set("s", "111");
System.out.println(opsForValue.get("s"));
}
执行结果:
由上面的配置文件 可以看出我们对6379进行写入操作,但是6379现在是从机是不能进行写的操作,所以报错
把配置文件改成6380(主机),再看结果
我们启动三个哨兵服务器,首先在linux中打开三个端口
firewall-cmd --zone=public --add-port=26379/tcp --permanent
firewall-cmd --reload
#这里就不需要了,让他们自己去找
#spring.redis.host=192.168.195.157
#spring.redis.port=6380
spring.redis.password=123
spring.redis.database=0
spring.redis.jedis.pool.max-active=20
spring.redis.jedis.pool.max-idle=10
#指定主机的名字
spring.redis.sentinel.master=mymaster
#哨兵的地址
spring.redis.sentinel.nodes=192.168.195.157:26379,192.168.195.157:26380,192.168.195.157:26381
#这里我们没有为哨兵设置密码,所以不用写
#spring.redis.sentinel.password=xxx
用上面的代码测试一下
记过没问题,就完成了java对哨兵的连接