概念:用户需要查询一个数据,发现Redis中没有,也就是缓存没有命中,于是就向持久层数据库发起查询,发现也没有这个数据,于是本次查询失败
当用户很多的情况,缓存没有命中,又回去请求数据库,这就会给数据库造成很大的压力,这个就是缓存穿透
布隆过滤器是一种算法,是用户检测一个元素是否在一个集合中,存在一定的误差
可以将所有可能查询的参数以hash形式来进行存储,在控制层进行校验,不符合的则丢弃,从而避免对数据库的查询压力
当存储层不命中时,及时返回一个空对象也将其缓存起来,同时会设置一个过期时间,之后在访问这个数据会从缓存中获取,既能保证数据的有效性也能保护后端数据库
注意:存在问题
及时对缓存设置了过期时间,还是会有缓存和数据库数据不一致的窗口期,对于需要保持一致性的业务会有影响
概念:缓存击穿,指一个key非常热点,在不停的扛着大量的并发,当这个key在失效的期间,持续的大并发的请求就会穿破缓存,直接请求数据库,当key在过期的瞬间,大量的请求并发访问,会同时访问数据库来查询最新的数据,回写到内存,会导致数据库压力瞬间增大。
业界比较常用的做法,是使用mutex。简单地来说,就是在缓存失效的时候(判断拿出来的值为空),不是立即去load db,而是先使用缓存工具的某些带成功操作返回值的操作(比如Redis的SETNX或者Memcache的ADD)去set一个mutex key,当操作返回成功时,再进行load db的操作并回设缓存;否则,就重试整个get缓存的方法。
从换存储层面看,没有设置过期时间,所以不会出现热点key过期后造成的数据库压力
概念:指在某一个时间段,缓存集中过期失效
集中过期,并不是致命问题,比较致命的是,是缓存服务器在某个节点宕机或者断网,一定的时间段内,数据库的压力聚增,对数据库的压力是不可预估的,很有可能就把数据库压宕机了
单个Redis可能会挂点,多增设几台Redis,这样一台挂掉之后其他的也可以继续服务,就是搭建缓存服务器集群(异地多活)
在缓存失效后,通过加锁或者队列来控制读写数据库的线程数量,比如对某个key只允许一个线程查询数据和写缓存,其他线程等待
在部署之前,先将可能的数据先预先访问一遍,这样部分大量访问的数据就会加载到缓存 中,在即将发生大并发前手动书法加载缓存不同的key,社会不同的过期时间,让缓存失效的时间尽量均匀
主从复制:
指的是一个Redis服务器的数据,复制到其他的Redis服务器,前者称之为主节点(mater/leader),后者称之为从节点(slave/follower),数据的复制是单向,只能是从主节点到从节点,master以写为主,Slave节点以读为主
默认情况,每台Redis服务器都是主节点,且一个主节点可以有多个从节点(或者没有从节点),但是一个从节点只能有一个主节点
配置环境主要配置从库,不需要配置主库
redis.conf
复制redis.conf配置文件,修改对应信息 slaveof host ip
1、端口号
2、pid文件名
3、dump.rdb名称
1)在上面的全量同步过程中,master会将数据保存在rdb文件中然后发送给slave服务器,但是如果master上的磁盘空间有效怎么办呢?那么此时全部同步对于master来说将是一份十分有压力的操作了。此时可以通过无盘复制来达到目的,由master直接开启一个socket将rdb文件发送给slave服务器。(无盘复制一般应用在磁盘空间有限但是网络状态良好的情况下)
2)主从复制结构,一般slave服务器不能进行写操作,但是这不是死的,之所以这样是为了更容易的保证主和各个从之间数据的一致性,如果slave服务器上数据进行了修改,那么要保证所有主从服务器都能一致,可能在结构上和处理逻辑上更为负责。不过你也可以通过配置文件让从服务器支持写操作。(不过所带来的影响还得自己承担哦。。。)
3)主从服务器之间会定期进行通话,但是如果master上设置了密码,那么如果不给slave设置密码就会导致slave不能跟master进行任何操作,所以如果你的master服务器上有密码,那么也给slave相应的设置一下密码吧(通过设置配置文件中的masterauth);
4)关于slave服务器上过期键的处理,由master服务器负责键的过期删除处理,然后将相关删除命令已数据同步的方式同步给slave服务器,slave服务器根据删除命令删除本地的key。
在进行主从复制设置时,强烈建议在主服务器上开启持久化,当不能这么做时,比如考虑到延迟的问题,应该将实例配置为避免自动重启。
为什么不持久化的主服务器自动重启非常危险呢?
为了更好的理解这个问题,看下面这个失败的例子,其中主服务器和从服务器中数据库都被删除了。
设置节点A为主服务器,关闭持久化,节点B和C从节点A复制数据。
这时出现了一个崩溃,但Redis具有自动重启系统,重启了进程,因为关闭了持久化,节点重启后只有一个空的数据集。
节点B和C从节点A进行复制,现在节点A是空的,所以节点B和C上的复制数据也会被删除。
当在高可用系统中使用Redis Sentinel,关闭了主服务器的持久化,并且允许自动重启,这种情况是很危险的。
比如主服务器可能在很短的时间就完成了重启,以至于Sentinel都无法检测到这次失败,那么上面说的这种失败的情况就发生了。
如果数据比较重要,并且在使用主从复制时关闭了主服务器持久化功能的场景中,都应该禁止实例自动重启。
如果设置了一个从服务器,在连接时它发送了一个SYNC命令,不管它是第一次连接还是再次连接都没有关系。
然后主服务器开始后台存储,并且开始缓存新连接进来的修改数据的命令。当后台存储完成后,主服务器把数据文件发送到从服务器,从服务器将其保存在磁盘上,然后加载到内存中。然后主服务器把刚才缓存的命令发送到从服务器。这是作为命令流来完成的,并且和Redis协议本身格式相同。
你可以通过telnet自己尝试一下。在Redis服务器工作时连接到Redis端口,发送SYNC命令,会看到一个批量的传输,并且主服务器接收的每一个命令都会通过telnet会话重新发送一遍。
当主从服务器之间的连接由于某些原因断开时,从服务器可以自动进行重连接。当有多个从服务器同时请求同步时,主服务器只进行一个后台存储。
当连接断开又重新连上之后,一般都会进行一个完整的重新同步,但是从Redis2.8开始,只重新同步一部分也可以。
默认的情况下,每台Redis服务器都是主节点,主要来配置从节点
链路模式:
配置从机
Slaveof hots port(找主机)
(启动三个redis服务器:6379,6380,6381,配置6379为主节点,6380和6381位从节点)
查看主机信息
当前的命令行的配置是临时的,想配置永久化,需要在redis.conf配置文件中增加slaveof 这行配置信息
主机可以写,从机是可以读不能写,主机中的所有的信息和数据,都会保存到从机中
主机写:
从机只能读不能写:
自动选取主机(老大)的模式
哨兵: 模式主要就是解决主从模式下,主服务器宕机后,从服务器需要人工干预,造成一段时间的不可用的问题,Redis从2.8版本提供了sentinel(哨兵)模式
哨兵模式能够监控主机是否故障,如果发生故障就根据投票自动的将从库转为主库
Redis中提供了哨兵命令,哨兵是一个单独的进程,独立的运行,用来监控Redis服务器,哨兵发送命令,等待Redis服务器的响应,可以监听多个Redis的实例
1、发送命令,让Redis服务器返回运行状态,包括主服务器和从服务器
2、当哨兵检测到master宕机,会自动将Slave切换为master,然后通知其他的从服务器,来修改配置文件,即切换主机
单个哨兵进程会存在单点故障问题,因此为了解决该问题,可以使用多个哨兵进行监控,各个哨兵之间还会进行监控,多哨兵模式
多哨兵模式:
假设主服务器宕机,哨兵1首先检测到这个结果,系统并不会立即进行主从切换,仅仅是哨兵1主观的认为主服务器不可用,这个现象称之为主观下线。当其他的哨兵也检测到了主服务器不可用用,当数量达到一定值,那么哨兵就会进行一次投票,投票结果又一个哨兵发起,进行故障转移操作,即由一个哨兵通知其他哨兵和服务器进行从服务器切换为主服务器的过程,切换成功后,让各个哨兵将监控的从服务器切换为主机,这个过程称之为客观下线;
配置的就是哨兵模式的信息
sentinel monitor <master-name> <ip> <redis-port> <quorum> sentinel monitor mymaster 127.0.0.1 6379 2 master-name:主机名称 ip: redis-port:主机的端口 quorum:配置多少个sentinel
启动哨兵: redis-sentinel sentinel.conf
优点:
1、哨兵集群,基于主从复制模式,所有的主从配置优点,它都有
2、主从可以切换,故障可以转移,高可用性的系统
3、哨兵模式就是主从模式的升级,手动到自动,更加健壮
缺点:
1、Redis不好在线扩容的,集群容量一旦到达上限,在线扩容就十分麻烦
2、哨兵模式的配置繁琐