분산 캐시--Redis

분산 캐시 – Redis

1. 단일 포인트 Redis의 문제

  • 데이터 유실 문제 – Redis는 인메모리 스토리지로 서비스 재시작 시 데이터 유실이 발생할 수 있음
  • 솔루션: Redis 데이터 지속성 실현
  • 동시성 문제 – 단일 노드 Redis의 동시성 기능은 좋지만 618과 같은 높은 동시성 시나리오를 충족할 수 없습니다.
  • 솔루션: 마스터-슬레이브 클러스터를 구축하여 읽기-쓰기 분리 달성
  • 저장 용량 문제 – Redis는 메모리를 기반으로 하며, 단일 노드에서 저장할 수 있는 데이터의 양은 대용량 데이터에 대한 요구를 충족시키기 어렵습니다.
  • 솔루션: 조각화된 클러스터를 구축하고 슬롯 메커니즘을 사용하여 동적 확장 달성
  • 장애 복구 문제 – Redis가 다운되면 서비스를 사용할 수 없으며 자동 장애 복구 수단이 필요합니다.
  • 솔루션: Redis Sentinel을 사용하여 상태 감지 및 자동 복구 구현

둘, Redis 지속성

2.1 RDB 지속성

RDB의 전체 이름은 Redis 데이터 스냅샷 이라고도 하는 Redis 데이터베이스 백업 파일(Redis 데이터 백업 파일 )입니다 . 간단히 말해, 메모리의 모든 데이터는 디스크에 기록 됩니다 . Redis 인스턴스가 실패하고 다시 시작되면 디스크에서 스냅샷 파일을 읽고 데이터를 복원합니다.

  • 스냅샷 파일은 RDB 파일이라고 하며 기본적으로 현재 실행 중인 디렉터리에 저장됩니다.
  • Redis가 다운되면 RDB가 한 번 실행됩니다. (디폴트는 서비스 정지 시 RDB를 실행하도록 되어 있습니다.)
# 进入redis命令行接口
redis-cli
# 由Redis主进程来执行RDB,会阻塞所有命令
save 
# 开启子进程执行RDB,避免主进程受到影响
bgsave

2.1.1 단일 머신에 Redis 설치

Redis는 기본적으로 RDB 지속성을 사용하므로 redis 서비스를 수동으로 종료한 후 스냅샷이 자동으로 생성되며, 시작 시 스냅샷 정보가 자동으로 복원되지만 다운 시 스냅샷이 생성되지 않습니다.

# 首先需要安装Redis所需要的依赖
yum install -y gcc tcl
# 将下载好的Redis安装包上传到虚拟机的任意目录,解压缩
tar -xvf redis-6.2.4.tar.gz
# 进入redis目录
cd redis-6.2.4
# 运行编译命令
make && make install
# 修改redis.conf文件中的一些配置
# 绑定地址,默认是127.0.0.1,会导致只能在本地访问。修改为0.0.0.0则可以在任意IP访问
bind 0.0.0.0
# 数据库数量,设置为1
databases 1

# 启动Redis
redis-server redis.conf
# 停止redis服务
redis-cli shutdown

# 进入redis命令行接口
redis-cli
# 检测是否成功
ping
# 添加信息
set num 123
# 查看信息
get num

2.1.2 RDB 내부 메커니즘

Redis에는 redis.conf 파일에서 찾을 수 있는 RDB를 트리거하는 메커니즘이 있으며 형식은 다음과 같습니다.

# 900秒内,如果至少有1个key被修改,则执行bgsave , 如果是save "" 则表示禁用RDB
save 900 1  
save 300 10  
# 代表60秒内至少执行10000次修改则触发RDB
save 60 10000 

RDB의 다른 구성도 redis.conf 파일에서 설정할 수 있습니다.

# 是否压缩 ,建议不开启,压缩也会消耗cpu,磁盘的话不值钱
rdbcompression yes

# RDB文件名称
dbfilename dump.rdb  

# 文件保存的路径目录
dir ./ 

2.1.3 RDB 비동기 지속성

  • bgsave 시작 시 메인 프로세스는 자식 프로세스를 얻기 위해 분기되며 자식 프로세스는 메인 프로세스의 메모리 데이터를 공유합니다. (자식 프로세스를 생성한다는 것은 페이지 테이블을 복사하는 것이다. 주 프로세스와 자식 프로세스 모두 가상 테이블의 페이지 테이블을 처리하고 매핑 관계를 통해 물리 메모리에 대한 읽기 및 쓰기 작업을 수행한다.)
  • 포크가 완료된 후 메모리 데이터를 읽고 RDB 파일에 씁니다. (이전 RDB 파일을
    대체하기 위해 새 RDB 파일 쓰기)
  • Fork는 copy-on-write 기술을 사용합니다.
  • 메인 프로세스가 읽기 작업을 수행할 때 공유 메모리에 액세스합니다.
  • 메인 프로세스가 쓰기 작업을 수행하면 데이터의 복사본이 복사되고 쓰기 작업이 수행됩니다.

2.1.14 RDB의 단점

  • RDB 실행 간격이 길고 두 RDB 쓰기 사이에 데이터 손실 위험이 있습니다.
  • 하위 프로세스를 분기하고 압축하고 RDB 파일을 작성하는 데 시간이 걸립니다.

2.2 AOF 지속성

AOF의 전체 이름은 Append Only File( 파일 추가 )입니다. Redis에서 처리하는 모든 쓰기 명령은 명령 로그 파일 로 간주할 수 있는 AOF 파일에 기록됩니다 .

2.2.1 AOF 내부 메커니즘

AOF는 기본적으로 비활성화되어 있습니다. AOF를 활성화하려면 redis.conf 구성 파일을 수정해야 합니다.

# 想要使用AOF,需要先禁用RDB
save ""
# 是否开启AOF功能,默认是no
appendonly yes
# AOF文件的名称
appendfilename "appendonly.aof"

AOF 명령 기록의 빈도는 redis.conf 파일을 통해 구성할 수도 있습니다.

# 表示每执行一次写命令,立即记录到AOF文件
appendfsync always 
# 写命令执行完先放入AOF缓冲区,然后表示每隔1秒将缓冲区数据写到AOF文件,是默认方案
appendfsync everysec 
# 写命令执行完先放入AOF缓冲区,由操作系统决定何时将缓冲区内容写回磁盘
appendfsync no
구성 항목 칫솔질의 타이밍 이점 결점
언제나 동기 브러시 디스크 높은 신뢰성, 거의 데이터 손실 없음 성능 영향
매초 초당 브러시 중간 성능 최대 1초의 데이터 손실
아니요 운영 체제 제어 최고의 성능 낮은 신뢰성, 많은 양의 데이터 손실 가능성

2.2.2 AOF 파일 최적화

레코드 명령이기 때문에 AOF 파일은 RDB 파일보다 훨씬 큽니다. 그리고 AOF는 동일한 키에 여러 쓰기 작업을 기록하지만 마지막 쓰기 작업만 의미가 있습니다. bgrewriteaof명령을 실행하면 AOF 파일을 다시 작성하여 가장 적은 명령으로 동일한 효과를 얻을 수 있습니다.

# 直接在redis-cli中执行bgrewriteaof命令执行重写功能
bgrewriteaof

set num 123
set name jack
set num 666
上面的式子第4行舍弃,将第5和第6行合并为下面的式子
mset name jack num 666

또한 Redis는 임계값이 트리거될 때 자동으로 AOF 파일을 다시 작성합니다 . 임계값은 redis.conf에서도 구성할 수 있습니다.

# AOF文件比上次文件 增长超过多少百分比则触发重写
auto-aof-rewrite-percentage 100
# AOF文件体积最小多大以上才触发重写 
auto-aof-rewrite-min-size 64mb 

2.3 RDB와 AOF의 비교

RDB와 AOF는 각각 장단점이 있으며, 데이터 보안 요구 사항이 높을 경우 실제 개발에서 조합하여 사용 하는 경우가 많습니다.

** ** RDB AOF
고집 정기적으로 전체 메모리의 스냅샷을 찍습니다. 실행된 모든 명령 기록
데이터 무결성 불완전, 백업 간 손실 칫솔질 전략에 따라 상대적으로 완벽함
파일 크기 압축이 있으며 파일 크기가 작습니다. 기록 명령, 파일 크기가 매우 큽니다.
다운타임 복구 속도 느린
데이터 복구 우선순위 데이터 무결성이 AOF만큼 좋지 않기 때문에 낮음 더 높은 데이터 무결성 때문에 높음
시스템 리소스 사용량 높고 무거운 CPU 및 메모리 소비 주로 디스크 IO 리소스가 낮지만 AOF는 재작성 시 많은 CPU 및 메모리 리소스를 차지합니다.
사용되는 장면 데이터 손실은 몇 분 동안 견딜 수 있으며 더 빠른 시작 속도 추구 더 높은 데이터 보안 요구 사항이 일반적입니다.

3. Redis 마스터-슬레이브

3.1 마스터-슬레이브 아키텍처

단일 노드 Redis의 동시성 기능에는 상한이 있으며 Redis의 동시성 기능을 더욱 향상시키기 위해서는 마스터-슬레이브 클러스터를 구축하여 읽기-쓰기 분리를 달성해야 합니다.

3.1.1 마스터-슬레이브 관계 구성

이제 세 개의 인스턴스는 서로 관련이 없으며 master-slave를 구성하려면 replicaof 또는 slaveof(5.0 이전) 명령을 사용할 수 있습니다.

임시 및 영구의 두 가지 모드가 있습니다.

  • 구성 파일 수정(영구적)

    • redis.conf에 구성 라인을 추가합니다.slaveof <masterip> <masterport>
  • redis-cli 클라이언트를 사용하여 redis 서비스에 연결하고 slaveof 명령을 실행합니다(다시 시작하면 실패함).

    slaveof <masterip> <masterport>
    

추신: 명령 replicaof는 5.0 이후에 추가되었으며 salveof와 동일한 효과가 있습니다.

# 列举方式二
# 通过redis-cli命令连接
redis-cli -p 需要设置为slavel的Redis
# 执行slaveof
slaveof 主的ip 主的Redis

# 配置完从Redis,连接主Redis的redis-cli命令连接
redis-cli -p 主的Redis
# 查看状态
info replication

3.1.2 마스터-슬레이브 관계 테스트

  • 테스트 결과 쓰기 작업은 기본 Redis의 마스터 노드에서만 수행할 수 있는 것으로 나타났습니다.
  • Redis 슬레이브 노드에서는 읽기 작업만 수행할 수 있습니다.

3.2 데이터 동기화 원리

3.2.1 전체 동기화

실행조건 : 슬레이브노드가 마스터노드에 처음 접속하는 경우;

슬레이브 노드가 너무 오랫동안 연결 해제되어 repl_baklog의 오프셋을 덮어썼습니다.

  • Replication Id : Replid는 줄여서 데이터 셋의 표시이며, 같은 id는 같은 데이터 셋임을 의미합니다. 각 마스터에는 고유한 회신이 있으며 슬레이브는 마스터 노드의 회신을 상속합니다.
  • offset : repl_baklog에 기록된 데이터가 증가함에 따라 점차적으로 증가하는 오프셋. 슬레이브가 동기화를 완료하면 현재 동기화 오프셋도 기록합니다. 슬레이브의 오프셋이 마스터의 오프셋보다 작으면 슬레이브 데이터가 마스터보다 뒤쳐져 업데이트가 필요함을 의미합니다.

슬레이브가 데이터 동기화를 수행할 때 자신의 복제 ID와 오프셋을 마스터에 선언해야 마스터가 동기화해야 하는 데이터를 결정할 수 있습니다.

전체 동기화 프로세스 :

  • 슬레이브 노드가 증분 동기화를 요청합니다.
  • 마스터 노드는 replid를 판단하고 불일치를 발견하고 증분 동기화를 거부합니다.
  • 마스터는 완전한 메모리 데이터로 RDB를 생성하고 RDB를 슬레이브로 보냅니다.
  • 슬레이브는 로컬 데이터를 지우고 마스터의 RDB를 로드합니다.
  • 마스터는 RDB 기간 동안의 명령을 repl_baklog에 기록하고 로그에 있는 명령을 지속적으로 슬레이브로 보냅니다(후속 명령은 repl_baklog에 기록되어 슬레이브로 하나씩 전송됩니다)
  • 슬레이브는 수신된 명령을 실행하고 마스터와 동기화를 유지합니다.

마스터는 슬레이브 노드가 처음으로 데이터 동기화를 수행하는지 여부를 어떻게 판단합니까?

답변: 마스터 노드는 복제 ID가 일치하는지 여부를 판단하여 최초 여부를 판단합니다.

3.2.2 증분 동기화

첫 번째 마스터-슬레이브 동기화는 전체 동기화 이지만 슬레이브가 다시 시작되어 동기화되면 증분 동기화를 수행합니다.

실행 조건 : 슬레이브 노드가 연결 해제되어 복원되었을 때, 오프셋은 repl_baklog에서 찾을 수 있습니다.

  • 슬레이브는 자신의 오프셋을 마스터에 제출합니다.
  • 마스터의 repl_baklog에서 오프셋 후 데이터 가져오기
  • 오프셋 후 슬레이브에 명령 보내기

pl_baklog의 크기에는 상한이 있으며 가득 차면 가장 빠른 데이터를 덮어씁니다. 슬레이브가 너무 오랫동안 연결 해제되어 백업되지 않은 데이터를 덮어쓰게 되면 로그를 기반으로 증분 동기화를 수행할 수 없으며 다시 전체 동기화만 수행할 수 있습니다.

3.2.3 Redis 마스터-슬레이브 클러스터 최적화

  • 전체 동기화 중에 디스크 IO를 방지하기 위해 디스크 없는 복제를 활성화하려면 마스터에서 repl-diskless-sync yes를 구성합니다.
  • Redis 단일 노드의 메모리 사용량은 RDB로 인한 과도한 디스크 IO를 줄이기 위해 너무 크지 않아야 합니다.
  • repl_baklog의 크기를 적절히 늘리고 슬레이브가 다운된 것으로 확인되면 가능한 한 빨리 오류 복구를 실현하고 가능한 한 전체 동기화를 피하십시오.
  • 마스터의 슬레이브 노드 수를 제한합니다.슬레이브가 너무 많으면 마스터-슬레이브-슬레이브 체인 구조를 사용하여 마스터에 대한 압력을 줄일 수 있습니다.

4. 레디스 보초

4.1 센티넬의 역할

Redis는 마스터-슬레이브 클러스터의 자동 장애 복구를 달성하기 위한 Sentinel 메커니즘을 제공합니다.

Sentinel의 구조와 기능은 다음과 같습니다.

  • 모니터링 : Sentinel은 마스터와 슬레이브가 예상대로 작동하는지 지속적으로 확인합니다.
  • 자동 장애 복구 : 마스터에 장애가 발생하면 Sentinel이 슬레이브를 마스터로 승격합니다. 결함이 있는 인스턴스가 복구되면 새 마스터도 마스터가 됩니다.
  • 알림 : Sentinel은 Redis 클라이언트의 서비스 검색 소스 역할을 하며 클러스터가 장애 조치될 때 Redis 클라이언트에 최신 정보를 푸시합니다.

4.2 서비스 상태 모니터링

Sentinel은 하트비트 메커니즘을 기반으로 서비스 상태를 모니터링 하고 1초마다 클러스터의 각 인스턴스에 ping 명령을 보냅니다.

  • 주관적 오프라인 : 센티넬 노드는 인스턴스가 지정된 시간 내에 응답하지 않는 것을 발견하면 해당 인스턴스를 주관적으로 오프라인으로 간주합니다.
  • Objective offline : 지정된 수(정족수) 이상의 Sentinel이 인스턴스가 주관적으로 오프라인이라고 생각하는 경우 해당 인스턴스는 객관적으로 오프라인이 됩니다. 쿼럼 값은 Sentinel 인스턴스 수의 절반 이상이 바람직합니다.

4.3 새로운 마스터 선출

마스터 실패가 발견되면 Sentinel은 슬레이브 중 하나를 새 마스터로 선택해야 합니다. 선택 기준은 다음과 같습니다.

  • 먼저 슬레이브 노드와 마스터 노드의 연결이 끊어진 시간을 판단하여 지정된 값(down-after-milliseconds * 10)을 초과하면 슬레이브 노드는 제외됩니다.
  • 그런 다음 슬레이브 노드의 슬레이브 우선 순위 값을 판단하고 우선 순위가 낮을수록 우선 순위가 높으며 0이면 선거에 참여하지 않습니다.
  • 슬레이브 우선 순위가 같으면 슬레이브 노드의 오프셋 값을 판단하고 값이 클수록 최신 데이터이고 우선 순위가 높습니다.
  • 마지막은 슬레이브 노드의 실행 ID 크기를 판단하는 것입니다 . 우선 순위가 작을수록 우선 순위가 높습니다.

4.4 장애 복구를 달성하는 방법

슬레이브 중 하나가 새 마스터(예: slave1)로 선택되면 장애 조치 단계는 다음과 같습니다.

  • Sentinel은 후보 slave1 노드에 slaveof no one 명령을 보내 노드를 마스터로 만듭니다.
  • Sentinel은 다른 모든 슬레이브에게 slaveof 192.168.150.101 7002 명령을 전송하여 이 슬레이브를 새 마스터의 슬레이브 노드로 만들고 새 마스터에서 데이터 동기화를 시작합니다.
  • 마지막으로 Sentinel은 결함이 있는 노드를 슬레이브로 표시하고 결함이 있는 노드가 복구되면 자동으로 새 마스터의 슬레이브 노드가 됩니다.

4.5 RedisTemplate의 Sentinel 모드

Sentinel 클러스터의 감독하에 있는 Redis 마스터-슬레이브 클러스터에서 자동 장애 조치로 인해 해당 노드가 변경되며 Redis 클라이언트는 이 변경 사항을 인식하고 적시에 연결 정보를 업데이트해야 합니다. Spring의 RedisTemplate底层사용은 노드의 인식 및 자동 전환을lettuce 실현합니다 .

단계:

  • pom 파일에 redis의 스타터 종속성을 도입합니다.
  • 그런 다음 구성 파일 application.yml에서 센티널 관련 정보를 지정합니다.
  • 마스터-슬레이브 읽기-쓰기 분리를 구성합니다.

ReadFrom은 다음 옵션을 포함하는 열거형인 Redis 구성을 위한 읽기 전략 입니다.

  • MASTER : 마스터 노드에서 읽습니다.
  • MASTER_PREFERRED : 마스터 노드에서 먼저 읽고, 마스터를 사용할 수 없을 때 복제본을 읽습니다.
  • REPLICA : 슬레이브(레플리카) 노드에서 읽습니다.
  • REPLICA _PREFERRED : 슬레이브(레플리카) 노드부터 먼저 읽고, 모든 슬레이브를 사용할 수 없을 때만 마스터를 읽는다.

5. Redis 조각화 클러스터

5.1 샤드 클러스터 구조

마스터-슬레이브 및 센트리는 고가용성 및 높은 동시 읽기 문제를 해결할 수 있습니다. 그러나 아직 해결되지 않은 두 가지 문제가 있습니다.

  • 대량 데이터 저장 문제.
  • 높은 동시 쓰기 문제.

위의 문제는 샤드 클러스터를 사용하여 해결할 수 있습니다.샤드 클러스터의 특징:

  • 클러스터에는 여러 마스터가 있으며 각 마스터는 서로 다른 데이터를 저장합니다.
  • 각 마스터는 여러 슬레이브 노드를 가질 수 있습니다.
  • 마스터는 ping을 통해 서로의 건강 상태를 모니터링합니다.
  • 클라이언트 요청은 클러스터의 모든 노드에 액세스할 수 있으며 결국 올바른 노드로 전달됩니다.

5.2 해시 슬롯

Redis는 각 마스터 노드를 0에서 16383까지 총 16384개의 슬롯(해시 슬롯)에 매핑합니다.

데이터 키는 노드에 바인딩되지 않고 슬롯에 바인딩됩니다. Redis는 다음 두 가지 경우에 키의 유효 부분을 기반으로 슬롯 값을 계산합니다.

  • 키는 "{}"를 포함하고 "{}"는 최소 1개의 문자를 포함하며 "{}"의 부분은 유효한 부분입니다.
  • 키에 "{}"가 포함되어 있지 않으며 전체 키가 유효한 부분입니다.
  • 예를 들어 키가 num이면 num에 따라 계산되고 {itcast}num이면 itcast에 따라 계산됩니다. 계산 방법은 CRC16 알고리즘을 사용하여 해시 값을 얻은 다음 나머지 16384를 취하여 얻은 결과가 슬롯 값입니다.

Redis는 키가 있어야 하는 인스턴스를 어떻게 결정합니까?
답변: 1. 다른 인스턴스에 16384개의 슬롯을 할당합니다.
2. 키의 유효 부분에 따라 해시 값을 계산하고 나머지 16384를 취합니다.
3. 나머지를 슬롯으로 사용하고 슬롯이 있는 인스턴스를 찾습니다. 위치. .

동일한 Redis 인스턴스에 동일한 유형의 데이터를 저장하는 방법은 무엇입니까?
대답: 이 유형의 데이터는 동일한 유효 부분을 사용합니다. 예를 들어 모든 키에는 {typeId} 접두사가 붙습니다.

5.3 클러스터 확장

  • redis-cli --cluster는 클러스터를 작동하기 위한 많은 명령을 제공합니다.
  • redis-cli --cluster help도움말 문서를 확인하십시오.
  • 예를 들어, 노드를 추가하는 명령: add-node.

5.4 장애 조치

클러스터의 마스터가 다운되면 어떻게 됩니까?

  • 첫 번째는 인스턴스가 다른 인스턴스와의 연결이 끊어지는 것입니다.
  • 그런 다음 의심되는 가동 중지 시간이 있습니다.
  • 마지막으로 오프라인으로 전환하고 자동으로 슬레이브를 새 마스터로 승격하기로 결정합니다.

5.5 데이터 마이그레이션

이 명령을 사용하여 cluster failover클러스터의 마스터를 수동으로 종료하고 클러스터 장애 조치 명령을 실행하는 슬레이브 노드로 전환하여 비인식 데이터 마이그레이션을 실현할 수 있습니다. 프로세스는 다음과 같습니다.

수동 장애 조치는 세 가지 모드를 지원합니다.

  • 기본값: 그림 1~6 단계와 같이 기본 프로세스입니다.
  • force: 오프셋에 대한 일관성 검사를 생략합니다.
  • 인계: 데이터 일관성, 마스터 상태 및 기타 마스터 의견을 무시하고 5단계를 직접 실행합니다.

5.6 RedisTemplate 액세스 단편화 클러스터

RedisTemplate의 최하위 계층도 상추 기반의 조각난 클러스터 지원을 구현하며 사용되는 단계는 기본적으로 센티넬 모드와 동일합니다.

  • redis의 스타터 종속성을 소개합니다.
  • 샤드 클러스터 주소를 구성합니다.
  • 읽기-쓰기 분리를 구성합니다.

->微服务技术栈高级篇--分布式缓存--Redis课程视频

고급 Day3-01-Redis Persistence_哔哩哔哩_bilibili

<-

记录每一个学习瞬间

추천

출처blog.csdn.net/qq_51601665/article/details/130174598