Redis(四)(主从复制-搭建环境测试,哨兵模式-测试,缓存穿透,缓存击穿,缓存雪崩)

1、主从复制

(1)为什么会有主从复制?
  • 通过持久化功能,Redis保证了即使在服务器重启的情况下数据也不会丢失,但是由于数据是存储在一台服务器上的,如果这台服务器出现故障,比如硬盘坏了,也会导致数据的丢失。
  • 所以为了避免这种故障,我们需要将数据复制到多份部署在多台不同的服务器上,即使有一台服务器出现了故障,其他服务器依然可以继续提供服务。
  • 这就要求当一台服务器上的数据更新后,自动将更新的数据同步到其他服务器上,这时候就用到了Redis的主从复制。
(2)主从复制能干啥?
  • Reids提供了复制功能来自动实现多台服务器的数据同步
  • 我们可以部署多台redis,并在配置文件中指定这几台redis之间的主从关系,主负责写入数据,同时吧写入的数据同步实时到从机器,从负责读出数据,这样就实现了读写分离,减缓服务器的压力。
(3)搭建一主二从环境

查看当前服务器的信息

127.0.0.1:6379> info replication #查看当前库的信息
# Replication
role:master   # 角色 master
connected_slaves:0   #没有从机
master_replid:ec71d1c254d84b6b90741d40b18a4f9e7f5794df
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:0
second_repl_offset:-1
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0

1、复制三个配置文件,并修改相应信息:端口号、pid名字、log日志名、rdb文件名,并启动。
在这里插入图片描述
2、搭建一主二从

默认情况下,每台Redis服务器都是主节点,一般情况下只用配置从机就好了

配置从机80

127.0.0.1:6380> SLAVEOF 127.0.0.1 6379  #配置从机到主机(6379)
OK
127.0.0.1:6380> info replication
# Replication
role:slave #当前角色是从机
master_host:127.0.0.1 # 主机信息
master_port:6379
master_link_status:up
master_last_io_seconds_ago:4
master_sync_in_progress:0
slave_repl_offset:0
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:1f2cf82fa95696b20170cecbe96e931edffd0d7c
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:0
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:0

查看配置后主机信息

127.0.0.1:6379> info replication 
# Replication
role:master  #角色是主机
connected_slaves:2  #从机个数
# 从机的详细信息
slave0:ip=127.0.0.1,port=6380,state=online,offset=336,lag=1
slave1:ip=127.0.0.1,port=6381,state=online,offset=336,lag=1
master_replid:1f2cf82fa95696b20170cecbe96e931edffd0d7c
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:336
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:336

真实的主从配置应该是在配置文件中的REPLICATION进行配置的,这样配置的是永久的,这里使用命令来进行配置只是暂时的。

(4)测试

主机可以写,从机只能读不能写,主机中所有的数据都会自动同步到从机。

主机写

127.0.0.1:6379> keys *
(empty list or set)
127.0.0.1:6379> set k1 v1
OK

从机读

127.0.0.1:6380> keys *
(empty list or set)
127.0.0.1:6380> get k1
"v1"
127.0.0.1:6380> set k2 v2
(error) READONLY You can't write against a read only replica
  • 当主机连接断掉之后,从机依旧连接到主机的,但是不能写,这个时候,主机如果回来了,从机依旧可以获取到主机写进去的信息。
  • 如果使用命令行配置的,当从机断掉时候,再重新连接机会变回主机,但是只要变为从机,主机中写入的值立马就能获取到。
(5)复制原理

从机启动成功连接到主机后会发送一个sync同步命令,主机接到命令,启动后台的存盘进程,同时手机所有接受到的用户修改数据集命令,在后台进程执行完毕之后,主机将传送整个数据文件到从机,并完成第一次完全同步。

  • 全量复制:从机服务在接受到数据库文件数据后,将其存盘并加载到内存中。
  • 增量复制 :主机继续将新的所有收集到的修改命令依次传递给从机,完成同步。
    但是只要是从机重新连接主机,一次完全同步(全量复制)将自动执行
(6)使用层层链路型来进行连接

在这里插入图片描述
经过测试之后发现这种方式依然可以完成主从复制。

(7)主机宕机后手动配置主机
SLAVEOF no one # 让从机变为主机

主机恢复过来之后,就需要重新连接

2、哨兵模式

(1)概述
  • 主从切换技术的方法是:当服务器宕机后,需要手动把一台从从机切换为主机,这需要人工干预,不仅费时费力而且还会造成一段时间内服务不可用。所以就有了哨兵模式。
  • 谋朝篡位的自动版,能够监控后台主机是否故障,如果故障就会根据票数自动将从机变为主机
(2)单哨兵模式

哨兵模式是一种特殊的模式,首先Redis提供了哨兵的命令,哨兵是一个独立的进程,它会独立运行通过发送命令,等待Redsi服务器响应,从而监控多个Redis服务。
在这里插入图片描述
这里的哨兵有两个作用

  • 通过发送命令,来监控Rdis服务器的运行状态。
  • 当检测到主机宕机,会自动将某个从机切换为主机,然后通过发布订阅模式来通知其他服务器修改配置文件进行连接。
(3)多哨兵模式

然而一个哨兵对Redis服务器进行监控,当这个哨兵出现了问题该怎么办,因此我们可以使用多个哨兵来进行监控,每个哨兵之间也会进行监控,这样就形成了多哨兵模式。
在这里插入图片描述

假设主服务器宕机,哨兵1先检测到这个结果,系统并不会马上进行failover过程,仅仅是哨兵1主观的认为主服务器不可用,这个现象称为主观下线,当后面的哨兵也检测到主服务器不可用,并且数量达到一定值时,那么哨兵之间就会进行一次投票,投票的结果由一个哨兵执行failover故障转移操作,切换成功后,就会通过发布订阅发布让各个哨兵把自己监控的从服务器连接到新的主机。

(3)测试

1.配置哨兵配置文件

## sentinel.conf配置文件中
 sentinel menitor myredis 127.0.0.1 6379 1

2.启动哨兵

redis-sentinel Yconfig/sentinel.conf 

在这里插入图片描述

如果主机宕机后,就会从从机选择一个(投票)变为主机,其他从机会自动连接到这个新的主机,同时配置文件也会发生修改。

哨兵日志
在这里插入图片描述
配置文件
在这里插入图片描述
3.如果主机又回来了,会自动变为从机。
在这里插入图片描述

(4)优缺点

1、优点

  • 哨兵模式就是主从复制的升级,手动到自动,更加健壮
  • 主从可以却换,故障可以转移,系统的可用性就会更好

2、缺点

  • Redis不好在线扩容的,集群容量一旦达到上限,在线扩容就十分麻烦!
  • 实现哨兵模式的配置其实是很麻烦的,里面有很多的选择
(5)哨兵模式的全部配置

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

3、缓存穿透

(1)什么是缓存穿透?

缓存穿透的概念很简单,用户想要查询一个数据,发现redis内存数据库没有,也就是缓存没有命中,于是向持久层数据库查询。发现也没有,于是本次查询失败。当用户很多的时候,缓存都没有命中,于是都去请求了持久层数据库。这会给持久层数据库造成很大的压力,这时候就相当于出现了缓存穿透。
注意:缓存击穿和缓存穿透是两个概念。

(2)解决方案
布隆过滤器

原理
很简单首先也是对所有可能查询的参数以hash形式存储,当用户想要查询的时候,使用布隆过滤器发现不在集合中,就直接丢弃,不再对持久层查询。

  • 布隆过滤器是由一个很长的bit数组和一系列哈希函数组成的。
  • 数组的每个元素都只占1bit空间,并且每个元素只能为0或1
  • 布隆过滤器还拥有k个哈希函数,当一个元素加入布隆过滤器时,会使用k个哈希函数对其进行k次计算,得到k个哈希值,并且根据得到的哈希值,在数组中把对应下标的值置位1。
  • 判断某个数是否在布隆过滤器中,就对该元素进行k次哈希计算,得到的值在位数组中判断每个元素是否都为1,如果每个元素都为1,就说明这个值在布隆过滤器中

为什么会有误判?

  • 当插入的元素越来越多时,当一个不在布隆过滤器中的元素,经过同样规则的哈希计算之后,得到的值在位数组中查询,有可能这些位置因为其他的元素先被置1了。
  • 所以布隆过滤器存在误判的情况,但是如果布隆过滤器判断某个元素不在布隆过滤器中,那么这个值就一定不在。
  • 如果对布隆过滤器的概念还不是很理解的话,推荐一篇博客,图文并茂好理解很多。详解布隆过滤器的原理、使用场景和注意事项
缓存空对象

原理

当存储层不命中后,即使返回的空对象也将其缓存起来,同时会设置一个过期时间,之后再访问这个数据将会从缓存中获取,保护了后端数据源;

该方法所产生的的问题

  • 如果空值能够被缓存起来,这就意味着缓存需要更多的空间存储更多的键,因为这当中可能会有很多的空值的键;
  • 即使对空值设置了过期时间,还是会存在缓存层和存储层的数据会有一段时间窗口的不一致,这对于需要保持一致性的业务会有影响。

4、缓存击穿

(1)概述

缓存击穿,是指一个key非常热点,大并发的集中对这一个点进行访问,但是当redis中这个点在一个瞬间失效(缓存过期)了,那么这些大并发的访问都会直接请求数据库,给数据库瞬间造成极大的压力。

(2)解决方案
  • 设置热点数据永不过期,
  • 后台定义一个job(定时任务)专门主动更新缓存数据.比如,一个缓存中的数据过期时间是30分钟,那么job每隔29分钟定时刷新数据(将从数据库中查到的数据更新到缓存中),这种方案比较容易理解,但会增加系统复杂度。比较适合那些 key 相对固定,cache 粒度较大的业务,key 比较分散的则不太适合,实现起来也比较复杂。
  • 使用分布式锁,保证在高并发情况下每次同时只有一个线程去查询数据库,其他线程没有获得分布式锁的权限,其余的进行等待,这样就将高并发的压力转移到了分布式锁。

5、缓存雪崩

(1)概述

缓存雪崩是指,缓存层出现了错误,不能正常工作了。于是所有的请求都会达到存储层,存储层的调用量会暴增,造成存储层也会挂掉的情况。
在这里插入图片描述

(2)解决方案
  • 搭建集群,既然redis有可能挂掉,那我多增设几台redis,这样一台挂掉之后其他的还可以继续工作
  • 限流降级,在缓存失效后,通过加锁或者队列来控制读数据库写缓存的线程数量。比如对某个key只允许一个线程查询数据和写缓存,其他线程等待
  • 数据预热,数据加热的含义就是在正式部署之前,我先把可能的数据先预先访问一遍,这样部分可能大量访问的数据就会加载到缓存中。在即将发生大并发访问前手动触发加载缓存不同的key,设置不同的过期时间,让缓存失效的时间点尽量均匀。
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值