redis主从复制


是什么

主机数据更新后根据配置和策略, 自动同步到备机的master/slaver机制,Master以写为主,Slave以读为主

能干嘛

  • 读写分离,性能扩展
  • 容灾快速恢复

怎么玩:主从复制

  • 拷贝多个redis.conf文件include(写绝对路径)
  • 开启daemonize yes
  • Pid文件名字pidfile
  • 指定端口port
  • Log文件名字
  • dump.rdb名字dbfilename
  • Appendonly 关掉或者换名字

新建redis6379.conf,填写以下内容

include /myredis/redis.conf
pidfile /var/run/redis_6379.pid
port 6379
dbfilename dump6379.rdb

新建redis6380.conf,填写以下内容

新建redis6381.conf,填写以下内容


slave-priority 10
设置从机的优先级,值越小,优先级越高,用于选举主机时使用。默认100

启动三台redis服务器

查看系统进程,看看三台服务器是否启动

查看三台主机运行情况

info replication
打印主从复制的相关信息

配从(库)不配主(库)

命令:slaveof
成为某个实例的从服务器
1、在6380和6381上执行: slaveof 127.0.0.1 6379

2、在主机上写,在从机上可以读取数据
在从机上写数据报错

3、主机挂掉,重启就行,一切如初
4、从机重启需重设:slaveof 127.0.0.1 6379
可以将配置增加到文件中。永久生效。

常用3招

一主二仆

切入点问题?slave1、slave2是从头开始复制还是从切入点开始复制?比如从k4进来,那之前的k1,k2,k3是否也可以复制?
可以
从机是否可以写?set可否?
不行,从机只读
主机shutdown后情况如何?从机是上位还是原地待命?
原地待命
主机又回来了后,主机新增记录,从机还能否顺利复制?
可以
其中一台从机down后情况如何?依照原有它能跟上大部队吗?

薪火相传

上一个Slave可以是下一个slave的Master,Slave同样可以接收其他 slaves的连接和同步请求,那么该slave作为了链条中下一个的master, 可以有效减轻master的写压力,去中心化降低风险。
用 slaveof
中途变更转向:会清除之前的数据,重新建立拷贝最新的
风险是一旦某个slave宕机,后面的slave都没法备份
主机挂了,从机还是从机,无法写数据了


反客为主

当一个master宕机后,后面的slave可以立刻升为master,其后面的slave不用做任何修改。
用 slaveof no one 将从机变为主机。

复制原理

  • Slave启动成功连接到master后会发送一个sync命令
  • Master接到命令启动后台的存盘进程,同时收集所有接收到的用于修改数据集命令, 在后台进程执行完毕之后,master将传送整个数据文件到slave,以完成一次完全同步
  • 全量复制:而slave服务在接收到数据库文件数据后,将其存盘并加载到内存中。
  • 增量复制:Master继续将新的所有收集到的修改命令依次传给slave,完成同步
  • 但是只要是重新连接master,一次完全同步(全量复制)将被自动执行

哨兵模式

是什么

反客为主的自动版,能够后台监控主机是否故障,如果故障了根据投票数自动将从库转换为主库

单哨兵模式

哨兵的两个作用

  • 通过发送命令,让Redis 服务器返回监控其运行状态,包括主服务器和从服务器。
  • 当哨兵检测到Master宕机时,会通过投票机制自动将Slave切换成Master,然后再通过发布订阅模式通知其它的从服务器,修改配置文件,让它们切换主机。

多哨兵模式


多哨兵模式中,如果主机宕机了会怎么样?
假设主服务器宕机,哨兵1先检测到这个结果,但是系统并不会马上进行failover(故障转移)过程,因为仅仅是哨兵1主观认为主服务器不可用,这个现象成为主观下线。当后面的哨兵也检测到主服务器连接不上了,并且数量达到一定值时(3个哨兵中两个哨兵检测主机不能使用了,那么就认为这个主机挂掉了),那么哨兵之间就会对从机中进行一次选举主机的投票,投票的结果由其中任意一个哨兵(随机)发起,然后进行failover(故障转移)操作,选举成功后就将该从机切换成主机,之后就会通过发布订阅模式(所有的服务都被哨兵监控着),让各个哨兵把自己监控的从服务器实现切换主机,这个过程成为客观下线。

怎么玩

1、调整为一主二仆模式,6379带着6380、6381

2、自定义的/myredis目录下新建sentinel.conf文件,名字绝不能错

3、配置哨兵,填写内容
sentinel monitor mymaster 127.0.0.1 6379 1
其中mymaster为监控对象起的服务器名称, 1 为至少有多少个哨兵同意迁移的数量

4、启动哨兵
执行redis-sentinel /myredis/sentinel.conf

5、当主机挂掉,从机选举中产生新的主机
(大概10秒左右可以看到哨兵窗口日志,切换了新的主机)
哪个从机会被选举为主机呢?根据优先级别:slave-priority
原主机重启后会变为从机。

优点

  • 哨兵集群,基于主从复制模式,所有的主从配置的优点,它都有。
  • 主从可以切换,故障可以转移,系统的可用性就会更好。
  • 哨兵模式就是主从模式的升级版,从收到到自动,更加健壮。

缺点

  • Redis不好在线扩容,集群容量一旦达到上限,在线扩容就会十分麻烦。
  • 实现哨兵模式的配置比较麻烦,并且其中有很多选项

哨兵模式配置文件中的全部配置

# Example   sentinel.conf
# 哨兵sentinel实例运行的端口   默认是26379,如果有哨兵集群,我们还需要配置每个哨兵端口
port 26379
#哨兵sentinel的工作目录
dir /tmp
#哨兵 sentine1 监控的redis主节点的 ip port   
# master-name  ,可以自己命名的主节点名字 只能由字母A-Z、数字0-9、这三个字符"  .   -  _ "组成。
# quorum配置多少个sentine1哨兵统- -认为master主节点失联那么这时客观上认为主节点失联了
# sentine1 monitor    
sentinel monitor mymaster   127.0.0.1   6379   2
#当在Redis实例中开启了requirepass foobared 授权密码这样所有连接kedis实例的客户端都要提供密码
#设置哨兵sentinel连接主从的密码注意必须为主从设置- - 样的验证密码
# sentine1 auth-pass  
sentine1 auth-pass mymaster MySUPER--secret-0123passwOrd
#指定多少毫秒之后主节点没有应答哨兵sentine1 此时哨兵主观上认为主节点下线默认30秒
# sentinel down-after-mi 11i seconds  
sentine1 down-after-mi 11iseconds mymaster 30000
#这个配置项指定了在发生failover主备切换时最多可以有多少个slave同时对新的master进行同步,这个数字越小,完成fai lover所需的时间就越长,但是如果这个数字越大,就意味着越多的slave因为replication而 不可用。可以通过将这个值设为1来保证每次只有一个slave处于不能处理命令请求的状态。
# sentine1 paralle1-syncs  
sentine1 paralle1-syncs mymaster 1
#故障转移的超时时间failover-timeout 可以用在以下这些方面:
#1.同一个sentine1对同一 个master两次fai lover之间的间隔时间。
#2.当一个slave从一 个错误的master那里同步数据开始计算时间。直到s1ave被纠正为向正确的master那里同步数据时。
#3.当想要取消一个正在进行的failover所需要的时间。
#4.当进行failover时,配置所有s1aves指向新的master所需的最大时间。不过,即使过了这个超时,slaves 依然会被正确配置为指向master,但是就不按parallel-syncs所配置的规则来了
#默认三分钟
# sentine1 failover-timeout  
sentine1 fai lover-ti meout mymaster 180000
# SCRIPTS EXECUTION
#配置当某一事件发生时所需要执行的脚本,可以通过脚本来通知管理员,例如当系统运行不正常时发邮件通知相关人员。
#对于脚本的运行结果有以下规则:
#若脚本执行后返回1,那么该脚本稍后将会被再次执行,重复次数目前默认为10
#若脚本执行后返回2,或者比2更高的一个返回值,脚本将不会重复执行。
#如果脚本在执行过程中由于收到系统中断信号被终止了,则同返回值为1时的行为相同。
#一个脚本的最大执行时间为60s,如果超过这个时间,脚本将会被-一个SIGKILL信号终止,之后重新执行。
#通知型脚本:当sentine1有任何警告级别的事件发生时(比如说redis实例的主观失效和客观失效等等),将会去调用这个脚本,这时这个脚本应该通过邮件,SMS等 方式去通知系统管理员关于系统不正常运行的信息。调用该脚本时,将传给脚本两个参数,一 个是事件的类型,一个是事件的描述。如果sentine1. conf配置文件中配置了这个脚本路径,那么必须保证这个脚本存在于这个路径,并且是可执行的,否则sentine1无法正常启动成功。
#通知脚本
# she11编程
# sentine1 notification-script  
sentine1 notificati on-script mymaster /var/redis/notify. sh
#客户端重新配置主节点参数脚本
#当一个master由于failover而发生改变时,这个脚本将会被调用,通知相关的客户端关于master地址已经发生改变的信息。
#以下参数将会在调用脚本时传给脚本: 
#       
#目前总是“failover",
# 是“Teader"或者"observer"中的-一个。
#参数from-ip, from-port, to-ip,to-port是用来和旧的master和新的master(即旧的s lave)通信的
#这个脚本应该是通用的,能被多次调用,不是针对性的。
# sentine1 client-reconfig-script  
sentine1 client-reconfig-script mymaster /var/redis/reconfig.sh #一般都是由运维来配置!

复制延时

由于所有的写操作都是先在Master上操作,然后同步更新到Slave上,所以从Master同步到Slave机器有一定的延迟,当系统很繁忙的时候,延迟问题会更加严重,Slave机器数量的增加也会使这个问题更加严重。

故障恢复


优先级在redis.conf中默认:slave-priority 100,值越小优先级越高
偏移量是指获得原主机数据最全的
每个redis实例启动后都会随机生成一个40位的runid

java中使用

private static JedisSentinelPool jedisSentinelPool=null;

public static  Jedis getJedisFromSentinel(){
    if(jedisSentinelPool==null){
        Set sentinelSet=new HashSet<>();
        sentinelSet.add("192.168.11.103:26379");

        JedisPoolConfig jedisPoolConfig =new JedisPoolConfig();
        jedisPoolConfig.setMaxTotal(10); //最大可用连接数
        jedisPoolConfig.setMaxIdle(5); //最大闲置连接数
	jedisPoolConfig.setMinIdle(5); //最小闲置连接数
	jedisPoolConfig.setBlockWhenExhausted(true); //连接耗尽是否等待
	jedisPoolConfig.setMaxWaitMillis(2000); //等待时间
	jedisPoolConfig.setTestOnBorrow(true); //取连接的时候进行一下测试 ping pong

	jedisSentinelPool=new JedisSentinelPool("mymaster",sentinelSet,jedisPoolConfig);
	return jedisSentinelPool.getResource();
   }else{
	return jedisSentinelPool.getResource();
   }
}

springboot配置哨兵模式

spring:
  redis:
    sentinel:
      master: mymaster # 主节点名称
      nodes: 192.168.192.130:26379 # 哨兵节点
    database: 0
    # 读连接超时时间(毫秒)
    timeout: 1800000
    lettuce:
      pool:
        #连接超时时间(毫秒)
        max-active: 20
        #连接超时时间(毫秒)
        max-wait: 1
        #连接超时时间(毫秒)
        max-idle: 15
        #连接池中的最小空闲连接
        min-idle: 0