本文共 1557 字,大约阅读时间需要 5 分钟。
缓存雪崩是指系统中大量的缓存同时失效,导致后续的请求全部转向数据库,引发数据库过载甚至崩溃的现象。这种情况通常发生在大量的缓存 Key 同时到期时,系统无法及时从数据库获取数据来补充缓存,导致数据库承受无法忍受的压力。
缓存雪崩的本质是缓存 Key 的失效时间集中发生,导致 Redis 等缓存层无法及时提供数据支持。当大量 Key 同时失效时,系统会面临以下问题:
举个简单的例子:假设 Redis 中的所有 Key 都设置了相同的失效时间。如果系统同时受到大量请求,缓存层无法提供服务,请求会直接打到数据库。这种情况下,数据库可能在短时间内承受超过其负载能力的压力,导致服务中断。
缓存雪崩的解决方法主要集中在以下几个方面:
失效时间加个随机值
在批量写入 Redis 时,为每个 Key 的失效时间添加一个随机值。这样可以避免大量 Key 同时失效的风险。例如,可以将失效时间从固定的时间戳改为基于哈希函数生成的随机时间戳。设置热点缓存数据永远不过期
对于一些特别重要的热点数据,可以设置其缓存时间为永不过期。这样可以确保这些数据在高并发时仍能正常提供服务。分散请求时间
为每个客户端设置一个随机的短暂延迟时间。这样可以避免所有客户端在同一时间发送请求,从而减少缓存雪崩的可能性。缓存穿透是指用户请求的数据在 Redis 缓存和数据库中都不存在,而用户仍然试图从缓存层获取数据。这种情况通常发生在攻击者试图通过发送不存在的 Key 或参数来耗尽系统资源。
缓存穿透的本质是攻击者试图通过发送不存在的 Key 或参数,耗尽系统的资源。例如,用户可能会发送一个非常大的 ID 或负数 ID 来测试系统的健壮性。
如果系统没有对请求参数进行校验,缓存层会返回不存在的数据,请求会直接打到数据库。这种现象可能导致数据库承受极高的压力,甚至崩溃。
缓存穿透的解决方法主要包括以下几点:
接口层增加校验
在接口层对请求参数进行基础校验。例如,对于 ID 参数,可以设置一个合法范围(如 ID > 0),并对不合法的请求直接拦截。布隆过滤器
使用布隆过滤器来快速判断请求的 Key 是否存在于数据库中。布隆过滤器通过 probabilistic hashing 来判断 Key 是否存在,可以有效减少不必要的数据库查询。设置不存在的 Key 为 null
对于在数据库中不存在的 Key,可以将其缓存值设置为 null 或其他表示不存在的值。这样可以避免不必要的数据库查询,同时在 UI 或业务逻辑中进行处理。缓存击穿是指某个热点 Key 的缓存在失效后,仍然面临大量的并发请求。这种现象通常发生在 Key 的失效时间与高并发请求的时间点重合。
缓存击穿的本质是热点 Key 在失效后,仍然面临大量的并发请求。这种现象会导致 Redis 缓存被击穿,请求直接打到数据库,可能导致数据库过载。
缓存击穿的解决方法主要包括以下几点:
设置热点数据永远不过期
对于一些特别重要的热点数据,可以设置其缓存时间为永不过期。这样可以确保这些数据在高并发时仍能正常提供服务。互斥锁
采用互斥锁(锁机制)来保证同一时刻只有一个客户端可以查询底层数据库。这样可以避免多个客户端同时尝试查找同一个 Key,减少击穿的可能性。通过以上方法,可以有效减少缓存雪崩、穿透和击穿对系统的影响,从而提高系统的稳定性和可用性。
转载地址:http://nmfh.baihongyu.com/