Java学习笔记-Redis

文章详细介绍了Redis中的缓存问题,包括缓存穿透的解决方案如布隆过滤器,缓存击穿的处理方法如互斥锁和逻辑过期,以及缓存雪崩的预防措施。此外,还讨论了双写一致性、数据持久化机制如RDB和AOF,以及数据过期策略和淘汰策略。最后,提到了Redis的分布式锁和集群架构,包括主从复制、哨兵模式和分片集群。
摘要由CSDN通过智能技术生成

Redis

缓存穿透

描述:缓存穿透是指查询一个一定不存在的数据,由于缓存是不命中时需要从数据库查询,查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都要到数据库去查询,进而给数据库带来压力

解决:

  1. 对url中的key id值进行加密,不轻易暴露出真实的key值,防止黑客攻击

  2. 不管数据实际上存在不存在,都把这个键存入缓存

    value为空不代表不占用内存空间,比较有效的方法就是针对这类数据设置一个较短的过期时间

    缓存层和存储层的数据会有一段时间窗口的不一致。可以利用消息系统或者其他方式清除掉缓存层中的空对象

  3. 布隆过滤器拦截

​ 在访问缓存层和存储层之前,将存在的key用布隆过滤器提前保存起来,做第一层拦截

​ 优点:空间效率和查询效率都远远超过一般的算法

​ 弊端:有一定的误识别率

缓存击穿

描述:给某一个key设置了过期时间,当key过期的时候,恰好这时间点对这个key有大量的并发请求过来,这些并发的请求可能会瞬间把数据库压垮

解决方案一:互斥锁,强一致,性能差

解决方案二:逻辑过期,高可用,性能优,不能保证数据绝对一致

缓存雪崩

描述:缓存雪崩是指在同一时段大量的缓存key同时失效或者redis服务宕机,导致大量的请求到达数据库,带来巨大压力。

解决方案:

​ 给不同的key过期时间添加随机值

​ 利用redis集群提高服务的可用性

​ 给缓存业务添加降级限流策略

​ 给业务添加多级缓存

双写一致性

描述:当修改了数据库的数据也要同时更新缓存的数据,缓存和数据库的数据要保持一致

一致性要求高;允许延迟一致

  1. 延迟双删,降低脏数据的出现,但仍存在脏数据的风险
  2. 分布式锁:共享锁、排他锁。强一致、性能低
  3. 异步通知:表数据发生变化的时候通知变更情况更新缓存,确保最终一致
持久化
  1. ROB Redis数据备份文件 把内存中的所有数据记录到磁盘中,当Redis实例故障重启后,从磁盘读取快照文件,恢复数据。例如配置多少秒内有几条数据修改则进行数据备份。
  2. AOF 追加文件 Redis处理的每一个写命令都会记录在AOF文件,可以看做命令日志文件。
数据过期策略

描述:Redis对数据设置数据的有效时间,数据过期以后,就需要将数据从内存中删除掉。可以按照不同规则进行删除,这种删除规则就被称之为数据的删除策略。

  1. 惰性删除
  2. 定期删除

数据淘汰策略

描述:当Redis中的内存不够用时,此时向Redis中添加新的key,那么Redis就会按照某一种规则将内存中的数据删除掉,这种数据的删除规则被称之为内存的淘汰策略。

  • volatile-lru:从已设置过期时间的数据集中挑选最近最少使用的数据淘汰。
  • volatile-ttl:从已设置过期时间的数据集中挑选将要过期的数据淘汰。
  • volatile-random:从已设置过期时间的数据集中任意选择数据淘汰。
  • volatile-lfu:从已设置过期时间的数据集挑选使用频率最低的数据淘汰。
  • allkeys-lru:从数据集中挑选最近最少使用的数据淘汰
  • allkeys-lfu:从数据集中挑选使用频率最低的数据淘汰。
  • allkeys-random:从数据集中任意选择数据淘汰
  • no-enviction(驱逐):禁止驱逐数据,这也是默认策略。意思是当内存不足以容纳新入数据时,新写入操作就会报错,请求可以继续进行,线上任务也不能持续进行,采用no-enviction策略可以保证数据不被丢失。
分布式锁

在分布式系统里,有时执行定时任务,或者处理某些并发请求,涉及到多个进程之间的同步,需要确保多点系统里同时只有一个执行线程进行处理。分布式锁就是在分布式系统里互斥访问资源的解决方案。

Redis集群
  • 主从复制

描述:单节点Redis的并发能力是有上限的,要进一步提高Redis的并发能力,就需要搭建主从集群,实现读写分离。一般是一主多从,主节点负责写数据,从节点负责读数据。

全量同步:

  1. 从节点请求主节点同步数据(replication id、offset)
  2. 主机点判断是否是第一次请求,是第一次就与从节点同步版本信息
  3. 主节点执行bgsava,生成RDB文件,发送给从节点去执行
  4. 在RDG生成执行期间,主节点会以命令的方式记录到缓冲区(一个日志文件)
  5. 把生成之后的命令日志文件发送给从节点进行同步

增量同步:

  1. 从节点请求主节点同步数据,主节点判断不是第一次请求,就获取从节点的offfset值
  2. 主节点从命令日志中获取offset值之后的数据,发送给从节点进行数据同步
  • 哨兵模式

    • 监控:Sentinel会不断检查master和slave是否按预期工作

    • 自动故障恢复:如果master故障,Sentinel会将一个slave提升为master。当故障实例恢复后也以新的master为主

    • 通知:Sentinel充当Redis客户端的服务发现来源,当集群发生故障转移时,会将最新信息推送给Redis的客户端

– 脑裂解决方案:修改Redis配置,设置最少salve节点为一个;减少数据复制和同步的延迟时间

  • 分片集群

    • 集群中有多个master,每个master保存不同数据

    • 每个master都可以有多个slave节点

    • master之间通过ping检测彼此健康状态

    • 客户端请求可以访问集群任意节点,最终都会被转发到正确节点

分片集群中数据是怎么存储和读取的

Redis分片集群引入哈希槽的概念,Redis集群有16384个哈希槽

将16384个插槽分配到不同的实例

读写数据:根据key的有效部分计算哈希值,对18384取余(有效部分,如果key前面有大括号,大括号的内容就是有效部分,如果没有,则以key本身做为有效部分)余数做为插槽,寻找插槽所在的实例。

其他

Redis速度快的原因:

  • Redis是纯内存操作,执行速度非常快
  • 采用单线程,避免不必要的上下文切换可竞争条件,多线程还要考虑线程安全问题
  • 使用I/O多路复用模型,非阻塞IO

– I/O多路复用:Redis是纯内存操作,执行速度非常快,它的性能瓶颈是网络延迟而不是执行速度,I/O多路复用模式主要就是实现了高效的网络请求

​ 用户空间和内核空间

​ 常见的IO模型

  • 阻塞IO:当用户线程发出IO请求之后,内核会去查看数据是否就绪,如果没有就绪就会等待数据就绪,而用户线程就会处于阻塞状态,用户线程交出CPU。当数据就绪之后,内核会将数据拷贝到用户线程,并返回结果给用户线程,用户线程才解除block状态。

  • 非阻塞IO:当用户线程发起一个read操作后,并不需要等待,而是马上就得到了一个结果。如果结果是一个error时,它就知道数据还没有准备好,于是它可以再次发送read操作。一旦内核中的数据准备好了,并且又再次收到了用户线程的请求,那么它马上就将数据拷贝到了用户线程,然后返回。在非阻塞IO模型中,用户线程需要不断地询问内核数据是否就绪,也就说非阻塞IO不会交出CPU,而会一直占用CPU。

  • IO多路复用:利用单个线程来同时监听多个Socket,并在某个Socket可读、可写时得到通知,从而避免无效的等待,充分利用CPU资源

​ Redis网络模型

连接应答处理器

  • 连接应答处理器
  • 命令回复处理器
  • 命令请求处理器
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值