云虚拟主机和网站建设,网页素材图,wordpress的Portfolio,为公司做网站Redis的缓存穿透
缓存穿透是指那些查询请求所要获取的数据既不在缓存#xff08;Redis#xff09;中#xff0c;也不在数据库#xff08;例如#xff1a;MySQL#xff09;中#xff0c;因此每次请求都会直接访问数据库。这种情况通常由以下几种情形引起#xff1a;
恶…Redis的缓存穿透
缓存穿透是指那些查询请求所要获取的数据既不在缓存Redis中也不在数据库例如MySQL中因此每次请求都会直接访问数据库。这种情况通常由以下几种情形引起
恶意请求恶意用户或攻击者故意发送不存在的数据请求以造成系统负担或者尝试暴力攻击数据库。随机性访问大量请求发送到一个不存在的键导致每次请求都落到数据库上尤其是在高并发情况下。过期数据缓存中的数据过期或被淘汰而此时数据库中也不存在这些数据因此新的请求会穿透缓存直接访问数据库。
常见的解决方案有两种
缓存空对象
实施方式当请求查询的数据在缓存中不存在时仍将一个空对象或者默认值存入缓存中有效期根据需求设定以防止大量的无效请求穿透到数据库。
优点
实现简单维护方便。可以快速响应客户端请求减少对数据库的直接访问。
缺点
需要额外的内存空间来存储空对象或者默认值。可能导致短期内的数据不一致如果数据库中数据发生变化而缓存中的空对象未及时更新。
布隆过滤器
实施方式在缓存层之前引入布隆过滤器用于快速判断请求的键是否可能存在于缓存中从而减少对缓存和数据库的无效查询。
优点
占用内存较少不会存储多余的数据。能够快速判断请求是否可能命中缓存避免无效查询。
缺点
实现较为复杂需要维护布隆过滤器的哈希函数和位数组。存在一定的误判概率即布隆过滤器可能会误判某个数据存在于缓存中但实际上并不存在。 在实际应用中可以根据具体情况选择合适的解决方案或者结合两种方法来提高系统的性能和可靠性。例如可以使用布隆过滤器来过滤掉明显不存在于缓存中的请求同时对于偶尔的缓存穿透情况可以通过缓存空对象来缓解对数据库的压力。
Redis的缓存击穿
Redis缓存击穿是指缓存Redis中不存在但数据库例如MySQL中存在的数据在并发访问下导致大量请求直接穿透缓存直接访问数据库引起数据库压力过大的情况。这通常发生在某个缓存键过期或者被删除后恰好有大量并发请求同时访问该键对应的数据。
针对这个问题常见的解决方案包括互斥锁和逻辑过期两种方法。
互斥锁方案
原理 使用锁来保证在缓存失效时只允许一个线程重新查询数据库并更新缓存其他线程需要等待。
具体实现
当一个线程发现缓存失效时尝试获取互斥锁。如果获取锁成功该线程负责重新查询数据库并更新缓存。其他线程在尝试获取锁时会被阻塞直到锁被释放。释放锁后其他线程可以再次尝试获取锁并继续处理请求。 优点
简单直接易于实现。能够确保数据的一致性因为只有一个线程能够更新缓存。
缺点
锁竞争可能导致性能下降特别是在高并发场景下。可能出现死锁问题需要谨慎设计锁的获取和释放逻辑。
逻辑过期方案
原理 通过逻辑判断来避免真实过期时间导致的缓存击穿问题即在缓存失效时允许多个线程同时访问数据库但只有一个线程负责更新缓存。
具体实现
在缓存中存储一个额外的逻辑过期时间该时间比实际的过期时间要早。当缓存失效时所有线程可以同时访问数据库。第一个获取到数据的线程会尝试获取互斥锁并更新缓存。其他线程在发现缓存失效后检测到逻辑过期时间未到时直接返回之前的脏数据。 优点
可以避免锁竞争导致的性能问题允许多个线程并发访问数据库。对于用户体验较好因为大部分请求能够快速返回旧数据。
缺点
需要额外的逻辑来处理过期时间判断和数据更新实现较复杂。在数据更新完成前可能会返回旧数据存在数据不一致的风险。
对比与选择
互斥锁方案适合对数据一致性要求高、并发量较大的场景尤其是需要严格保证数据更新顺序的情况。逻辑过期方案适合对即时性要求较高、并发量不是特别高的场景能够在一定程度上减少数据库访问压力。 Redis的缓存雪崩
Redis的缓存雪崩是指在缓存中大量的键key同时过期导致大量请求直接打到数据库从而引起数据库压力剧增甚至宕机的情况。这种情况通常发生在缓存服务器重启、大规模的缓存并发失效、或者缓存Redis服务器宕机重启等情况下。 解决方案
给不同的Key的TTL添加随机值通常情况下缓存的过期时间设置为固定值会导致大量缓存在同一时间失效从而引发雪崩效应。通过给每个缓存键设置稍微不同的过期时间比如在原本过期时间的基础上加上一个随机值可以有效分散缓存失效的时间点减少集中失效带来的压力。利用Redis集群提高服务的可用性使用Redis集群可以提高Redis服务的可用性和容错能力。Redis集群能够分散请求到多个节点上即使某个节点发生故障或者重启其他节点仍然可以继续提供服务从而减少单点故障的影响。给缓存业务添加降级限流策略在缓存失效时为了避免大量请求直接打到数据库可以实施降级策略例如返回默认值、空值或者直接拒绝服务避免数据库被大量请求压垮。同时也可以通过限流策略控制并发访问量防止系统过载。给业务添加多级缓存使用多级缓存架构比如本地缓存如内存、分布式缓存如Redis、以及后备缓存如数据库可以有效应对单一缓存失效带来的问题。本地缓存可以提供快速响应而分布式缓存则能够提供高可用性和扩展性后备缓存则作为最终的备份数据源。
总体而言这些解决方案结合起来能够有效地减少缓存雪崩问题的发生并保证系统在高负载时依然能够稳定运行。