刚刚看到个会使用redis的帅哥拿到了上万,我很是不服,我这不但会使用redis还会配置redis,而且会redis集群,主从复制,哨兵模式和解决缓存穿透、缓存击穿和缓存雪崩等问题,重点重点我还是小鲜肉,你们大家说说我这是不是最低也待18k起步啊(小声逼逼:我可没多要,也就要了18k)
今天还是和大家分享下redis的知识,包括redis配置,redis集群搭建,主从复制,哨兵模式讲解,缓存穿透、缓存击穿和缓存雪崩的问题,闲话少说,趁着这个工作休息缝隙,赶紧给大家扔干货。
一、redis的配置文件redis.conf
声明:我所使用的是linux中的redis,因此所分享的redis内容全部基于linux服务器上的,麻烦大家注意一下。
1、首先找到redis的配置文件,进入编辑模式,命令如下:vim /usr/redis/conf/redis.conf。port 6379:代表redis启动时的端口号,默认6379,当然大家也可以修改成自己的。
2、daemonize yes:这个代表守护线程是否开启,当为yes时,说明守护线程开启,在该模式下,redis会在后台运行,除非手动kill该线程;为no时,exit会强制退出或者关闭连接工具都会导致redis进程退出。
3、pidfile /var/run/redis_6379.pid:这里代表是进程号,不过多详述。
4、databases 16:默认开启16个数据库,编号从0-15。
5、logfile “6379.log”:日志文件名称,为6379.log
6、save 900 1:在rdb持久化中代表每900s中更改1次就会出发rdb保存机制。
save 300 10:代表在300s内更改10次,那么就会触发rdb机制。
save 60 10000:代表在60s内更改10000次,那么就会触发rdb机制。
当然大家也可以进行修改成适合自己的,一般情况下不建议进行修改。
7、dbfilename dump.rdb:代表生成rdb文件名称,自己也可以进行修改。
8、dir “/usr/local/bin”:文件存储文件夹的位置。
9、appendonly no:开启aof快照模式,yes代表开启,no代表关闭。
10、appendfilename “appendonly.aof”:代表aof快照文件名称。可以自己进行更改。
11、appendfsync everysec:代表每秒记录一次;里面也可以设置成其它的,有一直记录和从不记录。
PS:大家可以根据自己的实际情况进行修改,不必须的修改尽量不要修改,还是按照默认的配置来。还有在启动的时候,大家按照redis-server kconfig/redis79.conf 这样代表以redis79.conf配置文件进行启动的redis。
二、redis持久化rdb操作
RDB(redis database)其实就是以快照的形式保存在磁盘上。快照可以理解为把当前时刻的数据拍成一张照片保存下来。
RDB持久化是指在指定的时间间隔内将内存中的数据集快照写入磁盘。也是redis默认持久化机制,这种方式是以快照的形式将内存中的数据集写入到二进制文件中,默认的文件名称为dump.rdb。
RDB持久化的触发机制在redis中提供了三种触发机制,分别为:save、bgsave和自动化。
这三种触发机制,我们在这里只讲最后一种哈,前两种基本上用不到。
自动触发是由我们的配置文件中配置来完成的,在redis.conf配置文件中有save m n,代表在m秒内进行n次修改将触发bgsave。
配置文件中的默认配置为:save 900 1:在rdb持久化中代表每900s中更改1次就会出发rdb持久化机制。
save 300 10:代表在300s内更改10次,那么就会触发rdb持久化机制。
save 60 10000:代表在60s内更改10000次,那么就会触发rdb持久化机制。
不需要持久化的话可以直接将save m n直接注释掉即可。
RDB优点和缺点:
优点:1:RDB文件紧凑,全量备份,非常适合用于进行备份和灾难恢复。
2:生成RDB文件时,主进程会fork()一个子进程来处理所有保存工作,主进程不需要进行任何磁盘IO操作。
3:RDB在恢复大量数据集时的速度要比AOF快,因为AOF文件保存的是所有操作redis的语句,当进行数据恢复的时候,它需要把所有语句进行重新跑一遍,当几十万上百万条语句需要跑一遍的时候,时间你可想而知。
4:如果你想最大限度的避免数据丢失,那么采用RDB是一个不太好的选择,如果redis宕机了,那么没有记录到rdb文件的数据就会丢失。因此数据的高可用不太好。
三、redis持久化aof操作
aof(append only file)是redis更高效的数据备份方式,工作机制比较简单。redis会将收到的每一个写命令和删除命令都会通过write函数追加到aof文件中,通俗的可以理解为日志记录。持久化原理如下图所示:
aof文件中只记录写和删除命令,查询命令不会记录。
aof重写原理:持久化文件会变的越来越大。为了压缩aof的持久化文件。redis提供了bgrewriteaof命令。将内存中的数据以命令的方式保存到临时文件中,同时会fork出一条新进程来将文件重写。
重写aof文件的操作,并没有读取旧的aof文件,而是将整个内存中的数据库内容用命令的方式重写了一个新的aof文件,这点和快照有点类似。
三种触发机制:
每次修改同步:同步持久化 每次发生数据变更会被立即记录到磁盘 性能较差但数据完整性比较好
每秒同步:异步操作,每秒记录 如果一秒内宕机,有数据丢失
不同步no:从不同步
优点:
1、AOF更好的保护数据,一般是一秒钟同步数据一次,也就是说即使数据丢失,最多也就丢失1s的数据。
2、写入性能比较高,文件不容易损坏。
3、AOF日志文件通过非常可读的方式进行记录,这个特性非常适合做灾难性的误删除紧急恢复。比如flushall命令,将数据全部清空,打开aof文件,删除flushall命令,通过恢复机制,自动恢复数据即可。
缺点:
同一份数据,AOF日志文件会比RDB数据快照大的多。RDB 在恢复大数据集时的速度比 AOF 的恢复速度要快。
**注意:**当RDB和AOF同时存在的情况下,redis会以AOF为准。
四、redis集群环境搭建和主从复制
主从是指将一台redis服务器的数据,复制到其他redis服务器中去;前面的服务器称为主节点(master/leader),后者服务器称为从节点(slave|follower);master主要是写,slave主要是读,80%的情况下都是进行读,减轻服务器压力。(一个主节点有多个从节点,一个从节点只能有一个主节点。类似:一个爸爸可以有多个儿子,一个儿子只有一个爸爸)
主要作用:
1、数据冗余:主从复制实现了数据备份,是持久化之外的另外一直数据备份。
2、故障恢复:当主节点出现宕机时,可以由从节点提供服务,实现快速数据恢复;实际上是一种服务的数据冗余。
3、负载均衡:在主从复制的基础上,配合读写分离,可以由主节点提供写服务,从节点负责读服务,分担服务器负载,在写少读多多的环境下,通过多个从节点分担读的压力,从而提高redis服务器的并发量。
4、高可用基石:主从复制还是哨兵和集群能够实施的基础,因此说主从复制是高可用的基石。
注意: 数据复制是单向,只能由主节点往从节点中进行复制,不能反向。
在集群中,最低需要三台服务器,一主二从,因为哨兵模式中会有一个当主服务器出现问题时,会在从服务器中选取一个从服务器当做主服务器。单台服务器最大使用内存不应该超过20G,
集群环境配置: 只配置从库,不需要配置主库,因为redis的6379端口就是默认主库。
第一步:将redis.conf文件复制三个,并进行修改配置文件内容。
1、复制三份redis.conf配置
2、更改相对应的配置文件,包括:端口号、开启守护线程、设置进程号、设置日志文件名称、设置rdb和aof持久化名称。
3、开始启动各个服务器。
4、启动redis客户端,并且查看该服务器的配置信息
注意: 默认情况下,每一台redis服务器都是主节点。一般情况下只需要配置从机即可,也就是认老大。
配置:在从机中配置(找老大):slaveof 127.0.0.1 6379
查看从节点信息:
主节点信息:
当然配置从机时也可以在从机配置文件中进行配置,配置步骤如下:
注意: 主机只能写,从机只能进行读。主机的所有信息和数据都能被从机保存。
复制原理:
Slave启动成功连接到master后会发送一个sync命令
Master接到命令,启动后台的存盘进程,同时收集所有接收到用于 修改数据命令,在后台进程执行完毕之后,master会将整个数据文件到slave,并完成一次完全同步
全量复制:salve服务在接收到主节点数据库文件数据后,并将存盘加载到内存中。
增量复制:Master继续将新的所有收集到的修改命令依次传给slave,完成同步
但是只要重新连接master,一次完全同步将被自动执行。
五、哨兵模式
哨兵模式:通俗的可以理解为自动选取老大,当主服务器宕机出现问题时,将根据投票数自动选取从库将该从库变为主库。哨兵是一个独立的进程,作为进程可以独立运行。 哨兵发送命令,等待redis服务器响应,从而监控运行的多个redis实例。
哨兵的两个作用:
1、通过发送命令,让Redis服务器返回监控其运行状态,包括主服务器和从服务器。
2、当哨兵监测到master宕机,会自动将slave切换成master,然后通过发布订阅模式通知其他的从服务器,修改配置文件,让他们切换主机。
然而一个哨兵进程对Redis服务器进行监控,可能会出现问题,为此,我们可以使用多个哨兵进行监控。各个哨兵之间还会进行监控,这样就形成了多哨兵模式。
假设主服务器宕机,哨兵1先监测到这个结果,系统并不会马上进行failover过程,仅仅是哨兵1主观认为主服务器不可用,这个现象称为主观下线,当后面的哨兵也监测到主服务器不可用,并且数量达到一定值时,那么哨兵之间就会进行一次投票,投票的结果由一个哨兵发起,进行failover故障转移,就会通过发布订阅模式,让各个哨兵把自己监控的从服务器实现切换主机,这个过程称为客观下线。
设置哨兵模式,编写sentinel.conf哨兵配置文件,步骤如下:
注意:刚刚哪一行少写个属性,完整的哨兵设置语句应该是
sentinel monitor myredis 127.0.0.1 6379 1
这个最后的 1 忘写了,1代表的是当监测的主服务器挂了之后,会进行投票选择一个从服务器为主服务器。
启动哨兵:
在哨兵模式启动后,如果主节点宕机了,那么哨兵会进行投票随机选举一台从节点为主节点(这里有一个投票算法)。
如果主机再回来,那么只能当从机,不会再当主机。
优点:
1、哨兵集群基于主从复制模式,所有主从复制的优点它都有。
2、主从节点可以切换,故障转移,系统的可用性好。
3、哨兵模式就是主从模式的升级,由手动配置变为自动配置。
缺点:
1、Redis不好在线扩容,集群容量一旦达到上限,在线扩容就会很麻烦。
2、实现哨兵模式的配置其实很麻烦,里面有很多选择。
哨兵模式全部配置:
基础配置
protected-mode no #关闭保护模式
port 26479 #端口
daemonize yes #使用后台模式启动
pidfile “/var/run/redis-sentinel_26479.pid” #进程id文件
logfile “/usr/local/redis/sentinel/sentinel_26479.log” #日志文件
dir “/usr/local/redis/sentinel” #工作目录
核心配置
1、sentinel monitor < master-name> < ip> < port> < quorum>
master-name:redis主节点昵称。
ip:redis主机ip。
port:redis主机端口。
quorum:哨兵判断主节点是否发生故障的票数。如果设置为2,表示2个哨兵节点认为主节点发生了故障,一般设置为:哨兵节点数/2+1。
2、sentinel down-after-milliseconds < master-name> < times>
哨兵会定期的向redis节点发送ping命令来判断redis是否可达,若超过指定的times毫秒内还未得到pong回复,则判读该redis不可达。
3、sentinel parallel-syncs < master-name> < nums>
当redis主节点挂了后,哨兵会选出新的master,此时,剩余的slave会向新的master发起同步数据,这个设置表示允许并行同步的slave个数。
4、sentinel failover-timeout < master-name> < times>
进行故障转移时,如果超过设置的times毫秒,表示故障转移失败。
5、sentinel auth-pass < master-name> < password>
如果redis主节点设置了密码,则需要进行这个配置。
六、缓存穿透、缓存击穿和缓存雪崩
这里我简单介绍下这三种情况和大致解决问题思路,不做过多详述,后期详细研究解决方案之后再进行补充。
1、缓存穿透:在使用缓存的情况下,我们查询数据时会先查询缓存,假如缓存中不存在,那么就会在数据库中查询,数据库中查询到的话会将查询的数据返回而且会将数据暂存在缓存中一份。缓存穿透可以理解为查询数据,这个时候缓存中不存在,然后进行去数据库中查询,数据库中也不存在。当查询数据过多时,查询数据压力全部扔给了数据库,这个时候数据库不堪压力,给崩掉了,这个时候就是缓存穿透。可以人为的利用这个漏洞进行去攻击。
解决方法:可以采用布隆过滤器(这里不再详述,后期深入研究后进行补充),或者去数据库中查询,数据库中不存在,返回不存在同时在缓存中暂存为null值,这样等下次再来查询时就不需要再走刚刚的那重复步骤去数据库中查询,可以减轻数据库压力。
2、缓存击穿(量太大,缓存过期):缓存穿透和缓存击穿的区别是,缓存穿透是缓存中没有这个key,然后进数据库进行查询,但是数据库中也查询不到,在持续抗高并发,持续大量的去访问不存在的数据库,那么数据库不堪压力,最终挂掉;缓存击穿同样是把缓存当作一堵墙,所有火力打在这堵墙上的某一个点上,把这个墙上的这一点给穿透,然后大量的火力通过这堵墙的这一点打在数据库上,这时候数据库不堪压力,然后给崩掉。用官方话可以说:当缓存中的一个key值是非常热点,不停的抗高并发,高并发数据集中对这个key进行访问,当key值失效的瞬间,会同时访问数据库来访问数据,导致数据库压力过大,数据库瞬间崩掉。例如微博中当某某明星出轨时,是一个非常热的热点,当key失效时,数据库受不了压力就会挂掉。这个时候就是我们常称为微博因某某明星出轨给挂掉了。
解决方案:1、设置key值永不过期;2、加互斥锁,只保证只有一个线程能够进去访问数据库,其余都进行等待。
3、缓存雪崩:在一段时间段内,缓存集中过期失效,Redis宕机。例如:双十一期间,凌晨十二点开始抢购,key值的有效期是一个小时,那么在凌晨一点的时候,会失效,那么压力全部打在了存储层,这个时候服务器就会造成周期性压力。
解决方案:1、利用redis的高可用性,多准备几台服务器,也就是异地多活,当其中一台服务器挂了,那么其他redis服务器可以进行工作,也就是搭建集群。
2、限流降级,在缓存失效之后,通过加锁或者队列来控制数据库写缓存的数量,比如某一个key只能允许一个线程查询和写缓存,其他线程等待。
3、缓存预热,在正式部署之前,先把可能的数据先预先访问一遍,这样大部分的数据加载到缓存中。
暂且结束redis,有好的知识点再进行添加,大家有疑问的可以在下方留言,欢迎大家一起探讨。静下心,在学习中成长,在成长中学习。