>  기사  >  데이터 베이스  >  Redis에서 꼭 마스터해야 할 20가지 질문, 와서 모아보세요! !

Redis에서 꼭 마스터해야 할 20가지 질문, 와서 모아보세요! !

青灯夜游
青灯夜游앞으로
2021-10-19 10:31:241598검색

이 기사에서는 여러분이 꼭 알고 숙지해야 할 20가지 Redis 문제를 공유하겠습니다. 와서 수집해 보세요.

Redis에서 꼭 마스터해야 할 20가지 질문, 와서 모아보세요! !

Redis란 무엇인가요?

Redis(Remote Dictionary Server)는 C 언어로 작성된 고성능 비관계형 키-값 데이터베이스입니다. Redis의 데이터는 기존의 데이터베이스와 달리 메모리에 저장되기 때문에 읽기, 쓰기 속도가 매우 빠르고 캐싱에 널리 사용됩니다. Redis는 디스크에 데이터를 쓸 수 있어 데이터 보안이 보장되고 손실되지 않으며 Redis 작업은 원자성입니다. [관련 추천 : Redis 영상 튜토리얼]

Redis의 장점은 무엇인가요?

  • 메모리 연산에 따라 메모리 읽기 및 쓰기 속도가 빠릅니다.

  • Redis는 단일 스레드로 스레드 전환 오버헤드와 다중 스레드 경쟁 문제를 방지합니다. 단일 스레드는 네트워크 요청이 하나의 스레드에 의해 처리됨을 의미합니다. 즉, 하나의 스레드가 모든 네트워크 요청을 처리합니다. 예를 들어, 데이터 지속성 프로세스는 다른 스레드를 시작합니다.

  • 문자열, 해시, 목록, Set, ZSet 등을 포함한 다양한 데이터 유형을 지원합니다.

  • 끈기를 지원하세요. Redis는 RDB와 AOF라는 두 가지 지속성 메커니즘을 지원합니다. 지속성 기능은 데이터 손실 문제를 효과적으로 방지할 수 있습니다.

  • 지원 업무. Redis의 모든 작업은 원자적이며 Redis는 여러 작업을 병합한 후 원자 실행도 지원합니다.

  • 마스터-슬레이브 복제를 지원합니다. 마스터 노드는 데이터를 슬레이브 노드에 자동으로 동기화하여 읽기 및 쓰기 분리를 허용합니다.

Redis가 왜 이렇게 빠른가요?

  • 메모리 기반: Redis는 메모리 저장소를 사용하며 디스크 IO 오버헤드가 없습니다. 데이터가 메모리에 저장되며 읽기 및 쓰기 속도가 빠릅니다.
  • 단일 스레드 구현(Redis 6.0 이전): Redis는 단일 스레드를 사용하여 요청을 처리하므로 스레드 전환 오버헤드를 방지하고 여러 스레드 간의 리소스 경합을 잠급니다.
  • IO 다중화 모델: Redis는 IO 다중화 기술을 사용합니다. Redis는 단일 스레드를 사용하여 설명자를 폴링하고 네트워크 I/O에 너무 많은 시간을 낭비하지 않고 데이터베이스 작업을 이벤트로 변환합니다.
  • 효율적인 데이터 구조: Redis는 더 빠른 속도를 추구하기 위해 각 데이터 유형의 하위 계층을 최적화했습니다.

Redis가 단일 스레드를 선택하는 이유는 무엇입니까?

  • 과도한 컨텍스트 전환 오버헤드를 피하세요. 프로그램은 항상 프로세스의 단일 스레드에서 실행되며 다중 스레드 전환 시나리오는 없습니다.
  • 동기화 메커니즘의 오버헤드 방지: Redis가 멀티 스레드 모델을 선택하고 데이터 동기화 문제를 고려해야 하는 경우 일부 동기화 메커니즘이 필연적으로 도입되어 데이터 운영 과정에서 더 많은 오버헤드가 발생하고 데이터 사용량이 증가합니다. 프로그램 복잡성도 저하됩니다.
  • 간단한 구현 및 손쉬운 유지 관리: Redis가 멀티스레딩 모드를 사용하는 경우 모든 기본 데이터 구조의 설계는 스레드 안전 문제를 고려해야 하며 Redis 구현은 더욱 복잡해집니다.

Redis의 적용 시나리오는 무엇입니까?

  • 핫스팟 데이터를 캐시하여 데이터베이스에 대한 부담을 덜어줍니다.

  • Redis의 원자 자동 증가 연산을 사용하면 사용자 좋아요 수, 사용자 방문 횟수 계산 등 counter 기능을 구현할 수 있습니다.

  • 간단한 메시지 대기열 Redis 고유의 게시/구독 모드 또는 목록을 사용하여 간단한 메시지 대기열을 구현하고 비동기 작업을 구현할 수 있습니다.

  • 속도 제한기는 사용자가 특정 인터페이스에 액세스하는 빈도를 제한하는 데 사용할 수 있습니다. 예를 들어 플래시 세일 시나리오는 사용자가 빠른 클릭으로 인한 불필요한 압력을 방지하는 데 사용됩니다.

  • 친구 관계, 교차, 결합, 차이 등과 같은 일부 수집 명령을 사용하여 공통 친구 및 공통 취미와 같은 기능을 구현합니다.

Memcached와 Redis의 차이점은 무엇인가요?

  • Redis는 단일 코어만 사용하는 반면 Memcached는 다중 코어를 사용할 수 있습니다.

  • MemCached는 단일 데이터 구조를 가지며 데이터를 캐시하는 데만 사용되는 반면, Redis는 여러 데이터 유형을 지원합니다.

  • MemCached는 데이터 지속성을 지원하지 않으며 다시 시작하면 데이터가 사라집니다. Redis는 데이터 지속성을 지원합니다.

  • Redis는 고가용성 서비스를 제공할 수 있는 마스터-슬레이브 동기화 메커니즘과 클러스터 배포 기능을 제공합니다. Memcached는 기본 클러스터 모드를 제공하지 않으며 클러스터의 샤드에 데이터를 쓰려면 클라이언트에 의존해야 합니다.

  • Redis는 Memcached보다 훨씬 빠릅니다.

  • Redis는 단일 스레드 다중 채널 IO 재사용 모델을 사용하고 Memcached는 다중 스레드 비차단 IO 모델을 사용합니다.

Redis의 데이터 유형은 무엇인가요?

기본 데이터 유형:

1, String: 가장 일반적으로 사용되는 데이터 유형 문자열 유형 값은 문자열, 숫자 또는 바이너리일 수 있지만 최대값은 512MB를 초과할 수 없습니다.

2, Hash: 해시는 키-값 쌍의 모음입니다.

3. Set: 순서가 없고 중복이 제거된 세트입니다. Set은 교차, 결합 등의 방법을 제공하며 이는 특히 상호 친구 및 공동 관심과 같은 기능을 구현하는 데 편리합니다.

4, List: 순서가 지정되고 반복 가능한 컬렉션인 맨 아래 레이어는 이중 연결 목록을 사용하여 구현됩니다.

5, SortedSet(ZSet): 주문된 세트. score 매개변수는 구현을 위해 내부적으로 유지됩니다. 순위 및 가중치가 적용된 메시지 대기열과 같은 시나리오에 적합합니다. score的参数来实现。适用于排行榜和带权重的消息队列等场景。

特殊的数据类型

1、Bitmap:位图,可以认为是一个以位为单位数组,数组中的每个单元只能存0或者1,数组的下标在 Bitmap 中叫做偏移量。Bitmap的长度与集合中元素个数无关,而是与基数的上限有关。

2、Hyperloglog。HyperLogLog 是用来做基数统计的算法,其优点是,在输入元素的数量或者体积非常非常大时,计算基数所需的空间总是固定的、并且是很小的。典型的使用场景是统计独立访客。

3、Geospatial :主要用于存储地理位置信息,并对存储的信息进行操作,适用场景如定位、附近的人等。

Redis事务

事务的原理是将一个事务范围内的若干命令发送给 Redis,然后再让 Redis 依次执行这些命令。

事务的生命周期:

  • 使用MULTI开启一个事务;

  • 在开启事务的时候,每次操作的命令将会被插入到一个队列中,同时这个命令并不会被真正执行;

  • EXEC命令进行提交事务。

Redis에서 꼭 마스터해야 할 20가지 질문, 와서 모아보세요! !

一个事务范围内某个命令出错不会影响其他命令的执行,不保证原子性:

first:0>MULTI
"OK"
first:0>set a 1
"QUEUED"
first:0>set b 2 3 4
"QUEUED"
first:0>set c 6
"QUEUED"
first:0>EXEC
1) "OK"
2) "OK"
3) "OK"
4) "ERR syntax error"
5) "OK"
6) "OK"
7) "OK"

WATCH命令

WATCH命令可以监控一个或多个键,一旦其中有一个键被修改,之后的事务就不会执行(类似于乐观锁)。执行EXEC命令之后,就会自动取消监控。

first:0>watch name
"OK"
first:0>set name 1
"OK"
first:0>MULTI
"OK"
first:0>set name 2
"QUEUED"
first:0>set gender 1
"QUEUED"
first:0>EXEC
(nil)
first:0>get gender
(nil)

比如上面的代码中:

  1. watch name开启了对name这个key的监控
  2. 修改name的值
  3. 开启事务a
  4. 在事务a中设置了namegender的值
  5. 使用EXEC命令进提交事务
  6. 使用命令get gender发现不存在,即事务a没有执行

使用UNWATCH可以取消WATCH命令对key的监控,所有监控锁将会被取消。

持久化机制

持久化就是把内存的数据写到磁盘中,防止服务宕机导致内存数据丢失。

Redis支持两种方式的持久化,一种是RDB的方式,一种是AOF的方式。前者会根据指定的规则定时将内存中的数据存储在硬盘上,而后者在每次执行完命令后将命令记录下来。一般将两者结合使用。

RDB方式

RDB是 Redis 默认的持久化方案。RDB持久化时会将内存中的数据写入到磁盘中,在指定目录下生成一个dump.rdb文件。Redis 重启会加载dump.rdb文件恢复数据。

bgsave是主流的触发 RDB 持久化的方式,执行过程如下:

Redis에서 꼭 마스터해야 할 20가지 질문, 와서 모아보세요! !

  • 执行BGSAVE命令
  • Redis 父进程判断当前是否存在正在执行的子进程,如果存在,BGSAVE命令直接返回。
  • 父进程执行fork操作创建子进程,fork操作过程中父进程会阻塞。
  • 父进程fork특수 데이터 유형:
  • 1,
  • Bitmap: 비트 배열로 간주할 수 있는 비트맵. 배열의 각 단위는 0 또는 1만 저장할 수 있습니다. 배열의 첨자는 비트맵에 있습니다. 오프셋이라고 합니다. Bitmap의 길이는 컬렉션의 요소 수와 관련이 없지만 카디널리티의 상한과 관련이 있습니다.
  • 2,
Hyperloglog

. HyperLogLog는 카디널리티 통계에 사용되는 알고리즘으로, 입력 요소의 개수나 양이 매우 클 경우 카디널리티를 계산하는 데 필요한 공간이 항상 고정되어 매우 작다는 장점이 있습니다. 일반적인 사용 시나리오는 고유 방문자를 계산하는 것입니다.

3,

Geospatial🎜: 주로 지리적 위치 정보를 저장하고 위치 확인, 주변 사람 등과 같은 적용 가능한 시나리오에 사용됩니다. 🎜

Redis 트랜잭션🎜🎜트랜잭션의 원칙은 트랜잭션 범위 내의 여러 명령을 Redis로 보낸 다음 Redis가 이러한 명령을 순서대로 실행하도록 하는 것입니다. 🎜🎜거래 수명 주기: 🎜
    🎜🎜거래를 열려면 MULTI를 사용하세요. 🎜🎜🎜🎜거래를 열 때마다 작업 명령은 대기열에 삽입되며 이 명령은 실제로 실행되지 않습니다. 🎜🎜🎜🎜EXEC 명령은 트랜잭션을 커밋합니다. Redis에서 꼭 마스터해야 할 20가지 질문, 와서 모아보세요! !🎜🎜트랜잭션 범위 내 명령의 오류는 다른 명령의 실행에 영향을 주지 않으며 원자성이 보장되지 않습니다: 🎜
    appendfsync always //每次写入aof文件都会执行同步,最安全最慢,不建议配置
    appendfsync everysec  //既保证性能也保证安全,建议配置
    appendfsync no //由操作系统决定何时进行同步操作
    🎜🎜WATCH 명령🎜🎜🎜WATCH 명령은 하나 이상의 키를 모니터링할 수 있습니다. 키 중 하나가 수정되면 후속 트랜잭션은 실행되지 않습니다(낙관적 잠금과 유사). <code>EXEC 명령 실행 후 모니터링은 자동으로 취소됩니다. 🎜
    //启动Redis实例作为主数据库
    redis-server  
    //启动另一个实例作为从数据库
    redis-server --port 6380 --slaveof  127.0.0.1 6379   
    slaveof 127.0.0.1 6379
    //停止接收其他数据库的同步并转化为主数据库
    SLAVEOF NO ONE
    🎜예를 들어 위 코드에서 🎜
      🎜watch namename의 모니터링을 이 key로 설정합니다. 🎜🎜수정 이름 값🎜🎜거래 a 열기🎜🎜이름성별 값은 거래 a에 설정됩니다🎜🎜EXEC트랜잭션 제출 명령🎜🎜성별 가져오기 명령을 사용하여 해당 트랜잭션이 존재하지 않는지, 즉 트랜잭션 a가 실행되지 않았는지 확인하세요🎜
    🎜사용 >UNWATCHWATCH를 취소합니다. code> 명령은 <code>key를 모니터링하고 모든 모니터링 잠금이 취소됩니다. 🎜

    지속성 메커니즘🎜🎜지속성은 서비스 다운타임으로 인한 메모리 데이터 손실을 방지하기 위해 🎜메모리 데이터를 디스크에 기록🎜하는 것입니다. 🎜🎜Redis는 두 가지 지속성 방법을 지원합니다. 하나는 RDB 방법이고 다른 하나는 AOF 방법입니다. 🎜전자는 지정된 규칙에 따라 하드 디스크의 메모리에 정기적으로 데이터를 저장하는 반면🎜, 🎜후자는 각 명령이 실행된 후 명령을 기록합니다🎜. 일반적으로 두 가지를 조합하여 사용됩니다. 🎜

    RDB 방법

    🎜RDB는 Redis의 기본 지속성 솔루션입니다. RDB가 지속되면 메모리의 데이터가 디스크에 기록되고 지정된 디렉터리에 dump.rdb 파일이 생성됩니다. Redis를 다시 시작하면 dump.rdb 파일이 로드되어 데이터가 복원됩니다. 🎜🎜bgsave는 RDB 지속성을 실행하는 주요 방법입니다. 실행 프로세스는 다음과 같습니다. 🎜🎜Redis에서 꼭 마스터해야 할 20가지 질문, 와서 모아보세요! !🎜
      🎜BGSAVE 명령을 실행하세요🎜🎜Redis 상위 프로세스는 현재 하위 프로세스 🎜를 실행하면 BGSAVE 명령이 직접 반환됩니다. 🎜🎜상위 프로세스는 포크 작업을 수행하여🎜하위 프로세스를 생성합니다🎜. 상위 프로세스는 포크 작업 중에 차단됩니다. 🎜🎜상위 프로세스 fork가 완료된 후 🎜상위 프로세스는 계속해서 클라이언트의 요청을 수신하고 처리하며🎜, 🎜하위 프로세스는 메모리의 데이터를 클라이언트의 임시 파일에 쓰기 시작합니다. hard disk🎜; 🎜🎜자식 프로세스 시 모든 데이터가 기록된 후 이전 RDB 파일이 이 임시 파일로 대체됩니다. 🎜🎜🎜Redis가 시작되면 RDB 스냅샷 파일을 읽고 하드 디스크의 데이터를 메모리로 로드합니다. RDB 지속성을 통해 Redis가 비정상적으로 종료되면 마지막 지속성 이후 변경된 데이터가 손실됩니다. 🎜🎜RDB 지속성을 트리거하는 방법:🎜
    1. 手动触发:用户执行SAVEBGSAVE命令。SAVE命令执行快照的过程会阻塞所有客户端的请求,应避免在生产环境使用此命令。BGSAVE命令可以在后台异步进行快照操作,快照的同时服务器还可以继续响应客户端的请求,因此需要手动执行快照时推荐使用BGSAVE命令。

    2. 被动触发

      • 根据配置规则进行自动快照,如SAVE 100 10,100秒内至少有10个键被修改则进行快照。
      • 如果从节点执行全量复制操作,主节点会自动执行BGSAVE生成 RDB 文件并发送给从节点。
      • 默认情况下执行shutdown命令时,如果没有开启 AOF 持久化功能则自动执行·BGSAVE·。

优点

  • Redis 加载 RDB 恢复数据远远快于 AOF 的方式

  • 使用单独子进程来进行持久化,主进程不会进行任何 IO 操作,保证了 Redis 的高性能

缺点

  • RDB方式数据无法做到实时持久化。因为BGSAVE每次运行都要执行fork操作创建子进程,属于重量级操作,频繁执行成本比较高。

  • RDB 文件使用特定二进制格式保存,Redis 版本升级过程中有多个格式的 RDB 版本,存在老版本 Redis 无法兼容新版 RDB 格式的问题

AOF方式

AOF(append only file)持久化:以独立日志的方式记录每次写命令,Redis重启时会重新执行AOF文件中的命令达到恢复数据的目的。AOF的主要作用是解决了数据持久化的实时性,AOF 是Redis持久化的主流方式。

默认情况下Redis没有开启AOF方式的持久化,可以通过appendonly参数启用:appendonly yes。开启AOF方式持久化后每执行一条写命令,Redis就会将该命令写进aof_buf缓冲区,AOF缓冲区根据对应的策略向硬盘做同步操作。

默认情况下系统每30秒会执行一次同步操作。为了防止缓冲区数据丢失,可以在Redis写入AOF文件后主动要求系统将缓冲区数据同步到硬盘上。可以通过appendfsync参数设置同步的时机。

appendfsync always //每次写入aof文件都会执行同步,最安全最慢,不建议配置
appendfsync everysec  //既保证性能也保证安全,建议配置
appendfsync no //由操作系统决定何时进行同步操作

接下来看一下 AOF 持久化执行流程:

Redis에서 꼭 마스터해야 할 20가지 질문, 와서 모아보세요! !

  • 所有的写入命令会追加到 AOP 缓冲区中。

  • AOF 缓冲区根据对应的策略向硬盘同步。

  • 随着 AOF 文件越来越大,需要定期对 AOF 文件进行重写,达到压缩文件体积的目的。AOF文件重写是把Redis进程内的数据转化为写命令同步到新AOF文件的过程。

  • 当 Redis 服务器重启时,可以加载 AOF 文件进行数据恢复。

优点

  • AOF可以更好的保护数据不丢失,可以配置 AOF 每秒执行一次fsync操作,如果Redis进程挂掉,最多丢失1秒的数据。

  • AOF以append-only的模式写入,所以没有磁盘寻址的开销,写入性能非常高。

缺点

  • 对于同一份文件AOF文件比RDB数据快照要大。

  • 数据恢复比较慢。

主从复制

Redis的复制功能是支持多个数据库之间的数据同步。主数据库可以进行读写操作,当主数据库的数据发生变化时会自动将数据同步到从数据库。从数据库一般是只读的,它会接收主数据库同步过来的数据。一个主数据库可以有多个从数据库,而一个从数据库只能有一个主数据库。

//启动Redis实例作为主数据库
redis-server  
//启动另一个实例作为从数据库
redis-server --port 6380 --slaveof  127.0.0.1 6379   
slaveof 127.0.0.1 6379
//停止接收其他数据库的同步并转化为主数据库
SLAVEOF NO ONE

主从复制的原理?

  • 当启动一个从节点时,它会发送一个 PSYNC 命令给主节点;

  • 如果是从节点初次连接到主节点,那么会触发一次全量复制。此时主节点会启动一个后台线程,开始生成一份 RDB 快照文件;

  • 同时还会将从客户端 client 新收到的所有写命令缓存在内存中。RDB 文件生成完毕后, 主节点会将RDB文件发送给从节点,从节点会先将RDB文件写入本地磁盘,然后再从本地磁盘加载到内存中

  • 그러면 마스터 노드는 메모리에 캐시된 쓰기 명령을 슬레이브 노드로 보내고 슬레이브 노드는 데이터를 동기화합니다.

  • 슬레이브 노드와 마스터 노드 사이에 네트워크 장애가 발생하면 연결이 끊어지면 자동으로 다시 연결됩니다. 연결 후 마스터 노드는 누락된 데이터 중 일부만 슬레이브 노드에 동기화합니다.

Sentinel

마스터-슬레이브 복제에는 자동으로 장애 조치가 불가능하고 고가용성을 달성할 수 없는 문제가 있습니다. 감시 모드는 이러한 문제를 해결합니다. 센티널 메커니즘은 마스터 노드와 슬레이브 노드 사이를 자동으로 전환할 수 있습니다.

클라이언트가 Redis에 연결되면 먼저 Sentinel에 연결됩니다. Sentinel은 클라이언트에게 Redis 마스터 노드의 주소를 알려준 후 클라이언트가 Redis에 연결하고 후속 작업을 수행합니다. 마스터 노드가 다운되면 Sentinel은 마스터 노드가 다운되었음을 감지하고 성능이 좋은 슬레이브 노드를 다시 선출하여 새로운 마스터 노드가 된 후 게시-구독 모드를 통해 다른 슬레이브 서버에 알려 전환할 수 있도록 합니다. 호스트.

Redis에서 꼭 마스터해야 할 20가지 질문, 와서 모아보세요! !

작동 방식

  • Sentinel은 자신이 알고 있는 MasterSlave에 초당 한 번씩 메시지를 보내고 > 다른 Sentinel 인스턴스는 PING 명령을 보냅니다. Sentinel以每秒钟一次的频率向它所知道的MasterSlave以及其他 Sentinel实例发送一个 PING命令。
  • 如果一个实例距离最后一次有效回复 PING 命令的时间超过指定值, 则这个实例会被 Sentine 标记为主观下线。
  • 如果一个Master被标记为主观下线,则正在监视这个Master的所有 Sentinel要以每秒一次的频率确认Master是否真正进入主观下线状态。
  • 当有足够数量的 Sentinel(大于等于配置文件指定值)在指定的时间范围内确认Master的确进入了主观下线状态, 则Master会被标记为客观下线 。若没有足够数量的 Sentinel同意 Master 已经下线, Master 的客观下线状态就会被解除。若 Master重新向 SentinelPING 命令返回有效回复, Master 的主观下线状态就会被移除。
  • 哨兵节点会选举出哨兵 leader,负责故障转移的工作。
  • 哨兵 leader 会推选出某个表现良好的从节点成为新的主节点,然后通知其他从节点更新主节点信息。

Redis cluster

哨兵模式解决了主从复制不能自动故障转移、达不到高可用的问题,但还是存在主节点的写能力、容量受限于单机配置的问题。而cluster模式实现了Redis的分布式存储,每个节点存储不同的内容,解决主节点的写能力、容量受限于单机配置的问题。

Redis cluster集群节点最小配置6个节点以上(3主3从),其中主节点提供读写操作,从节点作为备用节点,不提供请求,只作为故障转移使用。

Redis cluster采用虚拟槽分区,所有的键根据哈希函数映射到0~16383个整数槽内,每个节点负责维护一部分槽以及槽所映射的键值数据。

Redis에서 꼭 마스터해야 할 20가지 질문, 와서 모아보세요! !

哈希槽是如何映射到 Redis 实例上的?

  • 对键值对的key使用 crc16 算法计算一个结果

  • 将结果对 16384 取余,得到的值表示 key 对应的哈希槽

  • 根据该槽信息定位到对应的实例

优点:

  • 无中心架构,支持动态扩容;
  • 数据按照slot存储分布在多个节点,节点间数据共享,可动态调整数据分布
  • 高可用性。部分节点不可用时,集群仍可用。集群模式能够实现自动故障转移(failover),节点之间通过gossip协议交换状态信息,用投票机制完成SlaveMaster
  • 인스턴스에 대한 PING 명령에 대한 마지막 유효한 응답 이후의 시간이 지정된 값을 초과하는 경우 해당 인스턴스는 Sentine에 의해 주관적으로 오프라인으로 표시됩니다.

마스터가 주관적 오프라인으로 표시되면 이 마스터를 모니터링하는 모든 Sentinel은 1초에 한 번씩마스터는 실제로 주관적인 오프라인 상태에 들어갑니다. 충분한 수의 Sentinel(구성 파일에 지정된 값 이상)이 지정된 시간 내에 Master가 실제로 주관적인 오프라인 상태에 진입했음을 확인한 경우 범위이면 마스터는 객관적으로 오프라인으로 표시됩니다. 마스터가 오프라인이라는 데 동의할 만큼 센티널의 수가 충분하지 않은 경우 마스터의 객관적인 오프라인 상태가 해제됩니다. 마스터SentinelPING 명령에 대해 유효한 응답을 반환하면 마스터의 주관적인 오프라인 상태가 이동됩니다. 제거하다.

🎜Sentinel 노드는 장애 조치를 담당할 Sentinel 리더를 선출합니다. 🎜🎜센트리 리더는 성능이 좋은 슬레이브 노드를 새로운 마스터 노드로 선출한 후 다른 슬레이브 노드에게 마스터 노드 정보를 업데이트하도록 알립니다. 🎜🎜

Redis 클러스터🎜🎜Sentinel 모드는 마스터-슬레이브 복제가 자동으로 장애 조치를 수행할 수 없고 고가용성을 달성할 수 없지만 여전히 마스터 노드의 쓰기 능력과 용량이 제한되어 있는 문제를 해결합니다. 독립 실행형 구성에 문제가 있습니다. 클러스터 모드는 Redis의 분산 스토리지를 구현하고 각 노드는 서로 다른 콘텐츠를 저장하여 단일 시스템 구성으로 인해 마스터 노드의 쓰기 능력과 용량이 제한되는 문제를 해결합니다. 🎜🎜Redis 클러스터 노드의 최소 구성은 6개 노드(마스터 3개, 슬레이브 3개) 이상입니다. 마스터 노드는 읽기 및 쓰기 작업을 제공하고, 슬레이브 노드는 백업 노드 역할을 하며 요청을 제공하지 않고 노드만 제공합니다. 장애 조치에 사용됩니다. 🎜🎜Redis 클러스터는 🎜가상 슬롯 파티셔닝🎜을 사용합니다. 모든 키는 해시 함수에 따라 0~16383 정수 슬롯에 매핑됩니다. 각 노드는 슬롯의 일부와 슬롯에 매핑된 키 값 데이터를 유지 관리합니다. 🎜🎜Redis에서 꼭 마스터해야 할 20가지 질문, 와서 모아보세요! !🎜🎜🎜 해시 슬롯은 Redis 인스턴스에 어떻게 매핑되나요? 🎜🎜
    🎜🎜키-값 쌍의 key에 대해 crc16 알고리즘을 사용하여 결과를 계산합니다. 🎜🎜🎜🎜 결과는 16384의 모듈러스이며, 얻은 값은 🎜🎜🎜🎜해당 인스턴스는 슬롯 정보를 기반으로 위치합니다🎜🎜🎜🎜🎜장점: 🎜🎜🎜🎜중앙 아키텍처 없음, 🎜동적 확장 지원🎜; 🎜🎜데이터는 슬롯에 따라 여러 노드에 저장 및 배포되며, 노드 간에 데이터가 공유됩니다. 🎜데이터 배포는 동적으로 조정될 수 있습니다🎜 ; 🎜🎜🎜고가용성🎜. 일부 노드를 사용할 수 없어도 클러스터는 계속 사용할 수 있습니다. 클러스터 모드는 자동 장애 조치를 실현할 수 있으며, 노드는 gossip 프로토콜을 통해 상태 정보를 교환하고 투표 메커니즘을 사용하여 Slave에서 Master로의 전송을 완료합니다. 코드>. 역할 반전. 🎜🎜🎜🎜단점: 🎜🎜<ul> <li> <strong>일괄 작업</strong>(파이프라인)은 지원되지 않습니다. </li> <li>데이터는 비동기식으로 복사되며 <strong>데이터의 강력한 일관성은 보장되지 않습니다</strong>. </li> <li> <strong>트랜잭션 작업 지원이 제한됩니다</strong>. 동일한 노드에 여러 <code>키가 있는 트랜잭션 작업만 지원됩니다. 여러 가 서로 다른 노드에 배포되면 트랜잭션 기능을 사용할 수 없습니다. 사용됩니다. key在同一节点上的事务操作,当多个key分布于不同的节点上时无法使用事务功能。
  • key作为数据分区的最小粒度,不能将一个很大的键值对象如hashlist等映射到不同的节点。
  • 不支持多数据库空间,单机下的Redis可以支持到16个数据库,集群模式下只能使用1个数据库空间。

过期键的删除策略?

1、被动删除(惰性)。在访问key时,如果发现key已经过期,那么会将key删除。

2、主动删除(定期)。定时清理key,每次清理会依次遍历所有DB,从db随机取出20个key,如果过期就删除,如果其中有5个key过期,那么就继续对这个db进行清理,否则开始清理下一个db。

3、内存不够时清理。Redis有最大内存的限制,通过maxmemory参数可以设置最大内存,当使用的内存超过了设置的最大内存,就要进行内存释放, 在进行内存释放的时候,会按照配置的淘汰策略清理内存。

内存淘汰策略有哪些?

当Redis的内存超过最大允许的内存之后,Redis 会触发内存淘汰策略,删除一些不常用的数据,以保证Redis服务器正常运行。

Redisv4.0前提供 6 种数据淘汰策略

  • volatile-lru:LRU(Least Recently Used),最近使用。利用LRU算法移除设置了过期时间的key
  • allkeys-lru:当内存不足以容纳新写入数据时,从数据集中移除最近最少使用的key
  • volatile-ttl:从已设置过期时间的数据集中挑选将要过期的数据淘汰
  • volatile-random:从已设置过期时间的数据集中任意选择数据淘汰
  • allkeys-random:从数据集中任意选择数据淘汰
  • no-eviction:禁止删除数据,当内存不足以容纳新写入数据时,新写入操作会报错

Redisv4.0后增加以下两种

  • volatile-lfu:LFU,Least Frequently Used,最少使用,从已设置过期时间的数据集中挑选最不经常使用的数据淘汰。
  • allkeys-lfu:当内存不足以容纳新写入数据时,从数据集中移除最不经常使用的key。

内存淘汰策略可以通过配置文件来修改,相应的配置项是maxmemory-policy,默认配置是noeviction

key는 데이터 분할의 최소 단위입니다. hash, list 등과 같은 큰 키-값 개체는 매핑될 수 없습니다. 다른 노드.

여러 데이터베이스 공간을 지원하지 않습니다. 독립형 모드의 Redis는 최대 16개의 데이터베이스를 지원할 수 있으며 클러스터 모드에서는 1개의 데이터베이스 공간만 사용할 수 있습니다.

만료된 키의 삭제 전략은 무엇입니까?

1.

수동 삭제(게으름)

. 키에 접근할 때 키가 만료된 것으로 확인되면 해당 키가 삭제됩니다.

2. 적극 삭제(정기적으로). 정기적으로 키를 정리합니다. 각 정리는 모든 DB를 순차적으로 순회하고, db에서 20개의 키를 무작위로 꺼내고, 만료되면 삭제합니다. 5개의 키가 만료되면 계속해서 이 db를 정리하고, 그렇지 않으면 다음 db 정리를 시작합니다.

3.

메모리가 부족할 때 정리

. Redis에는 최대 메모리 제한이 있습니다. 최대 메모리는 maxmemory 매개 변수를 통해 설정할 수 있습니다. 사용된 메모리가 설정된 최대 메모리를 초과하면 메모리가 해제되어야 하며, 메모리는 구성된 제거 전략에 따라 정리됩니다.

기억 제거 전략은 무엇인가요?

Redis의 메모리가 최대 허용 메모리를 초과하면 Redis는 메모리 제거 전략을 실행하고 자주 사용되지 않는 일부 데이터를 삭제하여 Redis 서버의 정상적인 작동을 보장합니다.

Redisv4.0은 6가지 데이터 제거 전략을 제공합니다

:

휘발성-lru

: LRU(Least Recent Used), 최근에 사용됨. LRU 알고리즘을 사용하여 만료 시간이 설정된 키를 제거합니다

allkeys-lru

: 새로 작성된 데이터를 수용할 만큼 메모리가 부족한 경우 데이터 세트에서 가장 최근에 사용된 키를 제거합니다

휘발성-ttl
    : 만료 시간이 있는 데이터 세트에서 만료될 데이터를 선택하고 제거합니다.
  • 휘발성-random: 만료 시간이 있는 데이터 세트에서 데이터를 선택하고 제거합니다.

    🎜🎜allkeys-random🎜: 다음에서 데이터를 선택합니다. 🎜🎜🎜 no-eviction🎜: 데이터 삭제가 금지되어 있습니다. 메모리가 새로 작성된 데이터를 수용하기에 충분하지 않으면 새 쓰기 작업에서 오류가 보고됩니다🎜
🎜🎜 Redisv4.0에는 다음 두 가지 유형🎜이 추가되었습니다. 🎜🎜🎜🎜휘발성-lfu 🎜: LFU, Least 빈번하게 사용됨, 가장 적게 사용됨, 만료 시간이 있는 데이터 세트에서 가장 자주 사용되지 않는 데이터를 선택하여 제거합니다. 🎜🎜🎜allkeys-lfu🎜: 새로 작성된 데이터를 수용할 만큼 메모리가 부족한 경우 데이터 세트에서 가장 자주 사용되지 않는 키를 제거합니다. 🎜 🎜🎜메모리 제거 정책은 구성 파일🎜을 통해 수정할 수 있습니다. 해당 구성 항목은 maxmemory-policy이고, 기본 구성은 noeviction입니다. 🎜🎜캐시와 데이터베이스 간에 이중 쓰기 중에 데이터 일관성을 보장하는 방법은 무엇입니까? 🎜🎜🎜1. 캐시를 먼저 삭제한 후 데이터베이스를 업데이트하세요. 🎜🎜🎜업데이트 작업을 수행할 때, 후속 요청을 다시 읽으면 데이터베이스에서 새 데이터를 읽어서 데이터베이스를 업데이트합니다. 그런 다음 캐시로 업데이트되었습니다. 🎜🎜기존 문제: 캐시된 데이터를 삭제한 후 데이터베이스를 업데이트하기 전에 이 기간 동안 새로운 읽기 요청이 있으면 이전 데이터를 데이터베이스에서 읽고 캐시에 다시 쓰게 되어 다시 불일치가 발생하고 후속 읽기는 실패합니다. 모두 오래된 데이터입니다. 🎜🎜🎜2. 먼저 데이터베이스를 업데이트한 후 캐시를 삭제하세요🎜🎜🎜업데이트 작업을 수행할 때 먼저 MySQL을 업데이트하세요. 성공 후 캐시를 삭제한 후 후속 읽기 요청 중에 새 데이터를 캐시에 다시 쓰세요. 🎜🎜기존 문제: MySQL을 업데이트하고 캐시를 삭제하는 동안 읽기 요청은 여전히 ​​캐시된 이전 데이터입니다. 그러나 데이터베이스 업데이트가 완료되면 일관성이 유지되며 영향은 상대적으로 작습니다. 🎜🎜🎜3. 비동기 업데이트 캐시🎜🎜🎜데이터베이스 업데이트 작업이 완료된 후 캐시가 직접 작동되지 않고, 대신 작업 명령이 메시지로 캡슐화되어 메시지 대기열에 들어간 후 Redis 자체가 업데이트된 내용을 소비합니다. 메시지 큐는 데이터 작업 순서의 일관성을 보장하여 캐시 시스템의 데이터가 정상임을 보장합니다. 🎜🎜🎜캐시 침투, 캐시 눈사태, 캐시 고장 [자세한 설명]🎜Redis 캐시 침투, 침투, 눈사태 개념 및 솔루션🎜🎜🎜🎜캐시 침투🎜🎜캐시 침투는 🎜존재하지 않는 데이터🎜를 쿼리하는 것을 말합니다. 누락이 있을 때 수동적으로 기록되며, DB에서 데이터를 찾을 수 없으면 캐시에 기록되지 않습니다. 이로 인해 요청될 때마다 존재하지 않는 데이터가 DB에 쿼리되어 손실됩니다. 캐싱의 의미 트래픽이 많은 경우 DB가 중단될 수 있습니다. 🎜🎜🎜🎜🎜캐시 null 값🎜이며 데이터베이스를 확인하지 않습니다. 🎜
  • 采用布隆过滤器,将所有可能存在的数据哈希到一个足够大的bitmap中,查询不存在的数据会被这个bitmap拦截掉,从而避免了对DB的查询压力。

  • 布隆过滤器的原理:当一个元素被加入集合时,通过K个散列函数将这个元素映射成一个位数组中的K个点,把它们置为1。查询时,将元素通过散列函数映射之后会得到k个点,如果这些点有任何一个0,则被检元素一定不在,直接返回;如果都是1,则查询元素很可能存在,就会去查询Redis和数据库。

    缓存雪崩

    缓存雪崩是指在我们设置缓存时采用了相同的过期时间,导致缓存在某一时刻同时失效,请求全部转发到DB,DB瞬时压力过重挂掉。

    解决方法:在原有的失效时间基础上增加一个随机值,使得过期时间分散一些。

    缓存击穿

    缓存击穿:大量的请求同时查询一个 key 时,此时这个 key 正好失效了,就会导致大量的请求都落到数据库。缓存击穿是查询缓存中失效的 key,而缓存穿透是查询不存在的 key。

    解决方法:加分布式锁,第一个请求的线程可以拿到锁,拿到锁的线程查询到了数据之后设置缓存,其他的线程获取锁失败会等待50ms然后重新到缓存取数据,这样便可以避免大量的请求落到数据库。

    public String get(String key) {
        String value = redis.get(key);
        if (value == null) { 
            //缓存值过期
            String unique_key = systemId + ":" + key;
            //设置30s的超时
            if (redis.set(unique_key, 1, &#39;NX&#39;, &#39;PX&#39;, 30000) == 1) {  //设置成功
                value = db.get(key);
                redis.set(key, value, expire_secs);
                redis.del(unique_key);
            } else {  
                //其他线程已经到数据库取值并回写到缓存了,可以重试获取缓存值
                sleep(50);
                get(key);  //重试
            }
        } else {
            return value;
        }
    }

    pipeline的作用?

    redis客户端执行一条命令分4个过程:发送命令、命令排队、命令执行、返回结果。使用pipeline可以批量请求,批量返回结果,执行速度比逐条执行要快。

    使用pipeline组装的命令个数不能太多,不然数据量过大,增加客户端的等待时间,还可能造成网络阻塞,可以将大量命令的拆分多个小的pipeline命令完成。

    原生批命令(mset和mget)与pipeline对比:

    • 原生批命令是原子性,pipeline非原子性。pipeline命令中途异常退出,之前执行成功的命令不会回滚

    • 原生批命令只有一个命令,但pipeline支持多命令

    LUA脚本

    Redis 通过 LUA 脚本创建具有原子性的命令:当lua脚本命令正在运行的时候,不会有其他脚本或 Redis 命令被执行,实现组合命令的原子操作。

    在Redis中执行Lua脚本有两种方法:evalevalshaeval命令使用内置的 Lua 解释器,对 Lua 脚本进行求值。

    //第一个参数是lua脚本,第二个参数是键名参数个数,剩下的是键名参数和附加参数
    > eval "return {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}" 2 key1 key2 first second
    1) "key1"
    2) "key2"
    3) "first"
    4) "second"

    lua脚本作用

    1、Lua脚本在Redis中是原子执行的,执行过程中间不会插入其他命令。

    2、Lua脚本可以将多条命令一次性打包,有效地减少网络开销。

    应用场景

    举例:限制接口访问频率。

    在Redis维护一个接口访问次数的键值对,key是接口名称,value是访问次数。每次访问接口时,会执行以下操作:

    • 通过aop拦截接口的请求,对接口请求进行计数,每次进来一个请求,相应的接口访问次数count加1,存入redis。
    • 如果是第一次请求,则会设置count=1,并设置过期时间。因为这里set()expire()组合操作不是原子操作,所以引入lua脚本,实现原子操作,避免并发访问问题。
    • 如果给定时间范围内超过最大访问次数,则会抛出异常。
    private String buildLuaScript() {
        return "local c" +
            "\nc = redis.call(&#39;get&#39;,KEYS[1])" +
            "\nif c and tonumber(c) > tonumber(ARGV[1]) then" +
            "\nreturn c;" +
            "\nend" +
            "\nc = redis.call(&#39;incr&#39;,KEYS[1])" +
            "\nif tonumber(c) == 1 then" +
            "\nredis.call(&#39;expire&#39;,KEYS[1],ARGV[2])" +
            "\nend" +
            "\nreturn c;";
    }
    
    String luaScript = buildLuaScript();
    RedisScript<Number> redisScript = new DefaultRedisScript<>(luaScript, Number.class);
    Number count = redisTemplate.execute(redisScript, keys, limit.count(), limit.period());

    PS:这种接口限流的实现方式比较简单,问题也比较多,一般不会使用,接口限流用的比较多的是令牌桶算法和漏桶算法。

    更多编程相关知识,请访问:编程入门!!

    위 내용은 Redis에서 꼭 마스터해야 할 20가지 질문, 와서 모아보세요! !의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

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