이 기사에서는 Redis의 세 가지 일반적인 캐시 이상 현상인 캐시 침투, 캐시 고장 및 캐시 사태에 대해 설명합니다. 이를 통해 Redis의 단축키 저장 문제에 대해 이야기하겠습니다.
관련 권장 사항: "Redis 캐시 일관성, 캐시 침투, 캐시 고장 및 캐시 눈사태 문제를 함께 분석해 보겠습니다"
캐시 침투, 캐시 고장 및 캐시 눈사태는 Redis 인터뷰 및 실제 개발 중에 이 자주 고려해야 할 질문입니다. 아직도 많은 사람들이 이 문제의 원인, 원인, 해결 방법에 대해 명확하지 않습니다. 실제로 생성된 원리를 주의 깊게 분석하면 이 세 가지 상황에 대한 좋은 해결책을 찾을 수 있습니다. [관련 권장사항: Redis 동영상 튜토리얼]
이 글은 정의, 사례, 위험 및 솔루션을 통해 이러한 세 가지 문제를 빠르게 이해하는 데 도움이 됩니다.
이 세 가지 문제에 대한 해결책을 인터넷에서 많이 본 것 같습니다. 그 중 올바른
해결책이 있습니까? 또한 이 기사에서는 이러한 솔루션의 장점과 단점을 하나씩 분석합니다. 正确的
方案呢?本文也将一一分析此类方案的优缺点。
下图为本文的内容大纲,文章也是围绕这几点进行分析与总结。
缓存穿透、缓存击穿和缓存雪崩都是因为缓存中数据不存在,导致走数据库去查询数据。
由于缓存数据不存在,所有的请求都会走到数据库,因此会导致数据库的压力过大甚至出现服务崩溃,导致整个系统无法使用。
定义:缓存穿透是由于客户端求的数据在缓存中不存在,然后去查询数据库,然而数据库没有客户端要查询的数据,导致每一次请求都会走数据库查询操作。真正的问题在于该数据本身就是不存在的
。
举例:客户端请求商品详情信息时,携带一个商品ID,此时该商品ID是不存在的(不管是缓存中还是数据库中)。导致每一次请求该ID商品的数据信息都会走数据库。
危害:由于请求的参数对应的数据根本不存在,会导致每一次都会请求数据库,增加数据库的压力或者服务崩溃,更有甚至影响到其他的业务模块。经常发生在用户恶意请求
的情况下会发生。
解决方案:
1、根据请求的参数缓存一个null值。并且为该值设置一个过期时间,可以将时间设置短暂一点。
2、使用布隆过滤器,首先通过布隆过滤器进行筛选,如果在过滤器中存在则去查询数据库,然后添加到缓存中。如果不存在则直接返回客户端数据不存在。
3、由于缓存穿透可能是用户发起恶意请求,可以将用户ip给记录下来,针对恶意的ip请求进行封禁。
方案分析:
第一种方案,针对不存在的key,会缓存一个空的值。假设这样的请求特别多,是否都会一一去设置一个空值的缓存,此时Redis中就存在大量无效的缓存空值。假设这样的key是商品或者文章类的ID,我们在设置空值之后,如果后台添加数据应该去更新ID对应的缓存值,并设置一个合理的过期时间。
第二种方案,也是业界使用最多的一种方案。布隆过滤器的优点在于基于Redis实现,内存操作并且底层的实现也是非常节约内存。 当后台添加数据成功时,将该数据的ID添加到布隆过滤器中,前端在请求时先走布隆过滤器进行验证是否存在。但布隆过滤器也存在一个弊端,就是hash冲突问题。这里的hash冲突是什么意思呢?就是说多个ID在进行hash计算时,得到的hash位都是同一个值,这就导致在验证是否存在时误判。本身是有的,得到的结果是没有。布隆过滤器的一个弊端就是,它说有并不一定有,它说没有就一点是没有的。
세 가지 비교
캐시된 데이터가 존재하지 않기 때문에 모든 요청이 데이터베이스로 이동하게 되어 데이터베이스에 과도한 부담을 주거나 심지어 서비스 충돌을 일으켜 전체 시스템을 사용할 수 없게 됩니다. 🎜🎜🎜
실제 문제는 데이터 자체가 존재하지 않는다는 것입니다
. 🎜🎜예: 클라이언트가 제품 세부 정보를 요청할 때 제품 ID가 전달됩니다. 이때 제품 ID는 캐시나 데이터베이스에 존재하지 않습니다. 결과적으로 이 ID를 가진 제품의 데이터가 요청될 때마다 데이터베이스로 이동됩니다. 🎜🎜위험: 요청한 매개변수에 해당하는 데이터가 전혀 존재하지 않기 때문에 매번 데이터베이스를 요청하게 되어 데이터베이스에 대한 부담이 가중되거나 서비스 충돌이 발생하고 심지어 다른 비즈니스 모듈에도 영향을 미치게 됩니다. 이는 사용자가 악의적인 요청
을 할 때 자주 발생합니다. 🎜🎜🎜해결책: 🎜🎜🎜1. 요청된 매개변수에 따라 null 값을 캐시합니다. 그리고 이 값에 만료 시간을 설정하면 시간을 더 짧게 설정할 수 있습니다. 🎜🎜2. Bloom 필터를 사용하세요. 먼저 Bloom 필터를 통해 필터가 존재하는 경우 데이터베이스에 쿼리한 후 캐시에 추가하세요. 존재하지 않는 경우 클라이언트 데이터가 존재하지 않는다고 직접 반환합니다. 🎜🎜3. 사용자의 악의적인 요청으로 인해 캐시 침투가 발생할 수 있으므로 사용자의 IP를 기록하고 악의적인 IP 요청을 차단할 수 있습니다. 🎜🎜🎜 솔루션 분석: 🎜🎜블룸 필터의 단점 중 하나는 존재한다고 해서 반드시 존재하지 않고, 존재하지 않으면 존재하지 않는다는 뜻이라는 점입니다.
🎜🎜🎜🎜세 번째 옵션은 일정 기간 내에 동일한 사용자에 대해 많은 수의 요청을 시작하여 캐시 침투 메커니즘을 트리거하는 것입니다. 이때 클라이언트의 액세스를 표시할 수 있습니다. 그러나 공격자가 DDOS 공격을 실행하면 이러한 공격을 완전히 피할 수 없으므로 이 솔루션은 좋은 솔루션이 아닙니다. 🎜🎜🎜🎜🎜 계획 요약: 🎜🎜먼저 요청 수준에 세 번째 솔루션을 추가하여 일부 악의적인 요청을 제어하기 위한 현재 제한 메커니즘과 IP 블랙리스트 메커니즘을 생성합니다. 잘못된 판단인 경우 IP 차단 해제와 같은 작업을 구현할 수 있습니다. 캐시 계층은 첫 번째 솔루션을 사용하여 구현됩니다. 합리적인 캐시 시간을 설정하세요.
오판을 용인할 수 있는 비즈니스 시나리오의 경우 두 번째 솔루션을 직접 사용할 수 있습니다. Redis를 완벽하게 기반으로 하여 시스템 복잡성을 줄입니다.
정의: 캐시 분석은 핫스팟 키가 존재하지 않아 데이터베이스 쿼리가 발생하기 때문에 발생합니다. 데이터베이스에 대한 부담이 증가했습니다. 이 압력은 일시적일 수도 있고 오래 지속될 수도 있습니다. 真正的问题在于该key是存在,只是缓存中不存在,导致走数据库操作
.
예: 인기 있는 제품이 있습니다. 사용자가 제품 세부 정보를 볼 때 제품 세부 정보를 얻기 위해 제품 ID를 가지고 있습니다. 이때 캐시에 있는 데이터가 만료되었으므로 들어오는 모든 요청은 쿼리를 위해 데이터베이스로 이동해야 합니다.
위험: 캐시 침투에 비해 데이터가 데이터베이스에 존재하지만 캐시가 만료되었기 때문에 한 번 데이터베이스로 이동한 후 캐시에 추가되고 다음 요청이 캐시로 이동할 수 있습니다. 보통. 소위 피해도 데이터베이스 수준을 목표로 합니다.
해결책:
1.뮤텍스 잠금을 추가하세요. 첫 번째 요청에서는 캐시에 데이터가 없는 것으로 확인되었습니다. 이때 쿼리 데이터베이스가 캐시에 추가되었습니다. 이러한 방식으로 후속 요청은 데이터베이스 쿼리를 거칠 필요가 없습니다.
2. 비즈니스 로직 만료 시간을 늘립니다. 캐시를 설정할 때 캐시 만료 시간을 추가할 수 있습니다. 읽을 때마다 판단하십시오. 만료 시간이 현재 시간보다 짧으면 백그라운드 스레드를 트리거하고 데이터베이스로 이동하여 데이터를 가져온 다음 캐시된 데이터와 캐시된 만료 시간을 업데이트합니다. 실제로 코드 수준에서 캐시에 대한 캐시 기간을 연장하는 것이 원칙입니다.
3. 데이터 워밍업. 백그라운드를 통해 캐시에 데이터 추가를 구현합니다. 예를 들어, 반짝 세일 장면이 시작되기 전에 해당 제품의 재고가 캐시에 추가되어 사용자 요청이 오면 바로 캐시로 이동하게 됩니다.
4. 만료되지 않습니다. 캐시 만료 시간을 설정할 때 만료되지 않도록 설정하세요. 이러한 캐시의 만료 시간과 데이터 업데이트를 유지하기 위해 별도의 스레드가 백그라운드에서 열립니다.
프로젝트 분석:
뮤텍스 잠금은 하나의 요청만 데이터베이스로 이동하도록 보장하며 이는 장점입니다. 그러나 분산 시스템의 경우 분산 잠금을 구현하는 데 분산 잠금이 사용됩니다. 분산 잠금 자체의 구현에는 특정 어려움이 있어 시스템이 더욱 복잡해집니다.
두 번째 솔루션은 만료 및 비즈니스 만료를 방지하기 위해 Redis를 사용하여 구현됩니다. 이를 통해 모든 요청이 데이터를 얻을 수 있고 동시에 백그라운드 스레드를 사용하여 데이터를 업데이트할 수 있습니다. 단점은 백그라운드 스레드가 데이터 업데이트를 완료하지 못했다는 것입니다. 현재 요청된 데이터는 오래된 데이터이므로 실시간 요구 사항이 높은 비즈니스 시나리오에서는 단점이 있을 수 있습니다.
세 번째 해결 방법은 캐시 예열을 사용하고 로드될 때마다 캐시하는 것으로 두 번째 해결 방법과 유사합니다. 하지만 핫 데이터 업데이트 문제도 있기 때문에 이 솔루션은 높은 실시간 데이터가 필요하지 않은 데이터에 적합합니다.
네 번째 솔루션은 두 번째 및 세 번째 솔루션과 유사합니다. 이를 기반으로 백그라운드 비동기 스레드를 사용하여 캐시된 데이터를 적극적으로 업데이트하는 등 특정 최적화가 이루어졌습니다. 업데이트 빈도를 제어하는 데 어려움이 있습니다.
솔루션 요약:
실시간 요구 사항이 높은 데이터의 경우 첫 번째 솔루션을 사용하는 것이 좋습니다. 기술적으로 어렵지만 실시간 데이터 처리가 가능합니다. 일부 요청이 오랜 시간 동안 대기하는 경우 예외가 반환될 수 있으며 클라이언트는 요청을 다시 보낼 수 있습니다.
높은 실시간 성능이 필요하지 않은 데이터의 경우 네 번째 옵션을 사용할 수 있습니다.
정의: 앞에서 언급했듯이 캐시 고장은 캐시의 특정 단축키가 실패하여 많은 수의 요청이 데이터베이스로 이동하기 때문에 발생합니다. 하지만 캐시의 눈사태는 사실 똑같지만, 캐시된 키의 대부분은 한두 개의 키가 아닌 유효하지 않은 키입니다.
예: 전자상거래 시스템에서 특정 카테고리의 제품 데이터는 캐시에서 유효하지 않습니다. 그러나 현재 시스템의 많은 요청은 이 카테고리의 제품 데이터에 대한 것입니다. 이렇게 하면 모든 요청이 데이터베이스 쿼리를 거치게 됩니다.
위험: 순간적으로 많은 요청이 유입되므로 각 요청을 데이터베이스에서 쿼리해야 합니다. 데이터베이스로의 순간적인 트래픽 유입은 데이터베이스에 대한 부담을 심각하게 증가시키고 직접적인 데이터베이스 마비로 이어지기 쉽습니다.
해결책:
1. 캐시 시간은 무작위입니다. 특정 시간에 많은 수의 캐시가 만료되기 때문에 캐시 만료 시간이 상대적으로 집중되어 있음을 의미합니다. 만료 시간을 집중되지 않고 무작위로 직접 설정합니다. 이러한 방식으로 캐시 만료 시간이 집중되지 않으며 동시에 쿼리 작업을 위해 데이터베이스에 대한 요청이 많지 않습니다.
2. 다단계 캐시. 단순히 캐싱을 위해 Redis에 의존하는 대신, 캐싱을 위해 memcached를 사용할 수도 있습니다(여기에는 단지 예가 나와 있으며 다른 캐싱 서비스도 사용할 수 있습니다). 데이터를 캐싱할 때 Redis용 캐시와 memcached용 캐시를 만듭니다. Redis가 실패하면 memcached를 사용할 수 있습니다.
3. 뮤텍스 잠금. 캐시 분석에서 뮤텍스 잠금 사용에 대해 언급했으며 눈사태가 발생하는 경우에도 사용할 수 있습니다.
4. 만료 플래그를 설정합니다. 실제로 캐시 분석에서 언급한 영구 비만료를 사용할 수도 있습니다. 요청 시 만료 시간이 가까워지면 만료 플래그가 설정되어 캐시를 업데이트하는 독립 스레드가 트리거됩니다.
프로젝트 분석:
첫 번째 솔루션은 난수 캐시 시간을 사용하여 키 만료 시간을 분산시킵니다. 캐시 시간을 설정하는 방법에 어려움이 있으며, 캐시 시간이 짧고 데이터 양이 매우 많은 일부 데이터의 경우 이 솔루션에서는 시간에 대한 합리적인 제어가 필요합니다.
두 번째 솔루션은 모든 요청이 캐시된 데이터를 사용하도록 보장할 수 있는 다단계 캐싱을 사용합니다. 그러나 이는 시스템의 구조적 어려움과 다중 레벨 업데이트 캐싱과 같은 다양한 기타 문제를 증가시킵니다.
세 번째 솔루션은 뮤텍스 잠금을 사용합니다. 캐시 분석에서 뮤텍스 잠금을 언급했습니다. 눈사태 시나리오에서 사용할 수 있지만 이로 인해 많은 수의 분산 잠금이 생성됩니다.
네 번째 솔루션은 논리적 캐시 시간을 사용하는데, 이는 시스템의 캐시 압력을 잘 보장합니다.
계획 요약:
실제 프로젝트에서는 1차, 2차, 4차 계획을 사용해 보시는 것이 좋습니다.
캐시 침투는 데이터베이스 자체에 데이터가 없기 때문입니다.
캐시 고장 및 캐시 눈사태는 데이터베이스에 데이터가 있지만 캐시에 있는 데이터가 유효하지 않아 데이터베이스를 다시 쿼리한 다음 캐시에 추가하는 것을 의미합니다.
캐시 고장은 일부 단축키에 대한 것이고, 캐시 눈사태는 대규모 캐시 고장입니다. 캐시 키 분할이 다르다는 점을 제외하면 두 원칙은 실제로 동일합니다.
더 많은 프로그래밍 관련 지식을 보려면 프로그래밍 소개를 방문하세요! !
위 내용은 Redis의 핫키 스토리지 문제를 분석하고 캐시 예외에 대한 솔루션에 대해 논의합니다.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!