이 기사에서는 자주 발생하는 Redis 인터뷰 질문을 모아서 공유하고, 데이터 구조, 메모리 모델, IO 모델, 영구 RDB 등과 관련된 Redis의 핵심 지식 포인트를 안내합니다. 도움이 되기를 바랍니다. !
많은 사람들이 K/V NoSQl 인메모리 데이터베이스, 단일 스레드라는 것만 알고 있습니다. 이는 Redis를 완전히 이해하지 못하고 더 이상 질문을 계속할 수 없기 때문입니다.
이 질문은 기본적인 이해입니다. Redis의 다양한 데이터 유형의 기본 데이터 구조에서 완전히 메모리, IO 다중화 네트워크 모델, 스레드 모델, 점진적 재해시를 기반으로 구현할 수 있습니다.
얼마나 빠른지 먼저 이야기해 보겠습니다. 공식 데이터에 따르면 Redis의 QPS는 약 100,000(초당 요청 수)에 도달할 수 있습니다. 관심 있는 분은 공식 벤치마크 프로그램인 "Redis는 얼마나 빠릅니까?"를 참조하세요. 》, 주소: redis.io/topics/benc…
가로축은 연결수, 세로축은 QPS입니다.
이 사진은 수량화를 통해 면접관이 공식 문서를 읽었으며 매우 엄격하다는 느낌을 줍니다.
Redis는 디스크 데이터베이스에 비해 디스크 속도를 완전히 능가하는 메모리 기반 데이터베이스입니다.
읽기 작업과 쓰기 작업은 모두 메모리에서 완료됩니다. 메모리 작업과 디스크 작업의 차이점을 각각 비교해 보겠습니다.
디스크 호출
메모리 작동
메모리는 CPU 내부에 통합된 메모리 컨트롤러인 CPU에 의해 직접 제어되므로 메모리가 CPU에 직접 연결되어 최적의 대역폭을 누리게 됩니다. CPU와의 통신을 위해.
마지막으로 시스템의 다양한 지연을 수량화하기 위해 그림이 사용됩니다. (데이터의 일부는 Brendan Gregg에서 인용함)
MySQL을 배울 때 B+ Tree 데이터가 검색 속도를 향상시키기 위해 구조를 사용했습니다. 따라서 Redis의 빠른 속도도 데이터 구조와 관련이 있습니다.
Redis에는 총 5가지 데이터 유형이 있습니다. String、List、Hash、Set、SortedSet
.
더 빠른 속도를 추구하기 위해 하단에 하나 이상의 데이터 구조에서 다양한 데이터 유형을 지원합니다.
마 형제의 메시지: 각 데이터 유형의 기본 데이터 구조의 장점을 개별적으로 설명할 수 있습니다. 많은 사람들이 데이터 유형만 알고 있으며 기본 데이터 구조를 알려주면 사람들의 눈이 빛날 수 있습니다.
SDS에서 len은 이 문자열의 길이를 저장하고 O(1) 시간 복잡도는 문자열 길이 정보를 쿼리하는 데 사용됩니다.
공간 사전 할당: SDS가 수정된 후 프로그램은 SDS에 필요한 공간을 할당할 뿐만 아니라 사용되지 않은 공간도 추가로 할당합니다.
SDS를 단축할 때 프로그램은 초과된 메모리 공간을 회수하지 않습니다. 대신 여유 필드를 사용하여 바이트 수를 기록하고 나중에 추가 작업이 필요한 경우 이를 해제하지 않습니다. 직접 사용하십시오. 사용되지 않은 공간은 메모리 할당을 줄입니다.
압축 목록은 세 가지 데이터 유형인 List, hash 및 sorted Set의 기본 구현 중 하나입니다.
목록에 적은 양의 데이터만 있고 각 목록 항목이 작은 정수 값이거나 상대적으로 짧은 문자열인 경우 Redis는 압축된 목록을 목록 키의 기본 구현으로 사용합니다.
이렇게 하면 메모리가 콤팩트해지고 메모리가 절약됩니다.
후속 버전에서는 ziplist 및 linkedlist 대신 Quicklist를 사용하여 목록 데이터 구조를 변형했습니다.
quicklist는 ziplist와 linkedlist가 혼합된 것입니다. linkedlist를 세그먼트로 나눕니다. 각 세그먼트는 압축된 저장을 위해 ziplist를 사용하며, 여러 ziplist는 양방향 포인터를 사용하여 함께 연결됩니다.
sorted set 유형의 정렬 기능은 "skip list" 데이터 구조를 통해 구현됩니다.
스킵 리스트는 노드에 빠르게 액세스하는 목적을 달성하기 위해 각 노드의 다른 노드에 대한 여러 포인터를 유지하는 정렬된 데이터 구조입니다.
스킵 리스트는 연결된 리스트를 기반으로 여러 단계의 인덱스를 추가하며 인덱스 위치에서 여러 번의 점프를 통해 아래 그림과 같이 데이터의 위치를 빠르게 지정할 수 있습니다.
세트에 정수 값 요소만 포함되어 있고 이 세트의 요소 수가 크지 않은 경우 Redis는 메모리를 절약하기 위해 정수 세트를 세트 키의 기본 구현으로 사용합니다.
Brother Ma의 메시지: Redis의 단일 스레드는 Redis의 네트워크 IO(네트워크 IO는 버전 6.x 이후의 멀티스레딩을 사용함)와 키-값을 참조한다는 점에 유의해야 합니다. 쌍 명령 읽기 및 쓰기는 스레드에 의해 실행됩니다. Redis 지속성, 클러스터 데이터 동기화, 비동기 삭제 등은 모두 다른 스레드에 의해 실행됩니다.
Redis에 스레드가 하나만 있다고 말하지 마세요.
단일 스레드는 단일 스레드에서 Redis 키-값 쌍 읽기 및 쓰기 명령이 실행되는 것을 의미합니다.
남의 말을 토대로 블로그를 낭독하는 것이 아니라, 충분히 엄격함을 느끼게 하는 공식적인 답변에 대해 먼저 이야기해 보겠습니다.
공식 답변: Redis는 메모리 기반 작업이기 때문에 CPU는 Redis의 병목 현상이 아닙니다. Redis의 병목 현상은 머신 메모리의 크기나 네트워크 대역폭 때문일 가능성이 높습니다. 싱글 스레딩은 구현하기 쉽고 CPU에 병목 현상이 발생하지 않으므로 싱글 스레드 솔루션을 채택하는 것이 논리적입니다. 원래 주소: redis.io/topics/faq.
CPU를 최대한 활용하기 위해 멀티스레드 실행을 사용하는 것은 어떨까요?각 작업을 실행하기 전에 CPU는 작업이 로드되고 실행이 시작되는 위치를 알아야 합니다. 즉, 시스템은 CPU 컨텍스트라고 불리는 CPU 레지스터와 프로그램 카운터를 미리 설정하는 데 도움이 필요합니다.
컨텍스트를 전환할 때 일련의 작업을 완료해야 하는데 이는 리소스를 많이 소모하는 작업입니다.
멀티 스레드 개발을 도입하려면 공유 리소스의 동시 읽기 및 쓰기를 보호하기 위해 동기화 프리미티브를 사용해야 하며, 코드 복잡성이 증가하고 디버깅이 어려워집니다.싱글 스레드의 장점은 무엇인가요?
typedef struct redisObject{ //类型 unsigned type:4; //编码 unsigned encoding:4; //指向底层数据结构的指针 void *ptr; //... }robj;해시 충돌이 발생하면 어떻게 해야 하나요? Redis는
체인 해싱을 통해 충돌을 해결합니다. 즉, 동일한 버킷의 요소는 연결 목록을 사용하여 저장됩니다. 그러나 연결리스트가 너무 길면 검색 성능이 저하될 수 있으므로 Redis는 속도를 추구하기 위해 두 개의 전역 해시 테이블을 사용합니다. 기존 해시 버킷 수를 늘리고 해시 충돌을 줄이기 위해 재해시 작업에 사용됩니다.
기본적으로 키-값 쌍 데이터를 저장하려면 "해시 테이블 1"을 사용하여 시작하세요. "해시 테이블 2"에는 현재 할당된 공간이 없습니다. 점점 더 많은 데이터가 재해시 작업을 트리거하면 다음 작업이 수행됩니다.해시 테이블 1의 데이터를 해시 테이블 2로 다시 매핑하는 프로세스는 일회성 프로세스가 아니므로 Redis가 차단되고 서비스를 제공할 수 없다는 점에 유의할 가치가 있습니다.
대신 progressive rehash를 사용하여 클라이언트 요청이 처리될 때마다 "해시 테이블 1"의 첫 번째 인덱스부터 시작하여 이 위치의 모든 데이터를 "해시 테이블 2"에 복사합니다. 시간이 많이 걸리는 차단을 피하기 위해 여러 요청으로 다시 해시합니다.
Redis의 데이터 지속성은 "RDB 데이터 스냅샷" 방법을 사용하여 다운타임으로부터 신속한 복구를 달성합니다. 그러나 전체 데이터 스냅샷을 너무 자주 실행하면 두 가지 심각한 성능 오버헤드가 발생합니다.
그래서 Redis는 메모리 수정 지침을 기록하기 위해 AOF 쓰기 후 로그도 설계했습니다.
인터뷰어: RDB 메모리 스냅샷이 무엇인가요?
Redis가 "write" 명령을 실행하는 동안 메모리 데이터는 계속 변경됩니다. 소위 메모리 스냅샷은 특정 순간에 Redis 메모리에 있는 데이터의 상태 데이터를 말합니다.
특정 순간에 시간이 정지된 것과 같습니다. 사진을 찍으면 사진을 통해 특정 순간의 순간을 완벽하게 기록할 수 있습니다.
Redis도 이와 유사합니다. 특정 순간의 데이터를 파일 형식으로 캡처하여 디스크에 씁니다. 이 스냅샷 파일은 RDB 파일이라고 하며 Redis DataBase의 약어입니다.
데이터 복구를 수행할 때 RDB 파일을 메모리로 직접 읽어 복구를 완료하세요.
인터뷰어: RDB 생성 중에 Redis가 쓰기 요청을 동시에 처리할 수 있나요?
예, Redis는 운영 체제의 다중 프로세스 기록 중 복사 기술 COW(기록 중 복사)를 사용하여 스냅샷 지속성을 달성하고 데이터 일관성을 보장합니다.
Redis는 지속성 동안 하위 프로세스를 생성하기 위해 glibc 함수 fork
를 호출합니다. 스냅샷 지속성은 하위 프로세스에 의해 완전히 처리되며 상위 프로세스는 계속해서 클라이언트 요청을 처리합니다. fork
产生一个子进程,快照持久化完全交给子进程来处理,父进程继续处理客户端请求。
当主线程执行写指令修改数据的时候,这个数据就会复制一份副本, bgsave
子进程读取这个副本数据写到 RDB 文件。
这既保证了快照的完整性,也允许主线程同时对数据进行修改,避免了对正常业务的影响。
面试官:那 AOF 又是什么?
AOF 日志记录了自 Redis 实例创建以来所有的修改性指令序列,那么就可以通过对一个空的 Redis 实例顺序执行所有的指令,也就是「重放」,来恢复 Redis 当前实例的内存数据结构的状态。
Redis 提供的 AOF 配置项appendfsync
写回策略直接决定 AOF 持久化功能的效率和安全性。
aof_buf
缓冲区中的内容刷写到 AOF 文件。没有两全其美的策略,我们需要在性能和可靠性上做一个取舍。
面试官:既然 RDB 有两个性能问题,那为何不用 AOF 即可。
AOF 写前日志,记录的是每个「写」指令操作。不会像 RDB 全量快照导致性能损耗,但是执行速度没有 RDB 快,同时日志文件过大也会造成性能问题。
所以,Redis 设计了一个杀手锏「AOF 重写机制」,Redis 提供了 bgrewriteaof
bgsave
하위 프로세스가 복사본 데이터를 읽고 이를 RDB 파일에 씁니다. 이것은 스냅샷의 무결성을 보장할 뿐만 아니라 메인 스레드가 동시에 데이터를 수정할 수 있게 하여 정상적인 비즈니스에 영향을 주지 않습니다.
인터뷰어: 그럼 AOF는 무엇인가요?
🎜🎜AOF 로그는 Redis 인스턴스 생성 이후 수정된 모든 명령 시퀀스를 기록합니다. 그러면 빈 Redis 인스턴스에서 모든 명령을 순차적으로 실행, 즉 "재생"하여 현재 Redis 인스턴스의 메모리 데이터를 복원할 수 있습니다. 구조의 상태. 🎜🎜Redis에서 제공하는 AOF 구성 항목appendfsync
쓰기 저장 전략은 AOF 지속성 기능의 효율성과 보안을 직접적으로 결정합니다. 🎜🎜🎜always🎜: 동기 쓰기 저장,
🎜양쪽 모두를 위한 최선의 전략은 없습니다. 성능과 안정성 사이에서 절충점을 찾아야 합니다. 🎜🎜🎜인터뷰어: RDB에는 두 가지 성능 문제가 있으므로 AOF를 사용하지 않는 이유는 무엇입니까? 🎜🎜🎜AOF 사전 쓰기 로그는 각 "쓰기" 명령 작업을 기록합니다. RDB 전체 스냅샷처럼 성능 저하가 발생하지는 않지만 실행 속도가 RDB만큼 빠르지 않습니다. 동시에 로그 파일이 너무 크면 성능 문제도 발생합니다. 🎜🎜그래서 Redis는 킬러 "AOF 재작성 메커니즘"을 설계했습니다. Redis는 AOF 로그를 줄이기 위해aof_buf
버퍼의 콘텐츠는 쓰기 명령이 실행된 직후 AOF 파일로 플러시됩니다. 🎜🎜🎜everysec🎜: 쓰기 명령이 실행된 후 로그는 AOF 파일 버퍼에만 기록되고 버퍼 내용은 매초 디스크에 동기화됩니다. 🎜🎜🎜no: 🎜 운영 체제에 의해 제어되며 쓰기 실행이 완료된 후 로그가 AOF 파일 메모리 버퍼에 기록되고 운영 체제가 이를 디스크에 플러시할 시기를 결정합니다. 🎜bgrewriteaof
명령을 제공합니다. 🎜🎜원칙은 하위 프로세스를 열어 메모리를 순회하고 이를 일련의 Redis 작업 지침으로 변환하여 새로운 AOF 로그 파일로 직렬화하는 것입니다. 직렬화가 완료되면 작업 중 발생한 증분 AOF 로그가 새 AOF 로그 파일에 추가되며, 추가가 완료되면 기존 AOF 로그 파일이 즉시 교체되어 슬리밍 작업이 완료됩니다. 🎜🎜🎜🎜🎜🎜인터뷰어: 성능을 고려하면서 데이터 손실을 최대한 줄이는 방법은 무엇입니까? 🎜
Redis를 다시 시작할 때 많은 양의 데이터가 손실되므로 메모리 상태를 복원하기 위해 rdb를 거의 사용하지 않습니다. 우리는 주로 AOF 로그 재생을 사용하는데, AOF 로그 재생의 성능은 RDB에 비해 훨씬 느리기 때문에 Redis 인스턴스가 클 경우 시작하는 데 시간이 오래 걸립니다.
Redis 4.0은 이 문제를 해결하기 위해 새로운 지속성 옵션인 Hybrid persistence를 제공합니다. 증분 AOF 로그 파일과 함께 rdb 파일의 내용을 저장합니다. 여기서 AOF 로그는 더 이상 전체 로그가 아니라 지속성 시작부터 지속성 종료까지의 기간 동안 발생하는 증분 AOF 로그입니다. 일반적으로 AOF 로그의 이 부분은 매우 작습니다. 그래서
Redis가 다시 시작되면 먼저 rdb 콘텐츠를 로드한 다음 증분 AOF 로그를 재생할 수 있습니다. 이는 이전 AOF 전체 파일 재생을 완전히 대체할 수 있으며 다시 시작 효율성이 크게 향상됩니다. Redis 마스터-슬레이브 아키텍처 데이터 동기화
복제 데이터의 일관성을 보장하기 위해 마스터-슬레이브 아키텍처는 읽기-쓰기 분리 방식을 채택합니다.읽기 작업: 마스터 및 슬레이브 라이브러리 모두 실행 가능
로드 밸런싱: 마스터 노드는 쓰기 서비스를 제공하고 슬레이브 노드는 읽기 서비스를 제공하여 압력을 공유합니다. 고가용성: 센트리와 클러스터의 구현입니다. 기반은 고가용성의 초석입니다.
인터뷰어: 마스터-슬레이브 복제는 어떻게 구현되나요?
마스터-슬레이브 데이터베이스 간의 네트워크 연결 끊김 및 재연결 동기화.
인터뷰어: 첫 번째 동기화를 어떻게 달성하나요?
연결 설정:슬레이브 라이브러리는 레플리카오브를 실행하고 psync 명령을 전송하여 메인 라이브러리에 알립니다. 마스터 라이브러리가 응답을 확인한 후 마스터 라이브러리와 슬레이브 라이브러리 간의 동기화가 시작됩니다
.
마스터 라이브러리는 데이터를 슬레이브 라이브러리에 동기화합니다. 마스터는 bgsave
명령을 실행하여 RDB 파일을 생성하고 파일을 슬레이브 라이브러리로 보냅니다. 동시에 메인 라이브러리가 열립니다. 슬레이브를 기록하기 위한 각 슬레이브의 복제 버퍼 RDB 파일 구축은 수신된 모든 쓰기 명령으로 시작됩니다. 라이브러리에서 RDB를 저장하고 데이터베이스를 지운 다음 RDB 데이터를 메모리에 로드합니다.
RDB 이후에 수신된 새 쓰기 명령을 슬레이브 라이브러리로 보냅니다. RDB 파일 생성 후 쓰기 작업은 현재 RDB 파일에 기록되지 않습니다. 마스터-슬레이브 라이브러리 데이터의 일관성을 보장하기 위해 마스터 라이브러리는 RDB 파일이 생성된 후 모든 쓰기 작업을 기록하려면 복제 버퍼를 사용하세요. 그리고 내부의 데이터를 슬레이브로 보냅니다.
bgsave
命令生成 RDB 文件,并将文件发送给从库,同时主库为每一个 slave 开辟一块 replication buffer 缓冲区记录从生成 RDB 文件开始收到的所有写命令。从库保存 RDB 并清空数据库再加载 RDB 数据到内存中。面试官:主从库间的网络断了咋办?断开后要重新全量复制么?
在 Redis 2.8 之前,如果主从库在命令传播时出现了网络闪断,那么,从库就会和主库重新进行一次全量复制,开销非常大。
从 Redis 2.8 开始,网络断了之后,主从库会采用增量复制的方式继续同步。
增量复制:用于网络中断等情况后的复制,只将中断期间主节点执行的写命令发送给从节点,与全量复制相比更加高效。
断开重连增量复制的实现奥秘就是 repl_backlog_buffer
缓冲区,不管在什么时候 master 都会将写指令操作记录在 repl_backlog_buffer
中,因为内存有限, repl_backlog_buffer
是一个定长的环形数组,如果数组内容满了,就会从头开始覆盖前面的内容。
master 使用 master_repl_offset
记录自己写到的位置偏移量,slave 则使用 slave_repl_offset
记录已经读取到的偏移量。
当主从断开重连后,slave 会先发送 psync 命令给 master,同时将自己的 runID
,slave_repl_offset
发送给 master。
master 只需要把 master_repl_offset
与 slave_repl_offset
Redis 2.8부터 네트워크 연결이 끊어진 후에도 마스터-슬레이브 라이브러리는 증분 복제를 사용하여 계속 동기화됩니다.
repl_backlog_buffer
버퍼입니다. 메모리가 제한되어 있기 때문에 마스터는 언제라도 쓰기 명령 작업을 repl_backlog_buffer
에 기록합니다. repl_backlog_buffer
는 고정 길이 순환 배열입니다. 🎜배열 내용이 가득 차면 이전 내용을 처음부터 덮어씁니다🎜. 🎜🎜마스터는 master_repl_offset
를 사용하여 자신이 쓴 위치 오프셋을 기록하고, 슬레이브는 slave_repl_offset
을 사용하여 읽은 오프셋을 기록합니다. 🎜🎜🎜🎜Be 마스터 연결을 끊었다가 다시 연결한 후 슬레이브는 먼저 psync 명령을 마스터에 보내고 동시에 runID
및 slave_repl_offset
를 마스터에 보냅니다. 🎜🎜마스터는 master_repl_offset
과 slave_repl_offset
사이의 명령을 슬레이브 라이브러리에 동기화하기만 하면 됩니다. 🎜증분 복사 실행 과정은 다음과 같습니다.
인터뷰어: 전체 동기화를 완료한 후 정상 작동 중에 데이터를 동기화하는 방법은 무엇입니까?
마스터-슬레이브 라이브러리가 전체 복제를 완료하면 마스터 라이브러리는 이 연결을 사용하여 슬레이브 라이브러리에 연속적으로 수신된 후속 명령 작업을 동기화합니다. 이 프로세스는 긴 연결을 기반으로 호출되기도 합니다. . 명령 전파, 긴 연결을 사용하는 목적은 빈번한 연결 설정으로 인한 오버헤드를 방지하는 것입니다.
인터뷰어: 물론이죠. 너무 많이 알아요. Sentinel Cluster 원리를 아시나요?
Sentinel은 Redis 인스턴스(마스터 노드, 슬레이브 노드)의 실행 상태를 모니터링하는 데 중점을 두고 있으며, 마스터 노드 실패 시 일련의 메커니즘을 통해 마스터 선택 및 마스터-슬레이브 선택을 실현할 수 있습니다. 전체 Redis 시스템의 가용성을 보장하기 위해 장애 조치를 전환하고 구현합니다.
그의 아키텍처 다이어그램은 다음과 같습니다. Redis Sentinel에는 다음과 같은 기능이 있습니다.인터뷰어: 파수꾼들은 서로 어떻게 아는 사이인가요?센티널은 마스터와의 통신을 설정하고 마스터가 제공하는 게시/구독 메커니즘을 사용하여 키와 몸무게, 싱글, IP, 포트 등의 자체 정보를 게시합니다... 마스터에는 전용
__sentinel__:hello
채널은 센티널 간에 메시지를 게시하고 구독하는 데 사용됩니다. 이것은 __sentinel__:hello
WeChat 그룹과 같습니다. Sentinel은 마스터가 설립한 WeChat 그룹을 사용하여 자체 뉴스를 게시하는 동시에 다른 Sentinel이 게시한 뉴스에 주의를 기울입니다__sentinel__:hello
的专用通道,用于哨兵之间发布和订阅消息。这就好比是 __sentinel__:hello
微信群,哨兵利用 master 建立的微信群发布自己的消息,同时关注其他哨兵发布的消息。
面试官:哨兵之间虽然建立连接了,但是还需要和 slave 建立连接,不然没法监控他们呀,如何知道 slave 并监控他们的?
关键还是利用 master 来实现,哨兵向 master 发送 INFO
命令, master 掌门自然是知道自己门下所有的 salve 小弟的。所以 master 接收到命令后,便将 slave 列表告诉哨兵。
哨兵根据 master 响应的 slave 名单信息与每一个 salve 建立连接,并且根据这个连接持续监控哨兵。
面试官:除了哨兵以外,还有其他的高可用手段么?
有 Cluster 集群实现高可用,哨兵集群监控的 Redis 集群是主从架构,无法很想拓展。使用 Redis Cluster 集群,主要解决了大数据量存储导致的各种慢问题,同时也便于横向拓展。
在面向百万、千万级别的用户规模时,横向扩展的 Redis 切片集群会是一个非常好的选择。
面试官:什么是 Cluster 集群?
Redis 集群是一种分布式数据库方案,集群通过分片(sharding)来进行数据管理(「分治思想」的一种实践),并提供复制和故障转移功能。
将数据划分为 16384 的 slots,每个节点负责一部分槽位。槽位的信息存储于每个节点中。
它是去中心化的,如图所示,该集群有三个 Redis 节点组成,每个节点负责整个集群的一部分数据,每个节点负责的数据多少可能不一样。
三个节点相互连接组成一个对等的集群,它们之间通过 Gossip
.
인터뷰어: 센티넬은 서로 연결을 설정했지만 여전히 슬레이브와 연결을 설정해야 합니다. 그렇지 않으면 슬레이브를 어떻게 알고 모니터링할 수 있나요?
INFO
명령을 보냅니다. 마스터는 자연스럽게 자신의 밑에 있는 모든 살브 소년을 알고 있습니다. 따라서 마스터는 명령을 받은 후 센티널에게 슬레이브 목록을 알려줍니다. 인터뷰어: 센트리 외에 고가용성 방법이 있나요?
고가용성을 달성하기 위한 클러스터 클러스터가 있습니다. Sentinel 클러스터에서 모니터링하는 Redis 클러스터는 마스터-슬레이브 아키텍처로 쉽게 확장할 수 없습니다.
Redis Cluster 클러스터를 사용하면 대용량 데이터 저장으로 인한 다양한 속도 저하 문제를 주로 해결하고 수평 확장도 용이하게 합니다.
🎜수백만 또는 수천만 명의 사용자를 상대할 때 수평 확장이 가능한 Redis 슬라이싱 클러스터는 매우 좋은 선택이 될 것입니다. 🎜🎜🎜🎜인터뷰어: 클러스터란 무엇인가요? 🎜🎜🎜Redis 클러스터는 분산 데이터베이스 솔루션입니다. 클러스터는 샤딩("분할 정복" 방식)을 통해 데이터를 관리하고 복제 및 장애 조치 기능을 제공합니다. 🎜🎜데이터는 16384개의 슬롯으로 나누어져 있으며, 각 노드는 슬롯의 일부를 담당합니다. 슬롯 정보는 각 노드에 저장됩니다. 🎜🎜그림과 같이 클러스터는 3개의 Redis 노드로 구성되어 있으며 각 노드는 전체 클러스터의 데이터 중 일부를 담당합니다. 🎜🎜🎜🎜三노드들은 서로 연결되어 P2P 클러스터를 형성합니다. Gossip
프로토콜을 통해 서로 클러스터 정보를 교환합니다. 마지막으로 각 노드는 다른 노드의 슬롯 할당을 저장합니다. 🎜🎜🎜인터뷰어: 해시 슬롯은 Redis 인스턴스에 어떻게 매핑되나요? 🎜🎜🎜🎜키-값 쌍의 키에 따라 CRC16 알고리즘을 사용하여 16비트 값을 계산합니다. 🎜🎜16비트 값은 모듈로 16384이며 0에서 16383 사이의 숫자를 얻어서 키에 해당하는 해시 슬롯. 🎜🎜슬롯 정보를 바탕으로 해당 인스턴스를 찾습니다. 🎜🎜🎜키-값 쌍 데이터, 해시 슬롯 및 Redis 인스턴스 간의 매핑 관계는 다음과 같습니다. 🎜🎜🎜🎜🎜🎜인터뷰어: 클러스터는 장애 조치를 어떻게 구현합니까? 🎜
Redis 클러스터 노드는 Gossip
프로토콜을 사용하여 전체 클러스터에 대한 지식의 상태와 변경 사항을 브로드캐스트합니다. 예를 들어, 노드가 특정 노드의 손실(PFail)을 발견하면 이 정보를 전체 클러스터에 브로드캐스트하고 다른 노드도 이 연결 손실 정보를 수신할 수 있습니다.
특정 노드로부터의 연결 끊김 횟수(PFail Count)가 클러스터의 과반수에 도달했다는 것을 노드가 수신하면 해당 노드를 오프라인(Fail)으로 판단한 후 전체 클러스터에 브로드캐스팅할 수 있습니다. 다른 노드도 해당 노드가 오프라인 상태가 되었다는 사실을 수신하고 손실된 노드에서 즉시 마스터-슬레이브 전환을 수행하도록 강제합니다.
인터뷰어: 클라이언트는 액세스된 데이터가 배포되는 인스턴스를 어떻게 결정합니까?
Redis 인스턴스는 해시 슬롯 정보를 Gossip 프로토콜을 통해 클러스터의 다른 인스턴스로 전송하여 해시 슬롯 할당 정보의 확산을 실현합니다.
이런 방식으로 클러스터의 각 인스턴스는 모든 해시 슬롯과 인스턴스 간의 매핑 관계 정보를 갖게 됩니다.
클라이언트가 임의의 인스턴스에 연결되면 인스턴스는 해시 슬롯과 인스턴스 간의 매핑 관계로 클라이언트에 응답하고, 클라이언트는 해시 슬롯과 인스턴스 간의 매핑 정보를 로컬로 캐시합니다.
클라이언트가 요청하면 해당 키에 해당하는 해시 슬롯을 계산하고, 로컬에 캐시된 해시 슬롯 인스턴스 매핑 정보를 통해 데이터가 위치한 인스턴스를 찾아 해당 인스턴스로 요청을 보냅니다.
인터뷰어: Redis 리디렉션 메커니즘이 무엇인가요?
새 인스턴스 또는 로드 밸런싱 재배포로 인해 해시 슬롯과 인스턴스 간의 매핑 관계가 변경되었습니다. 클라이언트가 인스턴스에 요청을 보냅니다. 이 인스턴스에는 해당 데이터가 없습니다. 다른 인스턴스에.
Redis는 MOVED 오류 및 ASK 오류를 통해 클라이언트에 알립니다.
MOVED 오류(로드 밸런싱, 데이터가 다른 인스턴스로 마이그레이션됨): 클라이언트가 인스턴스에 키-값 쌍 작업 요청을 보냈고 키가 위치한 슬롯이 자체 책임이 아닌 경우 , 이 인스턴스는 MOVED 오류를 반환하여 노드가 슬롯을 담당하도록 지시합니다.
동시에 클라이언트는 로컬 캐시도 업데이트하여 슬롯과 Redis 인스턴스 간의 해당 관계를 올바르게 업데이트합니다.
특정 슬롯에 데이터가 많으면 일부는 새 인스턴스로 마이그레이션되고 일부는 마이그레이션되지 않습니다.
요청된 키가 현재 노드에서 발견되면 명령을 직접 실행하세요. 그렇지 않으면 ASK 오류 응답이 필요합니다.
슬롯 마이그레이션이 완료되지 않은 경우 키에 액세스해야 하는 슬롯이 인스턴스 1에서 인스턴스 2로 마이그레이션되는 경우(키가 더 이상 인스턴스 1에 없는 경우) 인스턴스 1은 ASK 오류 메시지를 반환합니다. 클라이언트: 클라이언트 요청 키가 있는 해시 슬롯이 인스턴스 2로 마이그레이션됩니다. 먼저 인스턴스 2에 ASKING 명령을 보낸 다음 작업 명령 을 보냅니다.
예를 들어 클라이언트가 인스턴스 172.17.18.1에서 키 = "공식 계정: 코드 바이트"를 사용하여 슬롯 16330을 찾으라고 요청하는 경우 노드 1은 찾을 수 있으면 명령을 직접 실행하고, 그렇지 않으면 ASK 오류로 응답합니다. 메시지를 보내고 클라이언트에게 리디렉션을 지시합니다. 마이그레이션되는 대상 노드는 172.17.18.2입니다.
참고: ASK 오류 명령은 클라이언트 캐시 해시 슬롯 할당 정보를 업데이트하지 않습니다.
이 글에서는 데이터 구조, 메모리 모델, IO 모델, 영구 RDB 및 AOF, 마스터-슬레이브 복제 원리, 센티넬 원리, 클러스터 원리 등 Redis의 핵심 내용을 주로 다룹니다.
원본 주소: https://juejin.cn/post/6976257378094481444
저자: Code Brother Byte
더 많은 프로그래밍 관련 지식을 보려면 프로그래밍 비디오를 방문하세요! !
위 내용은 자주 발생하는 Redis 인터뷰 질문을 공유하면 핵심 지식 포인트를 마스터하는 데 도움이 됩니다!의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!