이 기사에서는 지속성 전략에 대한 관련 내용을 주로 소개하는 Redis에 대한 관련 지식을 제공합니다. RDB 지속성이란 지정된 시간 간격 내에 메모리에 데이터 세트의 스냅샷을 쓰는 것을 말합니다. 모든 사람에게 도움이 되기를 바랍니다.
추천 학습: Redis 동영상 튜토리얼
원격 사전 서비스인 Redis(원격 사전 서버)는 오픈 소스 메모리 캐시 데이터 저장 서비스입니다. ANSI C 언어로 작성되어 네트워크, 메모리 기반 및 영구 로그 유형, Key-Value 데이터 저장을 지원하고 다국어 API를 제공합니다.
Redis는 메모리 내 데이터베이스이며 데이터는 메모리에 저장됩니다. 프로세스 종료로 인한 데이터의 영구적인 손실을 방지하려면 Redis의 데이터를 어떤 형식(데이터 또는 명령)으로 메모리에서 하드 디스크로 정기적으로 저장해야 합니다. 다음에 Redis가 다시 시작되면 영구 파일을 사용하여 데이터 복구를 수행합니다. 또한 재해 백업 목적으로 영구 파일을 원격 위치에 복사할 수 있습니다. Redis에는 두 가지 지속성 메커니즘이 있습니다.
RDB는 현재 데이터를 하드 디스크에 저장하고, AOF는 현재 데이터를 저장합니다. 실행된 쓰기 명령은 하드 디스크에 저장됩니다(MySQL의 Binlog와 유사). AOF 지속성은 실시간 성능이 더 좋습니다. 즉, 프로세스가 예기치 않게 종료될 때 손실되는 데이터가 적습니다.
rdb ( redisdata base)은 지정된 시간 간격 내에서 메모리에 데이터 세트의 스냅 샷을 쓰는 것을 나타냅니다 메모리 스냅샷(메모리 데이터의 직렬화된 이진 형식) 형식으로 유지됩니다. 매번 Redis에서 스냅샷이 생성되어 데이터를 완전히 백업합니다.
장점:
단점:
기본적으로 Redis는 데이터베이스 스냅샷을 dump.rdb라는 바이너리 파일에 저장합니다. RDB 파일 구조는 다섯 부분으로 구성됩니다.
(1) 길이가 5바이트인 REDIS
상수 문자열. REDIS
常量字符串。
(2)4字节的 db_version,标识 RDB 文件版本。
(3)databases:不定长度,包含零个或多个数据库,以及各数据库中的键值对数据。
(4)1字节的 EOF 常量,表示文件正文内容结束。
(5)check_sum: 8字节长的无符号整数,保存校验和。
数据结构举例,以下是数据库[0]和数据库[3]有数据的情况:
手动指令触发
手动触发 RDB 持久化的方式可以使用 save
命令和 bgsave
命令,这两个命令的区别如下:
save
:执行 save
指令,阻塞 Redis 的其他操作,会导致 Redis 无法响应客户端请求,不建议使用。
bgsave
:执行 bgsave
指令,Redis 后台创建子进程,异步进行快照的保存操作,此时 Redis 仍然能响应客户端的请求。
自动间隔性保存
在默认情况下,Redis 将数据库快照保存在名字为 dump.rdb的二进制文件中。可以对 Redis 进行设置,让它在“ N 秒内数据集至少有 M 个改动”这一条件被满足时,自动保存一次数据集。
比如说, 以下设置会让 Redis 在满足“ 60 秒内有至少有 10 个键被改动”这一条件时,自动保存一次数据集:save 60 10
save
명령과 bgsave
명령을 사용할 수 있습니다. 이 두 명령의 차이점은 다음과 같습니다. 🎜🎜 save
: Redis의 다른 작업을 차단하기 위해 save
명령을 실행하면 Redis가 클라이언트 요청에 응답할 수 없게 되므로 권장되지 않습니다. 🎜🎜bgsave
: bgsave
명령을 실행하면 Redis는 백그라운드에서 하위 프로세스를 생성하고 스냅샷을 비동기식으로 저장합니다. 이때 Redis는 여전히 클라이언트 요청에 응답할 수 있습니다. . 🎜🎜🎜자동 간격 저장🎜🎜🎜기본적으로 Redis는 데이터베이스 스냅샷을 dump.rdb라는 바이너리 파일에 저장합니다. Redis는 "데이터 세트에 N초 내에 최소 M개의 변경 사항이 있음"이라는 조건이 충족되면 데이터 세트를 자동으로 저장하도록 설정할 수 있습니다. 🎜🎜예를 들어, 다음 설정을 사용하면 Redis가 "60초 내에 최소 10개의 키가 변경되었습니다"라는 조건을 충족할 때 데이터 세트를 자동으로 저장하게 됩니다: save 60 10
. 🎜Redis의 기본 구성은 다음 세 가지 설정 중 하나가 충족되면 자동 저장이 실행될 수 있습니다.
save 60 10000 save 300 10 save 900 1
자동 저장 구성의 데이터 구조
자동 저장이 실행되는 서버의 조건을 기록합니다. <code>BGSAVE
saveparams 속성. BGSAVE
条件的saveparams
属性。
lastsave
属性:记录服务器最后一次执行 SAVE
或者 BGSAVE
的时间。
dirty
lastsave
속성: 서버가 SAVE
또는 BGSAVE
를 마지막으로 실행한 시간을 기록합니다. dirty
속성: RDB 파일이 마지막으로 저장된 이후 서버가 쓴 횟수입니다.
RDB 지속성 체계를 백업할 때 Redis는 지속성을 위해 별도의 하위 프로세스를 포크하고, 데이터를 임시 파일에 쓰고, 지속성이 완료된 후 이전 RDB 파일을 교체합니다. 전체 지속성 프로세스 동안 기본 프로세스(클라이언트에 서비스를 제공하는 프로세스)는 IO 작업에 참여하지 않으므로 Redis 서비스의 높은 성능이 보장됩니다. RDB 지속성 메커니즘은 요구 사항이 높지 않은 사용에 적합합니다. 데이터 무결성을 위해 효율적인 복구를 추구합니다. 다음은 RDB 지속성 프로세스를 보여줍니다.
하위 프로세스는 스냅샷 쓰기를 완료하고 이전 RDB 파일을 교체한 다음 하위 프로세스를 종료합니다.
Fork 하위 프로세스의 역할
효율성을 이유로 Linux 운영 체제는 COW(쓰기 시 복사) 쓰기 중 복사 메커니즘을 사용합니다. 포크 하위 프로세스는 일반적으로 프로세스의 메모리가 부족할 때만 상위 프로세스와 함께 물리적 메모리 섹션을 사용합니다. 공간이 수정되면 메모리 공간이 복사됩니다.
Redis에서 RDB 지속성은 이 기술을 최대한 활용합니다. Redis는 지속성 중에 하위 프로세스를 분기하기 위해 glibc 함수를 호출하고 지속성 작업을 전적으로 담당하므로 상위 프로세스가 계속해서 서비스를 제공할 수 있습니다. 고객. Fork의 하위 프로세스는 처음에 상위 프로세스(Redis의 기본 프로세스)와 동일한 메모리를 공유합니다. 클라이언트가 지속성 프로세스 중에 메모리의 데이터를 수정하도록 요청하면 COW(Copy On Write) 메커니즘이 사용됩니다. 메모리의 데이터를 수정합니다. 데이터 세그먼트 페이지가 분리됩니다. 즉, 수정할 메인 프로세스를 위해 메모리 조각이 복사됩니다.
fork를 통해 생성된 하위 프로세스는 상위 프로세스와 정확히 동일한 메모리 공간을 얻을 수 있으며 상위 프로세스에 의한 메모리 수정은 하위 프로세스에 보이지 않으며 둘은 서로 영향을 미치지 않습니다. Fork를 통해 자식 프로세스를 생성합니다. 대용량 메모리의 복사는 즉시 실행되지 않고 COW(Copy On Write)를 사용합니다. 커널은 새로 생성된 하위 프로세스에 대한 가상 공간 구조만 생성하며 상위 프로세스의 가상 실제 구조를 복사하지만 상위 프로세스와 하위 프로세스의 물리적 공간을 공유하지는 않습니다. 프로세스는 해당 세그먼트를 변경합니다. 동작이 발생하면 물리적 공간이 하위 프로세스의 해당 세그먼트에 할당됩니다.AOF (Append Only File) 是把所有对内存进行修改的指令(写操作)以独立日志文件的方式进行记录,重启时通过执行 AOF 文件中的 Redis 命令来恢复数据。类似MySql bin-log 原理。AOF 能够解决数据持久化实时性问题,是现在 Redis 持久化机制中主流的持久化方案。
优点:
缺点:
被写入 AOF 文件的所有命令都是以 RESP 格式保存的,是纯文本格式保存在 AOF 文件中。
Redis 客户端和服务端之间使用一种名为
RESP(REdis Serialization Protocol)
的二进制安全文本协议进行通信。
下面以一个简单的 SET 命令进行举例:
redis> SET mykey "hello" //客户端命令OK
客户端封装为以下格式(每行用 \r\n
分隔)
*3$3SET$5mykey$5hello
AOF 文件中记录的文本内容如下
*2\r\n$6\r\nSELECT\r\n$1\r\n0\r\n //多出一个SELECT 0 命令,用于指定数据库,为系统自动添加 *3\r\n$3\r\nSET\r\n$5\r\nmykey\r\n$5\r\nhello\r\n
AOF 持久化方案进行备份时,客户端所有请求的写命令都会被追加到 AOF 缓冲区中,缓冲区中的数据会根据 Redis 配置文件中配置的同步策略来同步到磁盘上的 AOF 文件中,追加保存每次写的操作到文件末尾。同时当 AOF 的文件达到重写策略配置的阈值时,Redis 会对 AOF 日志文件进行重写,给 AOF 日志文件瘦身。Redis 服务重启的时候,通过加载 AOF 日志文件来恢复数据。
AOF 的执行流程包括:
命令追加(append)
Redis 先将写命令追加到缓冲区 aof_buf,而不是直接写入文件,主要是为了避免每次有写命令都直接写入硬盘,导致硬盘 IO 成为 Redis 负载的瓶颈。
struct redisServer { //其他域... sds aof_buf; // sds类似于Java中的String //其他域...}
文件写入(write)和文件同步(sync)
根据不同的同步策略将 aof_buf 中的内容同步到硬盘;
Linux 操作系统中为了提升性能,使用了页缓存(page cache)。当我们将 aof_buf 的内容写到磁盘上时,此时数据并没有真正的落盘,而是在 page cache 中,为了将 page cache 中的数据真正落盘,需要执行 fsync / fdatasync 命令来强制刷盘。这边的文件同步做的就是刷盘操作,或者叫文件刷盘可能更容易理解一些。
AOF 缓存区的同步文件策略由参数 appendfsync 控制,有三种同步策略,各个值的含义如下:
always
:命令写入 aof_buf 后立即调用系统 write 操作和系统 fsync 操作同步到 AOF 文件,fsync 完成后线程返回。这种情况下,每次有写命令都要同步到 AOF 文件,硬盘 IO 成为性能瓶颈,Redis 只能支持大约几百TPS写入,严重降低了 Redis 的性能;即便是使用固态硬盘(SSD),每秒大约也只能处理几万个命令,而且会大大降低 SSD 的寿命。可靠性较高,数据基本不丢失。no
:命令写入 aof_buf 后调用系统 write 操作,不对 AOF 文件做 fsync 同步;同步由操作系统负责,通常同步周期为30秒。这种情况下,文件同步的时间不可控,且缓冲区中堆积的数据会很多,数据安全性无法保证。everysec
:命令写入 aof_buf 后调用系统 write 操作,write 完成后线程返回;fsync 同步文件操作由专门的线程每秒调用一次。everysec 是前述两种策略的折中,是性能和数据安全性的平衡,因此是 Redis 的默认配置,也是我们推荐的配置。文件重写(rewrite)
定期重写 AOF 文件,达到压缩的目的。
AOF 重写是 AOF 持久化的一个机制,用来压缩 AOF 文件,通过 fork 一个子进程,重新写一个新的 AOF 文件,该次重写不是读取旧的 AOF 文件进行复制,而是读取内存中的Redis数据库,重写一份 AOF 文件,有点类似于 RDB 的快照方式。
文件重写之所以能够压缩 AOF 文件,原因在于:
前面提到 AOF 的缺点时,说过 AOF 属于日志追加的形式来存储 Redis 的写指令,这会导致大量冗余的指令存储,从而使得 AOF 日志文件非常庞大,比如同一个 key 被写了 10000 次,最后却被删除了,这种情况不仅占内存,也会导致恢复的时候非常缓慢,因此 Redis 提供重写机制来解决这个问题。Redis 的 AOF 持久化机制执行重写后,保存的只是恢复数据的最小指令集,我们如果想手动触发可以使用如下指令:
bgrewriteaof
文件重写时机
相关参数:
同时满足下面两个条件,则触发 AOF 重写机制:
AOF 重写流程如下:
bgrewriteaof 触发重写,判断是否存在 bgsave 或者 bgrewriteaof 正在执行,存在则等待其执行结束再执行
子进程遍历 Redis 内存快照中数据写入临时 AOF 文件,同时会将新的写指令写入 aof_buf 和 aof_rewrite_buf 两个重写缓冲区,前者是为了写回旧的 AOF 文件,后者是为了后续刷新到临时 AOF 文件中,防止快照内存遍历时新的写入操作丢失
子进程结束临时 AOF 文件写入后,通知主进程
主进程会将上面 3 中的 aof_rewirte_buf 缓冲区中的数据写入到子进程生成的临时 AOF 文件中
在实际中,为了避免在执行命令时造成客户端输入缓冲区溢出,重写程序会检查集合元素数量是否超过 REDIS_AOF_REWRITE_ITEMS_PER_CMD 常量的值,如果超过了,则会使用多个命令来记录,而不单单使用一条命令。
Redis 2.9版本中该常量为64,如果一个命令的集合键包含超过了64个元素,重写程序会拆成多个命令。
AOF重写是一个有歧义的名字,该功能是通过直接读取数据库的键值对实现的,程序无需对现有AOF文件进行任何读入、分析或者写入操作。
Redis 为什么考虑使用 AOF 而不是 WAL 呢?
很多数据库都是采用的 Write Ahead Log(WAL)写前日志,其特点就是先把修改的数据记录到日志中,再进行写数据的提交,可以方便通过日志进行数据恢复。
但是 Redis 采用的却是 AOF(Append Only File)写后日志,特点就是先执行写命令,把数据写入内存中,再记录日志。
시스템이 먼저 명령을 실행하도록 하면 성공적으로 실행할 수 있는 명령만 로그에 기록됩니다. 따라서 Redis는 잘못된 명령이 기록되는 것을 방지하기 위해 쓰기 후 로깅을 사용합니다.
또 다른 이유는 AOF는 명령이 실행된 후에만 로그를 기록하므로 현재 쓰기 작업을 차단하지 않는다는 것입니다.
버전 번호가 2.4 이상인 Redis에서는 BGSAVE 실행 중에 BGREWRITEAOF를 실행할 수 없습니다. 반면, BGREWRITEAOF 실행 중에는 BGSAVE를 실행할 수 없습니다. 이렇게 하면 두 개의 Redis 백그라운드 프로세스가 디스크에서 동시에 과도한 I/O 작업을 수행하는 것을 방지할 수 있습니다.
BGSAVE가 실행 중이고 사용자가 BGREWRITEAOF 명령을 명시적으로 호출하는 경우 서버는 사용자에게 OK 상태로 응답하고 BGREWRITEAOF 실행이 예약되었음을 사용자에게 알립니다. BGSAVE가 완료되면 BGREWRITEAOF가 공식적으로 시작됩니다.
Redis가 시작될 때 RDB 지속성과 AOF 지속성이 모두 켜져 있으면 프로그램은 일반적으로 AOF 파일에 저장된 데이터가 가장 완전하기 때문에 AOF 파일을 사용하여 데이터 세트를 복원하는 데 우선 순위를 부여합니다.
Redis 4.0 이후 대부분의 사용 시나리오에서는 지속성 메커니즘으로 RDB 또는 AOF만 사용하지 않고 두 가지의 장점을 모두 고려합니다. 그 이유는 RDB는 속도가 빠르지만 손실되는 데이터가 많고 데이터 무결성을 보장할 수 없기 때문이며, AOF는 데이터 무결성을 최대한 보장할 수 있지만 데이터 재생 및 복구 등 성능이 비판을 받는 것은 사실이다.
Redis는 버전 4.0부터 RDB-AOF 하이브리드 지속성 모드를 도입했습니다. 이 모드는 AOF 지속성 모드를 기반으로 구축되었습니다. aof-use-rdb-preamble yes
를 통해 활성화됩니다.
그런 다음 Redis 서버는 AOF 재작성 작업을 수행할 때 BGSAVE 명령을 실행하는 것처럼 데이터베이스의 현재 상태를 기반으로 해당 RDB 데이터를 생성하고 이 데이터를 새로 생성된 AOF 파일에 씁니다. 쓰기 시작 후 실행된 AOF rewrite Redis 명령은 프로토콜 텍스트 형식으로 새 AOF 파일의 끝 부분, 즉 기존 RDB 데이터 뒤에 계속 추가됩니다.
즉, RDB-AOF 하이브리드 지속 기능이 활성화된 후 서버에서 생성된 AOF 파일은 두 부분으로 구성됩니다. AOF 파일 시작 부분의 데이터는 RDB 형식의 데이터이고 그 다음은 다음과 같습니다. RDB 데이터는 AOF 형식의 데이터입니다.
RDB-AOF 하이브리드 지속성 모드를 지원하는 Redis 서버가 시작되고 AOF 파일을 로드하면 AOF 파일의 시작 부분에 RDB 형식 콘텐츠가 포함되어 있는지 확인합니다.
로그 파일 구조는 다음과 같습니다.
마지막으로 둘을 요약하자면 어느 것이 더 좋을까요?
추천 학습: Redis 비디오 튜토리얼
위 내용은 Redis 지속성 전략에 대한 간략한 분석의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!