빠른 읽기 및 쓰기: 캐시는 일반적으로 전체 메모리(예: Redis, Memcache)이고 스토리지 계층은 일반적으로 읽기 및 쓰기 성능이 부족하기 때문입니다(예: MySQL과 마찬가지로) 메모리 읽기 및 쓰기 속도는 디스크 I/O보다 훨씬 빠릅니다. 캐시를 사용하면 읽기 및 쓰기 속도를 효과적으로 높이고 사용자 경험을 최적화할 수 있습니다.
백엔드 부하 감소: 백엔드의 액세스 양을 줄이는 데 도움이 됩니다(Mysql은 최대 연결 수로 설정되어 있습니다. 많은 수의 액세스가 동시에 데이터베이스에 도달하고 디스크가 I/O 속도가 매우 느리고 최대 연결 수가 소진되기 쉬우나 이론적으로는 Redis가 가장 크고 계산이 복잡하여(예: 매우 복잡한 SQL 문) 백엔드의 로드가 크게 줄어듭니다. .
데이터 불일치: 특정 기간 내에서 캐시 레이어와 스토리지 레이어의 데이터에 불일치가 있으며, 해당 기간은 업데이트 전략과 관련이 있습니다.
코드 유지 비용: 캐시를 추가한 후 캐시 레이어와 스토리지 레이어의 로직을 동시에 처리해야 하므로 개발자의 코드 유지 비용이 늘어납니다.
운영 및 유지 비용: Redis 클러스터를 예로 들면, 가입 후 운영 및 유지 비용이 사실상 증가합니다.
오버헤드가 높은 복잡한 계산: 캐싱이 없는 일부 복잡한 작업 또는 계산(예: 다수의 공동 테이블 작업, 일부 그룹화 계산)은 다음과 같습니다. 높은 동시성은 MySQL에 큰 부담을 안겨줄 것입니다.
요청 응답 가속화: 단일 백엔드 데이터 쿼리가 충분히 빠르더라도 여전히 캐시를 사용할 수 있습니다. 예를 들어 Redis는 초당 수만 건의 읽기 및 쓰기를 완료할 수 있습니다. 제공된 배치 작업은 전체 IO 체인을 최적화할 수 있습니다. 응답 시간
생각: 프로덕션 환경의 Redis는 일단 작성되면 일부 데이터가 손실되는 경우가 많습니다. 잠시 후에 사라질 수도 있습니다. 이유는 무엇입니까?
보통 Redis 캐시는 메모리에 저장되지만, 메모리는 소중하고 제한적이라는 점을 고려하여 저렴하고 대용량의 디스크를 저장용으로 사용하는 것이 일반적입니다. 시스템의 메모리는 수십 기가바이트에 불과하지만 하드 드라이브 용량은 수 테라바이트에 이를 수도 있습니다. Redis는 주로 메모리를 기반으로 고성능, 높은 동시성 읽기 및 쓰기 작업을 수행합니다. 예를 들어, 메모리가 제한되어 있으므로 redis는 10G만 사용할 수 있습니다. 여기에 20G의 데이터를 쓰면 어떻게 될까요? 물론 10G 데이터는 삭제되며, 10G 데이터는 그대로 유지됩니다. 어떤 데이터를 삭제해야 합니까? 어떤 데이터를 보관해야 합니까? 당연히 자주 사용하지 않는 데이터는 삭제하고 자주 사용하는 데이터는 보관해야 합니다. Redis의 만료 정책은 데이터가 만료되더라도 메모리를 계속 점유하도록 결정합니다.
Redis에서는 사용된 메모리가 최대 메모리 상한(used_memory>maxmemory)에 도달하면 해당 오버플로 제어 전략이 트리거됩니다. 특정 정책은 maxmemory-policy 매개변수로 제어됩니다.
Redis는 6가지 전략을 지원합니다.
noeviction: 기본 전략은 데이터를 삭제하지 않고 모든 쓰기 작업을 거부하며 클라이언트 오류 메시지를 반환합니다(오류). 메모리를 사용할 때는 OOM 명령이 허용되지 않습니다. 현재 Redis만 가능합니다. 읽기 작업에 응답합니다
LRU 알고리즘에 따라 시간 초과 속성(만료)이 포함된 키 값을 삭제하고 충분한 공간을 해제합니다. 삭제할 수 있는 키 개체가 없는 경우 퇴거 없음 전략으로 돌아갑니다.
휘발성-random: 충분한 공간이 만들어질 때까지 만료된 키를 무작위로 삭제합니다.
allkeys-lru: 여부에 관계없이 LRU 알고리즘에 따라 키를 삭제합니다. 데이터가 있는지 없는지 충분한 공간이 만들어질 때까지 시간 초과 속성을 설정합니다.
allkeys-random: 충분한 공간이 만들어질 때까지 모든 키를 무작위로 삭제합니다(권장하지 않음)
휘발성-ttl: ttl(남은 시간) 기준 키-값 객체(TTL) 속성 중 최근 만료되는 데이터를 삭제하세요. 그렇지 않은 경우 noeviction 전략으로 돌아갑니다
LRU: Least Recent Used, 가장 최근에 사용되지 않은 캐시된 요소에는 타임스탬프가 있습니다. 캐시 용량이 가득 차서 새 요소를 캐시하기 위해 공간을 만들어야 하는 경우 요소는 기존 캐시 요소 중 현재 시간에서 가장 먼 타임스탬프를 가진 항목이 캐시에서 지워집니다.
메모리 오버플로 제어 전략은 config set maxmemory-policy{policy}를 사용하여 동적으로 구성할 수 있습니다. 쓰기 명령은 메모리 오버플로 시 빈번한 메모리 복구 실행으로 이어지며 이는 매우 비용이 많이 듭니다. 마스터-슬레이브 복제 아키텍처에서는 메모리 복구 작업에 해당하는 삭제 명령이 마스터의 데이터 일관성을 보장하기 위해 슬레이브 노드에 동기화됩니다. 및 슬레이브 노드로 인해 쓰기 증폭이 발생합니다.
Redis 서버에서 채택한 만료 전략은 지연 삭제 + 일반 삭제
지연 삭제:
모든 Redis 라이브러리에는 모든 키의 만료 시간을 저장하는 만료 사전이 포함되어 있습니다. 클라이언트는 키를 읽을 때 먼저 만료 사전에서 키가 만료되었는지 확인합니다. 키가 만료된 경우 삭제 작업을 수행하고 빈 값을 반환합니다. 이 전략은 CPU 비용을 절약하기 위한 것이지만, 이 방법을 단독으로 사용하면 만료된 키에 액세스하지 않으면 제때에 삭제되지 않아 메모리가 제때에 해제되지 않는 문제가 있습니다.
예약 삭제:
Redis는 기본적으로 초당 10번의 만료 검색을 실행합니다(실행 횟수는 redis.conf의 hz 구성을 통해 수정됨). 대신에 적응형 알고리즘을 사용하여 키의 만료 비율에 따라 키를 재활용하고 다음과 같은 두 가지 속도 모드를 사용합니다.
1. 만료된 사전에서 20개의 키를 무작위로 꺼냅니다.
2. 키 20개
3 .만료된 키 비율이 25%를 초과하는 경우 1단계와 2단계를 반복합니다
검사로 인해 과도한 주기가 발생하지 않도록 예약된 삭제 예약 작업을 실행 중이므로 외부에 서비스를 제공할 수 없습니다. 스레드가 정체되고 스캔 시간이 증가합니다. 상한은 기본값은 25밀리초입니다(즉, 기본적으로 느린 모드에서 25밀리초가 완료되지 않으면 차단 모드로 전환됩니다. 모드는 1밀리초이며 2초에 한 번만 실행할 수 있습니다. 느린 모드가 완료되면 정상적으로 종료되고 빠른 모드로 다시 전환됩니다.)
1. 먼저 캐시에서 데이터를 가져오고, 가져오지 못한 경우에는 데이터베이스에서 데이터를 가져오고 캐시에 저장됩니다.
2. 캐시를 먼저 삭제한 후 데이터베이스를 업데이트하세요. 이 작업에는 큰 문제가 있습니다. 캐시에서 데이터 업데이트 요청이 삭제된 후 이때 캐시가 삭제되었기 때문에 또 다른 읽기 요청이 수신됩니다. , 데이터베이스를 직접 읽습니다. 읽기 작업에 대한 데이터는 오래되었으며 후속 읽기 요청은 모든 이전 데이터에 액세스합니다.
3. 먼저 데이터베이스를 업데이트한 다음 캐시를 삭제하세요(권장). 데이터베이스에 쓴 후 캐시를 업데이트하는 것은 어떨까요? 주된 이유는 두 번의 동시 쓰기 작업으로 인해 더티 데이터가 발생할 수 있기 때문입니다.
모든 데이터를 캐싱하는 것은 부분 데이터보다 더 다양하지만 실제 경험에 따르면 애플리케이션에는 오랫동안 몇 가지 중요한 속성만 필요합니다.
모든 데이터를 캐싱하면 부분 데이터보다 더 많은 공간을 차지합니다. 다음과 같은 문제가 있습니다.
모든 데이터가 메모리 낭비를 유발합니다.
모든 데이터는 매번 대량의 네트워크 트래픽을 발생시킬 수 있고, 비교적 오랜 시간이 걸릴 수 있으며, 극단적인 경우에는 네트워크를 차단할 수도 있습니다.
모든 데이터의 직렬화 및 역직렬화로 인한 CPU 오버헤드가 더 큽니다.
전체 데이터에는 분명한 이점이 있지만 일부 데이터에 새 필드를 추가하려면 비즈니스 코드를 수정하고 일반적으로 캐시된 데이터를 새로 고쳐야 합니다.
위 내용은 Redis 캐시 업데이트 전략은 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!