Redis(五)—— Redis进阶部分

阅读: 评论:0

Redis(五)—— Redis进阶部分

Redis(五)—— Redis进阶部分

一、Redis配置文件详解

        注意这是Redis服务本身的配置文件,相当于maven的l,而不是我们在springboot去配置Redis的那个l。

========================核心部分======================include 引入其他redis配置文件,相当于spring的<import>bind 设置IP,默认是127.0.0.1protected-mode yes  是否开启保护模式,默认开启daemonize yes 是否以守护进程方式运行redis,默认是no,我们将其改为yespidfile /../../..pid  既然是守护进程,就指定这个守护进程的pid文件loglevel  日志级别,有好多种日志级别logfile 指定日志文件的位置databases 16  默认数据库16个always-show-logo yes  这个很有意思,就是开启redis服务的时候会不会打印图标(和springboot的那个图标一回事)==============SNAPSHOP快照部分(用于RDB持久化的配置)===============
save 900 1  900s内修改一次,这是最低标准save 300 10 save 60 10000 设置多长时间、多少次修改持久化一次,60s内修改1万次进行一次持久化stop-writes-on-bgsave-error yes 持久化出错后,是否继续工作rdbcompression yes 是否要压缩rdb文件,默认是压缩rdbchecksum yes 保存rdb文件的时候是否检查文件错误dir ./  rdb文件和aof文件的保存目录(RDB和AOF保存在相同目录下,都通过dir指定)===============REPLICATION主从复制用到的配置=======================
下次再讲========================SECURITY安全配置========================
requirepass 123456 设置密码=====================CLIENT 对客户端的限制(不用动,了解即可)=======
maxclients 10000  最多可以连接redis-server的客户端数量maxmemory  redis的最大运行内存maxmemory-policy redis要超过最大运行内存了怎么办?同JUC的6个策略(1-6从谨慎到发疯)# 1. noeviction 一个都不能删,直接返回redis运行内存不够了这个错误# 2. volatile-lru 只对设置了过期时间的key进行LRU# 3. allkeys-lru 对所有 key进行LRU# 4. valatile-ttl 删除即将过期的key# 5. volatile-random 随机删除即将过期的key# 6. allkeys-random 随机删除key  
=================APPEND ONLY AOF持久化配置================
appendoNly no 默认不开启AOF持久化,默认使用RDB方式持久化,因为RDB在大部分情况下就够用了appendfilename AOF持久化文件名appendfsync always/everysec/no  # 每次修改都sync,消耗性能/每秒一次sync,可能会丢失这1s的数据/不执行sync,这个时候操作系统自己同步数据,速度最快

在redis中查看密码的命令:

cj:0>config  get requirepass
1) "requirepass"
2) "CsiFlow!@#680"

二、持久化

PS :RBD类比undolog(MVCC里的历史版本记录,记得不?),AOF可以类比mysql的binlog去看

持久化的原因: 

        redis必须持久化吗?对啊!redis是内存数据库,不持久化的话断电即失!但“断电”这只是redis需要持久化的其中一个原因。一共有两个原因:

  • 重用数据(比如重启机器、机器故障之后恢复数据)
  • 或者是为了做数据同步(比如 Redis 集群的主从节点通过 RDB 文件同步数据)

3 种持久化方式

Redis 不同于 Memcached 的很重要一点就是,Redis 支持持久化,而且支持

  • 快照(snapshotting,RDB)
  • 只追加文件(append-only file, AOF)
  • RDB 和 AOF 的混合持久化(Redis 4.0 新增)

2.1 RDB 持久化

  • Redis 可以通过创建快照来获得存储在内存里面的数据在 某个时间点上的副本。Redis 创建快照之后,可以
    • 将快照复制到主从结构其他服务器从而创建具有相同数据的服务器副本
    • 将快照留在原地以便重启服务器的时候使用。
  • RDB持久化的过程跟浏览器下载文件的过程一样, 先在dir指定的路径下创建一个dump.rdb文件,往里写入数据,写完后替换上次的dump.rdb文件(区别于AOF的“追加”)。
  • 持久化了以后怎么用?全自动的!只要dump.rdb文件放在redis开启目录下,redis每次开启时都会开机自检核对数据
  • 持久化是 Redis 默认采用的持久化方式,在 配置文件中默认有此下配置(不用改,默认的就很好用)
save 900 1           #在900秒(15分钟)之后,如果至少有1个key发生变化,Redis就会自动触发bgsave命令创建快照。save 300 10          #在300秒(5分钟)之后,如果至少有10个key发生变化,Redis就会自动触发bgsave命令创建快照。save 60 10000        #在60秒(1分钟)之后,如果至少有10000个key发生变化,Redis就会自动触发bgsave命令创建快照。

1、触发RDB的时机 

       上面save设置了触发RDB的时机,但这并不是全部的时机。

  1. flushdb、flushall命令会自动触发RDB(所以可以推出,执行完flush命令以后如果后悔了其实是可以回滚的是吗?)
  2. 满足上面save规定
  3. 关掉redis时

2、RDB 创建快照时会阻塞主线程吗?

        redis是单线程的,但是在进行持久化的时候会fork一个子线程/子进程,专门进行持久化操作,主线程照样运行其他命令。

Redis 提供了两个命令来生成 RDB 快照文件:

  • save : 同步保存操作,会阻塞 Redis 主线程;
  • bgsave : fork 出一个子进程/线程,子进程执行,不会阻塞 Redis 主线程,默认选项。

2.2 AOF 持久化

  • 只记录写命令,不记录读命令,和binlog一样。恢复数据的时候把所有命令都执行一遍
  • 过 appendonly  yes参数开启,其他配置都不用动
  • 文件名:appendonly.aof

2.3 二者的选择与比较

能说出这仨点即可

  • RDB运行效率更高,所以RDB是redis默认开启的,AOF默认不开启
  • AOF的安全性更高。但是效率是牺牲数据的实时性带来的,AOF可以用sync命令去设置每次修改都同步,或者每秒同步,但是RDB只能用save命令设置多少秒同步,不能精确到每一条命令。试想我们设置一个save 60 10000,60s内发生一万次修改的时候持久化到硬盘,但是如果还没到60s,发生第9999次修改后宕机了,那这9999次修改就丢失了。但AOF也不是完全安全的哦,因为AOF默认开始的是每秒同步,但是如果这1秒没来及同步就宕机了,就会丢失这1秒的数据。当然如果你开启每条命令同步,那就是绝对安全的了。
  • RDB恢复速度更快。RDB存储的是数据库快照,而AOF就和mysql的binlog一样,存储的是一条条执行过的命令。如果要恢复大规模数据,RDB直接拷贝快照,但是AOF要一条条执行命令,你想想哪个快?

2.4 rdb或aof文件被破坏怎么办?

aof文件是可以打开的,比如说我们打开文件以后,往里面随便敲点东西。那么下次redis开机会直接开不了

解决:调用redis提供的redis-check-aof工具修复aof文件。

综上

  • 如果Redis 保存的数据丢失一些也没什么影响的话,可以选择使用 只用RDB。
  • 不建议单独使用 AOF,因为RDB确实牛哇!时不时地创建一个 RDB 快照可以进行数据库备份、更快的重启以及解决 AOF 引擎错误。
  • 如果企业对保存的数据要求安全性比较高的话,建议同时开启 RDB 和 AOF 持久化或者开启 RDB 和 AOF 混合持久化

所以,要么单独使用RDB,要么使用RDB+AOF,要么使用混合策略,就是不能单独使用AOF!

三、Redis发布订阅

        底层如何实现发布订阅逻辑:redis是用C语言写的,发布与订阅的功能在pubsub.c这个文件里,想看源码的可以去看。

        三个命令:

  • subscribe 频道名
  • publish 频道名
  • unsubscribe 频道名

应用场景

        redis的消息中间件功能只用于简单场景,复杂场景的话我们用rocketMQ,卡夫卡这种专业的消息中间件去做。

        除了推送公众号这种显而易见的发布订阅,聊天室可以用redis实现吗?

可以!管理者(我自己瞎起的名字)作为发布者,所有聊天室的人作为订阅者。要想做到每一个发送的聊天信息都能被所有人收到,那就要先发给管理者,然后由管理者推送给所有订阅者。就是多了先“发给管理者”这一步而已

四、Redis主从复制

  • redis主从复制跟MYSQL的主从复制是一模一样的,都是主机能读能写,从机只能读
  • 任何项目中都不可能只用一台redis!主要原因是因为redis会宕机,次要原因是性能瓶颈,没法实现负载均衡
  • 最低配置是一主二从,其实技术上来讲一主一从是可以的,但是由于redis的哨兵模式,当主机挂掉了并且只有一个从机的时候,是没办法进行选举的,所以在redis里,集群的最低配就是一主二从。
  • 默认情况下,每个redis服务都认为自己是主节点。就要让他低头认老大,变成从节点

4.1 集群搭建

在一台机器上开三个redis服务/进程/程序,占用3个不同的端口号(当然也可以开在不同的机器上哈)

4.2 配置一主二从

        和docker“数据卷容器”实现多个容器之间的数据同步,“通过docker run --volumes-from docker01挂载了docker01,那么docker01就是docker02的父容器”的思想是一样的。

://blog.csdn/qq_44886213/article/details/127844443

  • 永久方法(一)在配置文件中进行配置,只需要配置从机就行,这是永久的,也是实践中真实采用的。
  • 临时方法(二)用SLAVE命令 ,只需要配置从机就行,这是临时的,测试的时候用一下

                

  • 用set命令向主机中写一个key,从机中就能查出来了,底层是用RDB实现的?同步的吗??
  • 临时配置主从和永久配置主从带来的区别:
    • 主机断了无区别:一主二从模式下,主机宕机了怎么办?因为我们没有配置哨兵模式,所以不会选举新的主机,就干等着主机回来,或者用SLAVEOF no one命令手动配置一个新主机,这就是“谋朝篡位”。主机回来以后自动连接上他的两个从机(经测试,主机断开后再连接,然后set一个新的值,从机是能拿到这个新值的,说明主机回来以后自动建立起和从机的链接)。
      • “谋朝篡位”特别形象。因为一旦主机走了之后上任了新主机,那么原来的主机回来以后也失去了地位,所以“谋朝篡位”很形象!
    • 从机断了有区别:当从机断开连接后,再次回来的时候。如果使用命令行方式临时配置的,那么回来的从机又变成主机了,相当于和主机断开连接。但是如果是用配置文件配置的,回来的时候依然是从机。原因在于redis启动的时候会读配置文件
      • 如果是用临时方式配置的,从机回来以后成为主机,我们再将其用SLAVE命令变成从机,能拿到之前的命令吗?能啊!别被绕进去。因为主从复制拷贝的是主机的全部数据,主机和从机的数据完全一致的
  • 一个奇思妙想:

        如果是下图这种关系(当然生产实际不会用这种的哈,只是一个奇思妙想),把6380配成6379的从机,把6381配成6380的从机。那么6380的身份到底是主机还是从机呢?

我们用info replication命令去查,发现6380的role是从机。那么当6379宕掉时,6380会成为主机执行写操作吗?不可以!

五、哨兵模式——投票选举

5.1 原理

        一句话描述哨兵模式:在前面的描述里,主从模式下当主机宕掉后,我们用SLAVEOF no one命令手动配置新主机,叫做手动的“谋朝篡位”。一句话理解哨兵模式——自动版“谋朝篡位”。

        6个进程:哨兵是单独开的一个进程,这个进程和redis服务并列关系(类似于QQ和QQ管家之间的关系),不是多进程关系哦。还是以一主二从为例,这个哨兵定期向三台redis服务发送ping(心跳命令) 命令,看看有没有人回复PONG,没有回复就认为它挂了。这里有一个问题,万一哨兵自己挂了怎么办?所以哨兵模式采用多哨兵一共安排了3个哨兵,也就是说我们在一主二从的模式下一旦采用了哨兵模式,就至少开了6个进程。

        主观下线,客观下线:

        简单来说主观下线就是1个哨兵认为redis服务宕机了,只有1个哨兵这样想,这是主观的;客观下线就是3个哨兵哨兵经过一系列确认操作,确认redis服务确实挂掉了。

        假如现在master偷摸自己挂掉了,当哨兵1定时给master发送PING命令时,发现master没有回复PONG命令,哨兵1就主观认为master挂掉了,但是哨兵1不会马上发起选举操作,因为还要拉其他两个哨兵进行客观下线的确认。当哨兵2和哨兵3给master发PING命令也得不到回复时(注意不是发一次,而是累积多次PING),累积达到一定次数,就认为客观下线。那么此时就发起选举,这个选举可能是由哨兵1,哨兵2,哨兵3任何一个发起的(比如说我们设置累积10次PING得不到回复就认为master客观下线,那么第10次PING是哪个哨兵发起的,就由哪个哨兵发起选举)。

        投票算法

如何选举新主机?投票!下面讲一下投票算法。

5.2 实操——如何使用哨兵模式?

redis已经给我们准备好了!

之前说过,哨兵是单独开的一个进程,这个进程和redis服务并列关系,在这里:

如果要开启哨兵模式,就要按照以下步骤

(1)vim命令新建并编写哨兵配置文件conf文件

(2)运行哨兵进程

(3)测试选举

master崩了到选举出新master是一个动态的过程,建议看视频10:00左右

34、哨兵模式详解_哔哩哔哩_bilibili34、哨兵模式详解是【狂神说Java】Redis最新超详细版教程通俗易懂的第34集视频,该合集共计36集,视频收藏或关注UP主,及时了解更多相关视频内容。=34&vd_source=4e5addbe07f6c2c1f970580da6513dd6

  5.3 哨兵模式的优缺点

优点:

  • 高性能——负载均衡:主从模式的优点它都有
  • 高可用:master挂掉进行failover故障转移,重新选举master,保证了系统的高可用
  • 健壮性:哨兵模式实现自动的‘谋权篡位’,一改之前的手动模式,“自动”便是增加了系统的健壮性

缺点:

  • 别看我们上面就配置了一行,但是实际上哨兵模式的配置很麻烦的

六、缓存穿透和雪崩(面试高频,工作常用)

再也不怕,缓存雪崩、击穿、穿透!8 张图搞懂

先回顾一下缓存在哪个地方?当redis仅作为缓存使用(不作为key-value数据库使用)时,它就在MySQL前面,充当CPU-cache-内存中的“cache”的作用。

缓存异常会面临的三个问题:缓存雪崩、击穿和穿透。

其中,缓存雪崩和缓存击穿主要原因是数据不在缓存中,而导致大量请求访问了数据库,数据库压力骤增,容易引发一系列连锁反应,导致系统奔溃。不过,一旦数据被重新加载回缓存,应用又可以从缓存快速读取数据,不再继续访问数据库,数据库的压力也会瞬间降下来。因此,缓存雪崩和缓存击穿应对的方案比较类似。

而缓存穿透主要原因是数据既不在缓存也不在数据库中。因此,缓存穿透与缓存雪崩、击穿应对的方案不太一样。

1. 缓存穿透

        读请求先访问缓存,如果缓存没有命中再去访问数据库,MySQL数据库中也没有。那么当有大量这样的请求到来时,数据库的压力骤增,这就是缓存穿透的问题。

缓存穿透的发生一般有这两种情况:

  • 业务误操作,缓存中的数据和数据库中的数据都被误删除了,所以导致缓存和数据库中都没有数据;

  • 黑客恶意攻击,故意大量访问某些读取不存在数据的业务;

解决方法

  • ① 在controller层就拦截非法请求。在 API 入口处我们要判断求请求参数是否合理,请求参数是否含有非法值、请求字段是否存在,如果判断出是恶意请求就直接返回错误
  • ② 使用布隆过滤器快速判断缓存是否存在

        布隆过滤器实际是上一种hash数据结构,在写入数据库数据时,使用布隆过滤器做个标记,也就是说在数据库存在的数据一定是有标记的。我们先不查数据库,而是查询布隆过滤器快速判断数据是否存在,过滤掉那些请求不存在数据的请求。这样就不会去数据库读不存在的数据了,也就不会发生缓存穿透了。

  • ③ 缓存空对象

在缓存中设置一个空值或者默认值,这样后续请求就可以从缓存中读取到空值或者默认值,返回给应用,而不会继续查询数据库。

2. 缓存击穿

        击穿”很形象,打击的对象是某一个点,这个点叫做“热点数据”。想象大量请求访问同一个热点数据(比如某男艺人塌房的热搜),好比一连串的子弹都打在同一个地方,而redis是一堵墙替MySQL挡住了这些子弹,但是当缓存过期的一瞬间,这堵墙消失, 就会有一连串的子弹打到MySQL上,MySQL崩溃。

解决方法

  • ① 互斥锁。当业务线程在处理用户请求时,如果发现访问的数据不在 Redis 里,就加个互斥锁,保证同一时间内只有一个请求来构建缓存(从数据库读取数据,再将数据更新到 Redis 里),当这个请求把缓存构建好后,再释放锁。未能获取互斥锁的请求,要么等待锁释放后重新读取缓存,要么就返回空值或者默认值。// 实现互斥锁的时候,最好设置超时时间,不然第一个请求拿到了锁,然后这个请求发生了某种意外而一直阻塞,一直不释放锁,这时其他请求也一直拿不到锁,整个系统就会出现无响应的现象。

  • ② 设置不让缓存过期。但是缓存还是要更新的啊,不然就跟MySQL的数据不一致了,别忘了数据的一致性是ACID的终极目标,数据都不一致了再高的可用性也白搭。而是由redis服务自己更新缓存数据 。redis后台开启一个线程来负责更新。

3. 缓存雪崩

        “雪崩”很形象,缓存雪崩其实不只是缓存崩了,而是由缓存崩了引起来的一系列数据库继而崩了,微服务继而崩了,整个系统继而崩了,这才是雪崩。

        当大量缓存数据在同一时间过期(失效)或者 Redis 故障宕机时,如果此时有大量的用户请求,都无法在 Redis 中处理,于是全部请求都直接访问数据库,从而导致数据库的压力骤增,严重的会造成数据库宕机,从而形成一系列连锁反应,造成整个系统崩溃,这就是缓存雪崩的问题。 

总结,雪崩的两个原因:

  • redis宕机(更严重
    • 解决方法:
    • ① 服务熔断--->请求限流。暂停业务应用对缓存服务的访问,直接返回错误,这样做是为了保证数据库不崩溃,等到 Redis 恢复正常后,再允许业务应用访问缓存服务。
      • 但是直接服务熔断有点太粗暴了,为了减少对业务的影响,我们可以启用请求限流机制,只将少部分请求发送到数据库进行处理,再多的请求就在入口直接拒绝服务,等到 Redis 恢复正常并把缓存预热完后,再解除请求限流的机制。
    • ② 构建redis集群(异地多活)。注意不是主从复制,主从复制是一个写节点两个读节点,说白了还是一个服务节点。异地多活可以看成多个主从复制组成的集群
  • 缓存key集中过期(危害小一点,或许MySQL能扛过去
    • 解决方法
    • ① 均匀设置过期时间。避免将大量的数据设置成同一个过期时间。我们可以在对缓存数据设置过期时间时,给这些数据的过期时间加上一个随机数
    • ② 互斥锁。
    • ③ 设置不让缓存过期。

本文发布于:2024-01-28 05:10:59,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/17063898635023.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:进阶   Redis
留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23