>  기사  >  데이터 베이스  >  Redis 캐시 사태 문제를 해결하는 방법

Redis 캐시 사태 문제를 해결하는 방법

WBOY
WBOY앞으로
2023-06-03 09:46:021757검색

캐시 계층은 많은 수의 요청을 전달하여 스토리지 계층을 효과적으로 보호합니다. 그러나 캐시 장애가 많아 스토리지 계층에 많은 요청이 도착하거나, 캐시 전체가 서비스를 제공할 수 없는 경우 스토리지 계층의 부하가 증가하게 된다(요청이 많아 데이터베이스를 쿼리하는 경우). 이것은 캐시 사태의 현장입니다.

캐시 사태를 해결하려면 다음 사항부터 시작할 수 있습니다.

1. 캐시 레이어의 가용성을 높게 유지하세요

Redis 감시 모드 또는 Redis 클러스터 배포 방법, 즉 개별 Redis 노드는 오프라인 상태가 됩니다. 전체 캐시 계층을 계속 사용할 수 있습니다. 또한 Redis는 여러 컴퓨터실에 배포할 수 있으므로 컴퓨터실이 충돌하더라도 캐시 계층의 가용성을 높일 수 있습니다.

2. 전류 제한 및 다운그레이드 구성 요소

캐시 레이어와 스토리지 레이어 모두 오류 가능성이 있으며 리소스로 간주될 수 있습니다. 동시성이 많은 분산 시스템으로서 리소스를 사용할 수 없는 경우 모든 스레드가 해당 리소스를 얻을 때 예외가 발생하여 전체 시스템을 사용할 수 없게 되는 경우가 있습니다. 예를 들어 추천 서비스에서 개인화된 추천 서비스를 이용할 수 없는 경우 다운그레이드하여 핫스팟 데이터를 보완함으로써 전체 추천 서비스를 이용할 수 없게 되는 경우가 매우 일반적입니다. 일반적인 전류 제한 성능 저하 구성 요소로는 Hystrix, Sentinel 등이 있습니다.

3. 캐시는 만료되지 않습니다

Redis에 저장된 키는 만료되지 않으므로 동시에 많은 수의 캐시가 실패하는 문제는 없지만 Redis에는 더 많은 저장 공간이 필요합니다.

4. 캐시 만료 시간 최적화

캐시를 설계할 때 많은 수의 키가 동시에 무효화되어 캐시 사태가 발생하는 것을 방지하려면 각 키에 대해 적절한 만료 시간을 선택하세요.

5. 뮤텍스 잠금을 사용하여 캐시 재구축

높은 동시성 시나리오에서 데이터를 쿼리하고 동시에 캐시를 재구축하기 위해 스토리지 계층에 도달하는 많은 수의 요청을 방지하기 위해 뮤텍스 잠금 제어를 사용할 수 있습니다. 예를 들어, 키에 따라 캐시 계층에서 데이터를 쿼리하고, 캐시 계층에 도달하면 키가 잠기고, 저장 계층에서 데이터가 쿼리되고, 데이터가 캐시 계층에 기록되고, 마지막으로 잠금이 해제됩니다. . 다른 스레드에서 잠금 획득이 실패했음을 발견하면 스레드를 일정 시간 동안 휴면 상태로 두고 다시 시도하세요. 잠금 유형은 독립형 환경인 경우 Java 동시 패키지 아래의 잠금을 사용할 수 있습니다. 분산 환경인 경우 분산 잠금(Redis의 SETNX 메소드)을 사용할 수 있습니다.

분산 환경의 뮤텍스 잠금 재구성 캐시 의사 코드

/**
 * 互斥锁建立缓存
 *
 **/
public String get(String key) {
   // redis中查询key对应的value
   String value = redis.get(key);
   // 缓存未命中
   if (value == null) {
      // 互斥锁
      String key_mutex_lock = "mutex:lock" + key; 
      // 互斥锁加锁成功
      if(redis.setnx(key_mutex_lock,"1")) { // 返回 0(false),1(true)
          try {
              // 设置互斥锁超时时间,这里设置的是锁的失效时间,而不是key的失效时间
              redis.expire(key_mutex_lock,3*60);
              // 从数据库查询
              value = db.get(key);
              // 数据写入缓存
              redis.set(key,value);
            
          } finally {
               // 释放锁
              boolean keyExist = jedis.exists(key_mutex_lock);
              if(keyExist){
                  redis.delete(key_mutex_lock);
               }
      } else { 
              // 加锁失败,线程休息50ms后重试
               Thread.sleep(50);
               return get(key); // 直接返回缓存结果  
     }
   }
}

Redis 분산 잠금을 사용하여 분산 환경에서 캐시 재구성을 구현하는 장점은 설계 아이디어가 간단하고 데이터 일관성이 보장된다는 점입니다. 증가하고 사용자를 기다리게 할 수도 있습니다. 높은 동시성에서 캐시 재구성 중에 키가 잠겨 있다고 가정합니다. 현재 동시 요청이 1,000개라면 그 중 999개가 차단되어 999개의 사용자 요청이 차단되고 대기하게 됩니다.

6. 캐시의 비동기 재구축

이 방식에서는 캐시를 구축하기 위해 비동기 전략이 채택되어 캐시를 비동기적으로 구축하므로 모든 요청이 스토리지 계층에 직접 도달하지 않습니다. 이 구성표의 각 Redis는 논리적 제한 시간이 현재 시간보다 작으면 현재 캐시가 만료되었으며 캐시가 업데이트되어야 함을 의미합니다. 캐시의 값이 직접 반환됩니다. 예를 들어 Redis에서는 키의 만료 시간이 60분으로 설정되고, 해당 값의 논리적 만료 시간은 30분으로 설정됩니다. 이러한 방식으로 키가 논리적 만료 시간인 30분에 도달하면 이 키의 캐시를 비동기식으로 업데이트할 수 있지만 캐시를 업데이트하는 동안 이전 캐시를 계속 사용할 수 있습니다. 이 비동기 캐시 재구성 방법은 많은 수의 키가 동시에 무효화되는 것을 효과적으로 방지할 수 있습니다.

아아아아

위 내용은 Redis 캐시 사태 문제를 해결하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 yisu.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제