이 글은 Redis고빈도 인터뷰 질문을 요약하고 공유합니다. 도움이 필요한 친구들이 참고할 수 있기를 바랍니다.
면접관의 관점에서 이 질문의 목적은 캐싱에 대한 지식뿐만 아니라 캐싱을 기반으로 비즈니스 처리 및 아키텍처 개선 능력을 테스트하는 것입니다. 이 질문은 당연히 자신을 자유롭게 표현할 수 있게 하고, 자신이 가장 잘 알고 있는 지식 포인트로 면접관을 이끌어갈 수 있는 기회를 제공하므로, 이 기회를 최대한 활용하여 면접관에게 좋은 인상을 주어야 합니다. 이 질문에 대해 잘 이야기할 수 있다면 몇 시간 동안 심도 있는 소통이 가능합니다. 한 세션이면 기본적으로는 쉽게 해결할 수 있습니다. [관련 추천 : Redis 영상 튜토리얼]
하지만 바로 채팅 죽지는 마세요, 채팅이 너무 얕아서, 그럼 기본적으로 돌아가서 알림을 기다리세요...
예를 들어, 답변 방법은 다음과 같습니다.
많은 분들이 이 답변이 맞다고 말씀하실 거예요! 그렇죠, 그렇죠. 하지만 자신에게 주어진 기회가 쓸모없다는 느낌은 늘 있습니다.
지금 면접관님은 이런 생각을 하고 계십니다.
면접관의 십팔용평 손바닥을 거부하고 싶지 않다면, 솔선하여 면접관의 흥미를 불러일으키고, 자신의 구조(수평 폭과 깊이)를 개선하는 데 앞장서고, 알고 있는 것을 활용해야 합니다. 가능한 한 많이 말하세요.
예를 들어 다음과 같은 답변 방법이 있습니다.
제 이해도는 대략 이 면접관님과 같습니다! !
고성능: 고성능의 가장 큰 기준은 빠른 응답 시간입니다. Redis는 메모리 스토리지를 기반으로 하며 빠른 CPU 액세스 속도를 가지고 있습니다. 또한 Redis의 데이터 구조, 내부 스레드 모델 및 네트워크 I/O 모델 설계에 대한 극단적인 최적화는 Redis가 고성능 스토리지 데이터베이스임을 결정합니다. 유일한 단점은 메모리가 상대적으로 비싸고 리소스가 일반적으로 제한되어 있다는 점입니다. 따라서 매우 큰 데이터에 대한 캐시 아키텍처는 일반적으로 Redis 성능이 저하될 수 있으므로 Redis에 과도하게 큰 데이터를 저장하지 않습니다.
높은 동시성: 높은 동시성의 일반적인 지표에는 응답 시간(응답 시간), 처리량(처리량), 초당 쿼리 속도 QPS(초당 쿼리) 및 동시 사용자 수가 포함됩니다. Redis는 단일 프로세스 단일 스레드 모델입니다. 그러나 Redis는 실제로 높은 동시성 비즈니스 시나리오에서 강력한 도구입니다. 현재 Redis의 QPS는 100,000 또는 심지어 100만 수준에 도달할 수 있습니다. 이는 절대적으로 높은 동시성입니다.
고가용성: Redis 고가용성은 주로 마스터-슬레이브 복제, 센티넬(센티넬 모드) 및 클러스터(클러스터 모드)에 반영됩니다.
제가 이해한 내용은 대략 이 면접관님과 같습니다! !
Redis의 단일 스레드는 Redis6 출시 이후 단일 스레드를 사용하여 명령 작업을 실행하는 것을 의미합니다.
제가 이해한 바는 대략 이렇습니다. 면접관님! !
Redis에는 String, List, Hash, Set 및 ZSet의 5가지 기본 데이터 유형이 있으며, Bitmaps, Geospatial 및 HyperLogLog의 3가지 특수 데이터 유형도 있습니다.
데이터 유형 | 간단한 설명 | 사용 시나리오 |
---|---|---|
String | string(string)은 Redis에서 가장 간단하고 가장 널리 사용되는 데이터 구조입니다. 문자열(string)은 수정을 허용하는 동적 문자열입니다. 구조적 구현은 Java의 ArrayList와 유사합니다(기본적으로 크기 10의 초기 배열이 구성됨). 이는 pre라고도 알려진 메모리 중복 할당 아이디어입니다. - 할당; 이 아이디어는 확장으로 인한 성능 소모를 줄일 수 있습니다. 문자열(문자열)의 크기가 확장 임계값에 도달하면 문자열(문자열)이 확장됩니다. 문자열(문자열) 확장에는 세 가지 주요 상황이 있습니다. 1. 길이가 1MB 미만이고 확장이 2배가 됩니다. 원본 크기, 길이 = 길이 * 2 2. 길이는 1MB보다 크고, 확장 후 1MB씩 증가합니다. 길이 = 길이 + 1MB 3. 문자열의 최대 길이는 512MB입니다. | 캐시, 카운터, 분산 잠금 등 |
List | Redis의 목록은 Java 언어의 LinkedList와 동일합니다. 이는 이중 연결 목록 데이터 구조이며(그러나 이 구조는 나중에 소개될 더 영리하게 설계되었습니다) 순차 순회를 지원합니다. 연결리스트 구조의 삽입과 삭제 연산은 시간복잡도가 O(1)로 빠르지만 질의는 시간복잡도가 O(n)로 느리다. Redis의 목록(list)은 단순한 것이 아닙니다. LinkedList, 그러나 퀵리스트 - "빠른 목록"인 퀵리스트는 여러 개의 ziplist(압축 목록)로 구성된 양방향 목록입니다. | 링크된 목록, 비동기 대기열, Weibo 팔로어 타임라인 목록... |
Hash | Redis 해시(사전)는 Java 언어의 HashMap과 동일합니다. 이는 해시 값에 따라 배포되는 순서가 지정되지 않은 사전입니다. 내부 요소는 키-값 쌍으로 저장됩니다. 해시(딕셔너리)의 구현도 Java의 HashMap(JDK1.7) 구조와 일치합니다. 데이터 구조도 배열 + 연결 목록으로 구성된 2차원 구조입니다. 해시 충돌이 발생하면 사용됩니다. 연결 목록은 배열 노드에 연결됩니다. Redis의 해시(딕셔너리)에 저장되는 값은 문자열 값만 가능합니다. 또한 확장은 Java의 HashMap과 다릅니다. Java의 HashMap은 용량 확장 시 한 번에 완료되는 반면, Redis는 핵심 액세스가 단일 스레드 성능 문제라는 점을 고려하고 고성능을 추구하기 위해 점진적인 재해시 전략을 채택합니다. 점진적 재해시는 한 번 완료되지 않고 여러 번 완료됨을 의미하므로 이전 해시 구조를 유지해야 합니다. 따라서 Redis의 해시(사전)는 재해시 후 이전 해시 구조와 새 해시 구조를 갖게 됩니다. 모든 값이 새 해시로 이동된 후에야 새 해시가 이전 해시를 완전히 대체합니다. | 사용자 정보, 해시 테이블... |
Set | Redis의 집합(set)은 Java 언어의 HashSet과 동일하며 내부 키-값 쌍은 순서가 없고 고유합니다. 모든 값이 null인 특수 사전을 내부적으로 구현합니다. 컬렉션의 마지막 요소가 제거되면 데이터 구조가 자동으로 삭제되고 메모리가 회수됩니다. | 중복 제거 기능, 좋아요, 싫어요, 공통 친구... |
ZSet | zset(ordered set)은 Redis에서 가장 자주 묻는 데이터 구조입니다. Java 언어의 SortedSet과 HashMap의 조합과 유사하며, 한편으로는 내부 값의 고유성을 보장하기 위해 set을 사용하고, 다른 한편으로는 값의 점수(가중치)를 기준으로 정렬합니다. 이 정렬 기능은 Skip List를 통해 구현됩니다. zset(ordered set)의 마지막 요소 값이 제거된 후 데이터 구조가 자동으로 삭제되고 메모리가 재활용됩니다. | 팬 목록, 학생 성적 정렬, 트래픽 순위, 클릭 순위... |
비트맵 | 비트맵은 비트맵이라고 하며 엄밀히 말하면 데이터 유형이 아닙니다. 비트맵의 맨 아래 레이어는 문자열(키-값) 바이트 배열입니다. 일반적인 get/set를 사용하여 비트맵의 내용을 직접 얻고 설정할 수도 있고, Redis에서 제공하는 비트맵 작업 getbit/setbit를 통해 바이트 배열을 "비트 배열"로 처리할 수도 있습니다. 비트맵의 "비트 배열"의 각 셀은 0과 1만 저장할 수 있습니다. 비트맵에서는 배열의 첨자를 오프셋이라고 합니다. 비트맵 설정 시 키가 존재하지 않는 경우 새 문자열이 자동으로 생성됩니다. 설정된 오프셋이 기존 콘텐츠의 범위를 초과하면 비트 배열이 자동으로 0으로 확장됩니다 | 직원 출퇴근... |
Geospatial | Geospatial은 Redis 버전 3.2 이후에 추가된 지리적 위치 GEO 모듈입니다. | WeChat 근처에 있는 사람들이 온라인으로 "인근 레스토랑"을 주문합니다... |
HyperLogLog | HyperLogLog는 카디널리티 통계를 수행하는 데 사용되는 알고리즘입니다. 부정확한 중복 제거 계산 체계의 표준 오류(이 부정확성은 그다지 부정확하지 않음)는 0.81%입니다. 이 오류 범위는 UV와 같은 통계에 허용됩니다. HyperLogLog의 장점은 입력 요소의 개수나 양이 매우 클 경우 카디널리티 계산을 위한 저장 공간이 고정되어 있다는 것입니다. Redis에서 각 HyperLogLog 키의 메모리 비용은 12KB에 불과하며 거의 2^64개의 서로 다른 기준을 계산할 수 있습니다. 그러나 HyperLogLog는 카디널리티의 크기(즉, 데이터 세트의 크기와 세트 수)만 계산할 수 있습니다. 요소 자체를 저장할 수 없으며 요소 자체를 세트 컬렉션처럼 저장할 수 없습니다. 요소를 반환합니다. | 자외선 등 주요 통계 |
면접관님의 제가 이해한 내용입니다! !
Redis의 데이터 구조는 EXPIRE 키 초를 통해 키의 만료 시간(TTL)을 설정할 수 있습니다. 우리는 또한 Redis 키가 만료되면 자동으로 삭제될 것이라고 생각하는 데 익숙합니다. 분명히 이 생각은 옳지 않습니다. Redis의 설계는 성능/메모리 등 포괄적인 요소를 고려하고 일련의 만료 전략을 설계합니다.
능동 삭제(지연 삭제)는 키에 접근할 때 먼저 키가 만료되었는지 확인하고, 만료되면 키를 삭제하는 것을 의미합니다. 적극적으로 삭제했습니다.
수동 삭제(주기적 전략)는 Redis 서버가 정기적으로 키 만료 시간을 무작위로 테스트하는 것을 의미하며, 만료되면 수동적으로 삭제됩니다. 만료되어 더 이상 영원히 액세스할 수 없는 일부 키가 있기 때문에 수동 삭제가 필수적입니다. 활성 삭제에 의존하는 경우 메모리를 영구적으로 차지하게 됩니다.
고성능 서비스를 보장하기 위해 Redis는 만료된 키를 수동적으로 삭제하고 탐욕적 전략/확률적 알고리즘을 채택합니다. 기본적으로 구체적인 전략은 다음과 같습니다.
1. 사전(만료 시간이 설정됨) 키 세트에서 무작위로 20개 키를 선택하고 만료되었는지 확인합니다
2. 만료된 키를 삭제합니다
또한 개발자는 Redis 캐시 아키텍처를 설계할 때 많은 수의 키를 동일한 만료 시간으로 설정하는 것을 최대한 피(금지)하도록 주의해야 합니다. 수동 삭제와 결합하면 Redis가 만료된 키를 수동적으로 삭제하면 서비스를 일시적으로 사용할 수 없게 됩니다. 동시에 많은 수의 키가 만료되면 이로 인해 수동 키 삭제의 세 단계가 여러 번 순환되어 Redis가 작동하게 됩니다. 대규모 교통 프로젝트에서는 이러한 상황이 용납되지 않습니다.
따라서 이러한 상황을 방지하려면 허용된 만료 시간이 매우 정확할 필요가 없는 일부 키를 보다 임의적인 만료 시간으로 설정하여 지연 시간을 줄여야 합니다.
이것에 대한 저의 이해는 대략 이 면접관님과 같습니다! !
분산 시나리오에서 우리의 일반적인 분산 잠금 솔루션에는 다음이 포함됩니다(방법을 알고 있다면 다른 두 개를 여기에 가져올 수 있습니다. 그렇지 않다면 당황하지 마세요!):
분산 잠금은 다음을 기반으로 구현됩니다. 데이터베이스 잠금 메커니즘에 대해
Zookeeper를 기반으로 구현된 분산 잠금
Redis가 분산 잠금을 구현하는 솔루션은 다음과 같습니다.
Redis가 독립형 환경인 경우 Redis에서 제공하는 원자 명령을 통해 분산 잠금을 구현할 수 있습니다.
키 값을 [EX초] [PX 밀리초] [NX|XX]
설정하여 A 추가 B에 의해 잠금이 삭제되었습니다. 잠금 시 클라이언트의 잠금 태그가 전달될 수 있습니다. 클라이언트가 전달한 태그가 잠금 태그와 동일한 경우에만 잠금 해제가 허용됩니다. 그러나 Redis에서는 이러한 기능을 제공하지 않습니다. Lua 스크립트는 여러 명령어의 원자적 실행을 보장할 수 있기 때문에 처리할 Lua 스크립트만 전달할 수 있습니다. 마지막으로 잠금 시간 초과 문제를 고려해야 합니다. 클라이언트가 잠금을 해제하지 않으면 확실히 작동하지 않습니다. 따라서 잠금은 지정된 시간 초과 시간 범위 내에 다른 클라이언트가 잠금을 해제하지 않는다는 것만 보장할 수 있습니다. 이런 상황은 다음과 같이 최적화할 수 있습니다:
Redis 분산 잠금에서는 긴 작업을 실행하지 말고 잠금 간격을 최대한 짧게 실행하세요. 단일 JVM 잠금의 동기화 최적화와 마찬가지로 잠금 범위 최적화를 고려할 수 있습니다.
적절한 잠금 시간 초과를 추정하기 위해 더 많은 스트레스 테스트와 실제 시나리오의 온라인 시뮬레이션 테스트를 수행합니다.
분산 환경인 경우 새 문제가 추가됩니다. 예를 들어 센티넬 + 하나의 마스터 및 다중 슬레이브 환경에서는 클라이언트는 마스터 노드에 잠금을 신청할 수 있지만 동기화가 완료되지 않고 마스터 노드가 다운되어 새로 선출된 마스터 노드에 대한 잠금이 유효하지 않습니다.
이 상황에 대한 처리는 우선 Redis 마스터-슬레이브 직접 동기화로는 어떤 경우에도 데이터 손실 문제를 해결할 수 없습니다. 따라서 우리는 잠금 애플리케이션을 하나의 Redis에서 여러 독립형 Redis 잠금 애플리케이션으로 변경하는 것을 고려합니다. 대부분의 애플리케이션만 성공합니다. 이 아이디어는 RedLock입니다.
RedLock은 여러 Redis 인스턴스를 사용합니다. 각 인스턴스 간에는 마스터-슬레이브 관계가 없으며 서로 독립적입니다. 잠금 시 클라이언트는 노드의 절반 이상이 성공적으로 설정되면 잠금 명령을 보냅니다. 잠금에 성공했습니다. 잠금을 해제할 때 잠금을 해제하려면 모든 노드에 del 명령을 보내야 합니다.
Red Lock은 마스터-슬레이브 동기화 문제를 해결하지만 새로운 복잡한 문제를 야기합니다.
그래서 RedLock에서는 적용된 잠금의 최소 유효 기간을 계산해야 합니다. 클라이언트가 잠금을 성공적으로 적용하고, 첫 번째 키가 성공적으로 설정된 시간을 TF, 마지막 키가 성공적으로 설정된 시간을 TL, 잠금 시간 초과가 TTL, 서로 다른 프로세스 간의 클럭 차이가 CLOCK_DIFF라고 가정하고, 잠금의 최소 유효 기간은 다음과 같습니다.
TIME = TTL - (TF- TL) - CLOCK_DIFF
Redis를 사용하여 서버 가동 중지 시간 및 기타 가용성 문제와 분리할 수 없는 분산 잠금을 구현합니다. 여기서 RedLock의 경우 여러 개가 있더라도 서버가 잠금을 적용할 때 서버가 다운된 후 수행할 작업도 고려해야 합니다. 공식적인 권장 사항은 AOF 지속성을 사용하는 것입니다.
단, AOF 지속성은 정상적인 SHUTDOWN 명령에 대해서만 재시작 및 복원이 가능합니다. 그러나 정전이 발생하면 서버가 재시작될 때 정전까지의 마지막 지속성 잠금 데이터가 손실될 수 있습니다. 분산 잠금 의미가 잘못된 경우가 발생할 수 있습니다. 따라서 이러한 상황을 방지하기 위해 Redis 서비스를 다시 시작한 후 최대 클라이언트 TTL(잠금 응용 프로그램 서비스가 제공되지 않음) 내에서 Redis 서비스를 사용할 수 없도록 하는 것이 공식적인 권장 사항입니다. 이렇게 하면 문제가 실제로 해결될 수 있지만, 이는 Redis 서버의 성능에 확실히 영향을 미치며, 대부분의 노드에 이런 일이 발생하면 시스템을 전역적으로 사용할 수 없게 됩니다.
이것에 대한 저의 이해는 대략 이 면접관님과 같습니다! !
Redis가 매우 빠른 이유는 Redis 데이터가 메모리에 저장되어 있기 때문에 서버가 다운되거나 전원이 꺼지면 모든 데이터가 손실되기 때문입니다. 오류로 인해 모든 Redis 데이터가 손실되지 않도록 하기 위해 두 가지 메커니즘이 사용됩니다. 이 메커니즘을 Redis의 지속성 메커니즘이라고 합니다.
Redis에는 두 가지 지속성 메커니즘이 있습니다.
RDB(Redis DataBase)는 메모리의 지정된 데이터 세트 스냅샷을 참조합니다. RDB는 메모리 스냅샷(메모리 데이터의 바이너리 직렬화 형식) 형태로 유지됩니다. 매번 Redis에서 스냅샷이 생성되어 데이터를 완전히 백업합니다.
장점:
단점:
RDB 트리거 규칙은 수동 트리거와 자동 트리거라는 두 가지 범주로 나뉩니다.
자동 트리거:
트리거 규칙 구성
종료 트리거
수동 트리거:
save
bgsave
AOF(Append Only File)는 메모리를 수정하는 모든 명령(쓰기 작업)을 별도의 로그 파일에 기록하고, Redis 명령을 다시 시작하면 AOF 파일을 실행하여 데이터를 복원합니다. . AOF는 실시간 데이터 지속성 문제를 해결할 수 있으며 현재 Redis 지속성 메커니즘의 주류 지속성 솔루션입니다(하이브리드 지속성에 대해서는 나중에 4.0 이후에 설명하겠습니다).
장점:
단점:
AOF 로그는 파일 형식으로 존재합니다. 프로그램이 AOF 로그 파일에 쓸 때 해당 내용은 실제로 커널에서 할당한 메모리에 기록됩니다. 파일 설명자의 경우 커널은 버퍼의 데이터를 디스크에 비동기적으로 플러시합니다. 버퍼의 데이터가 디스크로 다시 플러시되기 전에 서버가 충돌하면 데이터가 손실됩니다.
그래서 Redis는 Linux 운영 체제의 glibc에서 제공하는 fsync(int fid)를 호출하여 버퍼의 데이터가 손실되지 않도록 커널 버퍼의 지정된 파일 내용을 디스크로 강제로 다시 보냅니다. 하지만 이는 IO 작업으로 Redis의 성능에 비해 매우 느리기 때문에 자주 실행할 수는 없습니다.
Redis 구성 파일에는 세 가지 플러시 버퍼 구성이 있습니다.
appendfsync Always
모든 Redis 쓰기 작업은 AOF 로그에 기록됩니다. Redis 쓰기가 상대적으로 적더라도 Redis의 동시성은 Linux 운영 체제에서 제공하는 최대 새로 고침 빈도를 훨씬 초과하기 때문에 이론적으로 Linux 운영 체제는 이 구성을 처리할 수 없습니다. , 이 구성은 IO 작업을 포함하기 때문에 성능도 많이 소모하므로 이 구성은 기본적으로
appendfsync Everysec
을 사용하지 않습니다. 이 Redis 구성에서는 매초 버퍼의 데이터를 AOF 파일로 새로 고칩니다. file 기본 전략은 성능과 데이터 무결성 간의 절충과 호환됩니다. 이 구성을 사용하면 이론적으로 데이터는 약 1초 안에 손실됩니다
appendfsync no
Redis 프로세스는 버퍼를 적극적으로 새로 고치지 않습니다. 데이터는 다음 위치에 저장됩니다. AOF 파일이지만 판단을 위해 운영 체제에 직접 전달되는 작업입니다. 이 작업은 권장되지 않으며 데이터 손실 가능성이 매우 높습니다.
앞서 AOF의 단점을 언급했을 때 AOF는 Redis 쓰기 명령을 저장하기 위한 로그 추가 형식이라고 말했습니다. 이로 인해 중복된 명령 저장량이 많아 AOF 로그 파일이 매우 커지게 됩니다. 메모리만 차지할 뿐 아니라 복구 속도도 매우 느려지므로 Redis는 이 문제를 해결하기 위해 다시 쓰기 메커니즘을 제공합니다. Redis의 AOF 지속성 메커니즘은 재작성을 수행한 후 데이터를 복원하기 위한 최소 명령어 세트만 저장합니다. 수동으로 트리거하려면 다음 명령어를 사용할 수 있습니다.
bgrewriteaof
Redis 4.0 이후의 재작성은 RDB 스냅샷과 AOF 명령어를 결합하여 사용합니다. 이런 방식으로 AOF 파일의 헤더는 RDB 스냅샷 데이터의 바이너리 형태이고, 테일은 스냅샷이 생성된 후 발생한 쓰기 작업의 명령입니다.
AOF 파일 재작성은 Redis 성능에 일정한 영향을 미치기 때문에 자동 재작성을 임의로 수행할 수 없습니다. Redis는 두 가지 조건이 모두 충족되는 경우에만 재작성이 발생합니다. auto-aof-rewrite-percentage 100: 파일의 메모리가 원래 메모리의 2배에 도달한 경우를 의미
auto-aof-rewrite-min-size 64mb: 파일 다시 쓰기를 위한 최소 메모리 크기를 의미
또한, Redis 4.0 이후의 대부분의 사용 시나리오에서는 지속성 메커니즘으로 RDB 또는 AOF만 사용하지 않지만 두 가지의 장점을 모두 고려합니다.
마지막으로 둘을 요약하자면 어떤게 더 나은가요?둘 다 켜는 것을 권장합니다
이것에 대한 저의 이해는 대략 이 면접관님과 같습니다! !
Redis는 메모리 저장 기반의 키-값 데이터베이스입니다. 메모리는 빠르지만 공간은 작습니다. 물리적 메모리가 상한선에 도달하면 시스템이 매우 느리게 실행되므로 최대값을 설정하겠습니다. Redis 메모리 메모리 재활용은 설정된 임계값에 도달하면 트리거됩니다. Redis는 다양한 메모리 제거 전략을 제공합니다:
noeviction:Redis 3.0에서 maxmemory_samples를 10으로 설정하면 Redis의 대략적인 LRU 알고리즘이 실제 LRU 알고리즘과 매우 유사하지만, 당연히 maxmemory_samples를 10으로 설정하면 매번 샘플링되는 샘플 데이터로 인해 maxmemory_samples를 5로 설정하는 것보다 CPU 컴퓨팅 시간이 더 많이 소모됩니다. 증가하면 계산 시간도 늘어납니다.
Redis3.0의 LRU 알고리즘은 Redis2.8의 LRU 알고리즘보다 더 정확합니다. Redis3.0은 키가 제거될 때마다 maxmemory_samples와 동일한 크기의 제거 풀을 추가하기 때문입니다. 제거 풀에서 제거 키를 비교하여 최종적으로 가장 오래된 키를 제거합니다. 실제로 제거를 위해 선택한 키를 모아서 다시 비교하면 가장 오래된 키가 제거됩니다.
LRU에는 키의 인기를 정확하게 나타낼 수 없다는 단점이 있습니다. 키에 액세스한 적이 없고 메모리 제거가 발생하기 직전에 사용자가 액세스한 경우 이는 LRU 알고리즘에서 고려됩니다. . LFU(Least 빈번하게 사용됨)는 Redis 4.0에서 도입된 제거 알고리즘입니다. 키의 액세스 빈도를 비교하여 키를 제거합니다.
LRU와 LFU의 차이점:
LFU 모드에서는 Redis 객체 헤더의 24비트 lru 필드가 두 개의 세그먼트로 나누어 저장됩니다. 상위 16비트는 ldt(Last Decrement Time)를 저장하고 하위 8비트는 logc(Logistic Counter)를 저장합니다. 상위 16비트는 카운터가 마지막으로 감소한 시간을 기록하는 데 사용됩니다. 8비트만 있으므로 Unix 분 타임스탬프 모듈로 2^16을 저장합니다. 16비트가 나타낼 수 있는 최대 값은 65535(65535/24/60)입니다. ≒45.5), 약 45.5일이 지나면 다시 돌아옵니다(뒤로 돌아간다는 것은 모듈로 값이 다시 0부터 시작한다는 의미입니다).
하위 8비트는 액세스 빈도를 기록하는 데 사용됩니다. 8비트가 나타낼 수 있는 최대 값은 255입니다. Logc는 실제로 Rediskey 액세스 횟수를 기록할 수 없습니다. 실제로 저장되는 이름에서 알 수 있습니다. 각각의 새로운 추가에 대한 로그입니다. 키의 logc의 초기 값은 5(LFU_INITI_VAL)입니다. 이는 새로 추가된 값이 선택되지 않고 키가 포함될 때마다 먼저 제거된다는 것을 보장합니다. 또한, logc는 시간이 지남에 따라 감소합니다.
로지스틱 카운터는 성장할 뿐만 아니라 붕괴할 것입니다. 성장 및 붕괴의 규칙도 redis.conf를 통해 구성할 수 있습니다.
면접관님의 제가 이해한 내용입니다! !
캐시 분석:
매우 자주 액세스되는 핫스팟 키가 중앙 집중식 높은 동시 액세스 상황에 있음을 의미합니다. 키가 무효화되면 많은 수의 요청이 캐시에 침투하여 직접 요청하게 됩니다. 데이터베이스는 Redis를 직접 통과합니다.
해결책:
캐시 침투:
캐시나 데이터베이스에 존재하지 않는 데이터에 대한 요청을 의미합니다. 이러한 상황은 일반적으로 해커에 의해 발생하며, 방어가 이루어지지 않으면 쉽게 데이터베이스가 종료될 수 있습니다. 요청. 예를 들어 해커가 음수 ID를 사용하여 테이블 중 하나를 쿼리하는 경우 일반적으로 ID는 음수로 설정되지 않습니다.
해결책:
캐시 사태:
캐시 사태는 많은 수의 캐시가 동시에 실패할 때 발생하며 이로 인해 데이터베이스가 즉시 충돌하게 됩니다(높은 동시성 시나리오). 이 경우 캐시가 그렇지 않은 경우 복원하면 데이터베이스가 쓸모 없게 되거나 계속해서 패배하게 됩니다.
해결책:
이렇게 대답할 뻔한 면접관의 얼굴에는 오랫동안 잃어버린 미소가 보였고 우리는 어쩔 수 없었습니다. 이 트릭을 사용하세요. 이번에는 인터뷰가 있습니다.
물론, 이 지식 포인트는 몇 문장으로 명확하게 설명할 수 없으므로 이 글을 읽어 보시고 쉽게 붙잡으실 것을 권합니다
"Redis Distributed - Master-Slave 복제, Sentinel, Clustering이 철저하게 구현되어 있습니다. 이해됨 》
이 기사는 https://juejin.cn/post/7019088999792934926
저자: Li Zi捌
더 많은 프로그래밍 관련 지식을 보려면 다음을 방문하세요: 프로그래밍 입문! !
위 내용은 2023년 Redis 고빈도 면접 질문 공유(답변 분석 포함)의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!