이 글은 지속성이 필요한 이유, RDB 지속성, AOF 지속성 등 지속성과 관련된 문제를 주로 소개하는 Redis에 대한 관련 지식을 제공합니다. 모두에게 도움이 되기를 바랍니다.
추천 학습: Redis 비디오 튜토리얼
Redis는 메모리를 기반으로 데이터를 운영합니다. 프로세스 종료, 서버 다운타임 등 예상치 못한 상황이 발생할 경우 지속성 메커니즘이 없으면 Redis의 데이터가 손실되어 복구할 수 없습니다. 지속성 메커니즘을 통해 Redis는 다음에 다시 시작할 때 데이터 복구를 위해 이전에 지속된 파일을 사용할 수 있습니다. Redis가 지원하는 두 가지 지속성 메커니즘:
RDB: 현재 데이터의 스냅샷을 생성하고 하드 디스크에 저장합니다.
AOF: 데이터의 모든 작업을 하드 디스크에 기록합니다.
지정된 시간 간격 내에 메모리에 설정된 데이터의 스냅샷을 디스크에 기록합니다. 복원되면 스냅샷 파일을 메모리로 직접 읽어옵니다. RDB(Redis DataBase) 지속성은 Redis에 있는 모든 현재 데이터의 스냅샷을 생성하여 하드 디스크에 저장하는 것입니다. RDB 지속성은 수동 또는 자동으로 트리거될 수 있습니다.
redis는 지속성을 위해 별도의 하위 프로세스를 생성(포크)합니다. 먼저 데이터를 임시 파일에 기록합니다. 지속성 프로세스가 완료된 후 이 임시 파일은 마지막 지속 파일을 대체하는 데 사용됩니다. 전체 프로세스 동안 기본 프로세스는 IO 작업을 수행하지 않으므로 매우 높은 성능이 보장됩니다. 대규모 데이터 복구가 필요하고 데이터 복구의 무결성이 그다지 중요하지 않은 경우에는 RDB 방법이 AOF 방법보다 더 효율적입니다. RDB의 단점은 마지막으로 유지된 데이터가 손실될 수 있다는 것입니다.
save
및 bgsave
명령 모두 RDB 지속성을 수동으로 트리거할 수 있습니다. save
和 bgsave
命令都可以手动触发RDB持久化。
save
save
命令会手动触发RDB持久化,但是save
命令会阻塞Redis服务,直到RDB持久化完成。当Redis服务储存大量数据时,会造成较长时间的阻塞,不建议使用。bgsave
bgsave
命令也会手动触发RDB持久化,和save
命令不同是:Redis服务一般不会阻塞。Redis进程会执行fork操作创建子进程,RDB持久化由子进程负责,不会阻塞Redis服务进程。Redis服务的阻塞只发生在fork阶段,一般情况时间很短。bgsave
命令的具体流程如下图:bgsave
命令,Redis进程先判断当前是否存在正在执行的RDB或AOF子线程,如果存在就是直接结束。bgsave
命令就结束了,自此Redis进程不会被阻塞,可以响应其他命令。除了执行以上命令手动触发以外,Redis内部可以自动触发RDB持久化。自动触发的RDB持久化都是采用bgsave
的方式,减少Redis进程的阻塞。那么,在什么场景下会自动触发呢?
save
的相关配置,如sava m n
,它表示在m秒内数据被修改过n次时,自动触发bgsave
操作。bgsave
操作,并且把生成的RDB文件发送给从节点。debug reload
命令时,也会自动触发bgsave
操作。shutdown
命令时,如果没有开启AOF持久化也会自动触发bgsave
save
save
명령을 실행하면 RDB 지속성이 수동으로 트리거되지만 save
명령은 차단됩니다. Redis는 RDB 지속성이 완료될 때까지 서비스합니다. Redis 서비스가 많은 양의 데이터를 저장하는 경우 장기간 정체가 발생하므로 권장되지 않습니다.
bgsave
🎜🎜 bgsave
명령을 실행하면 save
명령과 달리 RDB 지속성이 수동으로 트리거됩니다. 일반적으로 Redis 서비스는 차단하지 않습니다. Redis 프로세스는 포크 작업을 수행하여 하위 프로세스를 생성하며 RDB 지속성을 담당하며 Redis 서비스 프로세스를 차단하지 않습니다. Redis 서비스 차단은 포크 단계에서만 발생하며 일반적으로 시간이 매우 짧습니다. 🎜🎜bgsave
명령의 구체적인 프로세스는 다음과 같습니다. 🎜🎜🎜 1. bgsave
명령을 실행합니다. Redis 프로세스는 먼저 현재 실행 중인 RDB 또는 AOF 하위 스레드가 있는지 확인합니다. 존재하는 경우, 바로 종료됩니다. 🎜 2. Redis 프로세스는 하위 스레드를 생성하기 위해 포크 작업을 수행합니다. 포크 작업 중에 Redis 프로세스가 차단됩니다. 🎜 3. Redis 프로세스 포크가 완료되면 bgsave
명령이 종료됩니다. 그때부터 Redis 프로세스는 차단되지 않으며 다른 명령에 응답할 수 있습니다. 🎜 4. 하위 프로세스는 Redis 프로세스의 메모리를 기반으로 스냅샷 파일을 생성하고 원본 RDB 파일을 대체합니다. 🎜 5. 동시에 메인 프로세스에 rdb 지속성이 완료되었음을 알리는 신호가 전송되고, 메인 프로세스는 관련 통계 정보(info Persitence 아래의 rdb_* 관련 옵션)를 업데이트합니다. 🎜🎜🎜4. 자동 트리거🎜🎜위 명령을 실행하여 수동으로 트리거하는 것 외에도 Redis 내에서 RDB 지속성을 자동으로 트리거할 수 있습니다. 자동으로 트리거되는 RDB 지속성은 bgsave
메서드를 사용하여 Redis 프로세스 차단을 줄입니다. 그렇다면 어떤 상황에서 자동으로 실행되나요? 🎜save
관련 구성은 구성 파일에 설정됩니다(예: sava m n
). 이는 데이터가 m 내에서 n번 수정될 때를 의미합니다. 초, bgsave
작업을 자동으로 트리거합니다. 🎜bgsave
작업을 수행하고 생성된 RDB 파일을 슬레이브 노드로 보냅니다. 🎜debug reload
명령을 실행하면 bgsave
작업도 자동으로 실행됩니다. 🎜shutdown
명령을 실행할 때 AOF 지속성이 활성화되지 않은 경우 bgsave
작업이 자동으로 트리거됩니다. 🎜🎜🎜5. RDB 장점🎜🎜RDB 파일은 특정 시점의 모든 Redis 데이터에 대한 스냅샷인 컴팩트 바이너리 압축 파일입니다. 따라서 RDB를 이용한 데이터 복구 속도는 AOF보다 훨씬 빠르며, 이는 백업, 전체 복제, 재해 복구 등의 시나리오에 매우 적합합니다. 🎜bgsave
작업을 수행할 때마다 자식을 생성하기 위해 포크 작업을 수행해야 합니다. 이는 잦은 실행 비용이 너무 높습니다. 실시간 지속성 또는 두 번째 수준의 지속성을 달성할 수 없습니다. bgsave
操作都要执行fork操作创建子经常,属于重量级操作,频繁执行成本过高,所以无法做到实时持久化,或者秒级持久化。
另外,由于Redis版本的不断迭代,存在不同格式的RDB版本,有可能出现低版本的RDB格式无法兼容高版本RDB文件的问题。
快照周期:内存快照虽然可以通过技术人员手动执行SAVE
或BGSAVE
SAVE
또는 BGSAVE
명령을 수동으로 실행하여 메모리 스냅샷을 수행할 수 있지만 프로덕션 환경에서는 대부분의 경우 주기적인 실행 조건이 설정됩니다. 🎜🎜Redis의 새로운 기본 주기 설정🎜🎜🎜# 周期性执行条件的设置格式为 save <seconds> <changes> # 默认的设置为: save 900 1 save 300 10 save 60 10000 # 以下设置方式为关闭RDB快照功能 save ""</changes></seconds>
# 文件名称 dbfilename dump.rdb # 文件保存路径 dir ./ # 如果持久化出错,主进程是否停止写入 stop-writes-on-bgsave-error yes # 是否压缩 rdbcompression yes # 导入时是否检查 rdbchecksum yes
bgsave
子进程相互不影响。但是,如果主线程要修改一块数据(例如图中的键值对 C),那么,这块数据就会被复制一份,生成该数据的副本。然后,bgsave
子进程会把这个副本数据写入 RDB 文件,而在这个过程中,主线程仍然可以直接修改原来的数据。针对RDB不适合实时持久化的问题,Redis提供了AOF持久化方式来解决
AOF(Append Only File)持久化是把每次写命令追加写入日志中,当需要恢复数据时重新执行AOF文件中的命令就可以了。AOF解决了数据持久化的实时性,也是目前主流的Redis持久化方式。
Redis是“写后”日志,Redis先执行命令,把数据写入内存,然后才记录日志。日志里记录的是Redis收到的每一条命令,这些命令是以文本形式保存。PS: 大多数的数据库采用的是写前日志(WAL),例如MySQL,通过写前日志和两阶段提交,实现数据和逻辑的一致性。
而AOF日志采用写后日志,即先写内存,后写日志。
为什么采用写后日志?
Redis要求高性能,采用写日志有两方面好处:
但这种方式存在潜在风险:
AOF日志记录Redis的每个写命令,步骤分为:命令追加(append)、文件写入(write)和文件同步(sync)。
默认情况下,Redis是没有开启AOF的,可以通过配置redis.conf文件来开启AOF持久化,关于AOF的配置如下:
# appendonly参数开启AOF持久化 appendonly no # AOF持久化的文件名,默认是appendonly.aof appendfilename "appendonly.aof" # AOF文件的保存位置和RDB文件的位置相同,都是通过dir参数设置的 dir ./ # 同步策略 # appendfsync always appendfsync everysec # appendfsync no # aof重写期间是否同步 no-appendfsync-on-rewrite no # 重写触发配置 auto-aof-rewrite-percentage 100 auto-aof-rewrite-min-size 64mb # 加载aof出错如何处理 aof-load-truncated yes # 文件重写策略 aof-rewrite-incremental-fsync yes
以下是Redis中关于AOF的主要配置信息:
appendfsync:这个参数项是AOF功能最重要的设置项之一,主要用于设置“真正执行”操作命令向AOF文件中同步的策略。
什么叫“真正执行”呢?还记得Linux操作系统对磁盘设备的操作方式吗? 为了保证操作系统中I/O队列的操作效率,应用程序提交的I/O操作请求一般是被放置在linux Page Cache中的,然后再由Linux操作系统中的策略自行决定正在写到磁盘上的时机。而Redis中有一个fsync()函数,可以将Page Cache中待写的数据真正写入到物理设备上,而缺点是频繁调用这个fsync()函数干预操作系统的既定策略,可能导致I/O卡顿的现象频繁 。
与上节对应,appendfsync参数项可以设置三个值,分别是:always、everysec、no,默认的值为everysec。
no-appendfsync-on-rewrite:always和everysec的设置会使真正的I/O操作高频度的出现,甚至会出现长时间的卡顿情况,这个问题出现在操作系统层面上,所有靠工作在操作系统之上的Redis是没法解决的。为了尽量缓解这个情况,Redis提供了这个设置项,保证在完成fsync函数调用时,不会将这段时间内发生的命令操作放入操作系统的Page Cache(这段时间Redis还在接受客户端的各种写操作命令)。
auto-aof-rewrite-percentage: 위에서 언급했듯이 프로덕션 환경에서는 기술자가 "BGREWRITEAOF
" 명령을 사용하여 언제 어디서나 AOF 파일을 다시 쓰는 것이 불가능합니다. 따라서 Redis에서 AOF 파일의 자동 재작성 전략에 의존해야 하는 경우가 더 많습니다. Redis는 AOF 파일의 자동 재작성을 트리거하기 위한 두 가지 설정을 제공합니다. BGREWRITEAOF
”命令去重写AOF文件。所以更多时候我们需要依靠Redis中对AOF文件的自动重写策略。Redis中对触发自动重写AOF文件的操作提供了两个设置:
auto-aof-rewrite-percentage表示如果当前AOF文件的大小超过了上次重写后AOF文件的百分之多少后,就再次开始重写AOF文件。例如该参数值的默认设置值为100,意思就是如果AOF文件的大小超过上次AOF文件重写后的1倍,就启动重写操作。
auto-aof-rewrite-min-size:设置项表示启动AOF文件重写操作的AOF文件最小大小。如果AOF文件大小低于这个值,则不会触发重写操作。注意,auto-aof-rewrite-percentage和auto-aof-rewrite-min-size只是用来控制Redis中自动对AOF文件进行重写的情况,如果是技术人员手动调用“BGREWRITEAOF
는 현재 AOF 파일의 크기가 마지막 재작성 후 AOF 파일의 백분율을 초과하는지 여부를 나타냅니다. AOF 파일을 다시 작성하세요. 예를 들어 이 매개변수 값의 기본 설정 값은 100입니다. 이는 AOF 파일 크기가 마지막 AOF 파일 다시 쓰기 크기의 1배를 초과하면 다시 쓰기 작업이 시작된다는 의미입니다.auto-aof-rewrite-min-size
: 설정 항목은 AOF 파일 다시 쓰기 작업을 시작하기 위한 AOF 파일의 최소 크기를 나타냅니다. AOF 파일 크기가 이 값보다 작으면 다시 쓰기 작업이 트리거되지 않습니다. auto-aof-rewrite-percentage 및 auto-aof-rewrite-min-size는 Redis에서 AOF 파일의 자동 다시 쓰기를 제어하는 데만 사용됩니다. 기술자가 "BGREWRITEAOF
” 명령을 수동으로 호출하는 경우 이 두 가지 제한 사항이 적용되지 않습니다. 3. AOF 재작성에 대한 심층적인 이해
AOF는 각 쓰기 명령을 AOF 파일에 기록합니다. AOF 파일은 점점 더 커질 것입니다. 제어하지 않으면 Redis 서버는 물론 운영 체제에도 영향을 미칩니다. 또한 AOF 파일이 클수록 데이터 복구 속도가 느려집니다. AOF 파일 크기 확장 문제를 해결하기 위해 Redis는 AOF 파일을 "줄이기" 위한 AOF 파일 재작성 메커니즘을 제공합니다.
AOF 재작성을 설명하는 그림
AOF 재작성이 차단되나요?
AOF 재작성 프로세스는 백그라운드 프로세스 bgrewriteaof에 의해 완료됩니다. 메인 스레드는 백그라운드에서 bgrewriteaof 하위 프로세스에서 포크됩니다. 포크는 메인 스레드의 메모리를 데이터베이스의 최신 데이터가 포함된 bgrewriteaof 하위 프로세스로 복사합니다. 그런 다음 bgrewriteaof 하위 프로세스는 복사된 데이터를 작업에 하나씩 쓰고 기본 스레드에 영향을 주지 않고 다시 쓰기 로그에 기록할 수 있습니다. 따라서 aof를 다시 작성하면 프로세스를 포크할 때 메인 스레드가 차단됩니다.
AOF 로그는 언제 다시 작성되나요?
AOF 재작성 트리거를 제어하는 두 가지 구성 항목이 있습니다. auto-aof-rewrite-min-size: AOF 재작성을 실행할 때 파일의 최소 크기를 나타내며 기본값은 64MB입니다.
: 이 값은 현재 aof 파일 크기와 마지막 다시 쓰기 후 aof 파일 크기의 차이를 마지막 다시 쓰기 후 aof 파일 크기로 나누어 계산됩니다. 즉, 마지막으로 재작성된 AOF 파일과 비교한 현재 AOF 파일의 증분 크기 및 마지막 재작성 후 AOF 파일 크기의 비율입니다.
로그를 다시 작성할 때 새 데이터가 기록되면 어떻게 되나요? 재작성 프로세스는 "하나의 사본, 두 개의 로그"로 요약될 수 있습니다. 하위 프로세스에서 분기할 때와 다시 쓸 때 새 데이터가 기록되면 메인 스레드는 두 개의 로그 메모리 버퍼에 명령을 기록합니다. AOF 쓰기 저장 정책이 항상으로 구성된 경우 명령은 이전 로그 파일에 직접 다시 기록되고 명령 복사본은 AOF 다시 쓰기 버퍼에 저장됩니다. 이러한 작업은 새 로그 파일에 영향을 미치지 않습니다. (이전 로그 파일: 메인 스레드에서 사용하는 로그 파일, 새 로그 파일: bgrewriteaof 프로세스에서 사용하는 로그 파일)
bgrewriteaof 하위 프로세스가 로그 파일 다시 쓰기 작업을 완료한 후 메인 스레드에서 스레드가 다시 쓰기 작업을 완료하면 기본 스레드는 AOF 다시 쓰기 버퍼의 명령을 새 로그 파일 뒤에 추가합니다. 이때 높은 동시성 조건에서는 AOF 재작성 버퍼 축적이 매우 커질 수 있으며 이로 인해 차단이 발생할 수 있습니다. Redis는 나중에 Linux 파이프라인 기술을 사용하여 AOF 재작성 중에 동시 재생을 허용하므로 AOF 재작성이 완료된 후에는 A만 가능합니다. 소량의 남은 데이터를 재생해야 합니다. 마지막으로 파일 이름을 수정하여 파일 전환의 원자성이 보장됩니다.메인 스레드는 aof 로그를 다시 작성하기 위해 하위 프로세스를 분기합니다.
하위 프로세스가 로그를 다시 작성한 후, 메인 스레드는 aof 로그 버퍼를 추가합니다로그 파일 교체🎜 🎜🎜🎜알림🎜 🎜🎜🎜여기서 프로세스와 스레드의 개념은 약간 혼란스럽습니다. 백그라운드 bgreweiteaof 프로세스에는 단 하나의 스레드만 작동하고 메인 스레드는 역시 단일 스레드인 Redis 운영 프로세스이기 때문입니다. 여기서 표현하고 싶은 것은 Redis 메인 프로세스가 백그라운드 프로세스를 분기한 후 백그라운드 프로세스의 작업이 메인 프로세스와 연결되지 않으며 메인 스레드를 차단하지 않는다는 것입니다🎜
메인 스레드는 어떻게 하위 프로세스를 분기하고 메모리 데이터를 복사합니까?
포크는 운영 체제에서 제공하는 쓰기 시 복사 메커니즘을 사용하여 대량의 메모리 데이터를 한 번에 복사하고 하위 프로세스를 차단하는 것을 방지합니다. 자식 프로세스를 포크할 때 자식 프로세스는 부모 프로세스의 페이지 테이블, 즉 가상과 실제 매핑 관계(가상 메모리와 물리적 메모리 간의 매핑 인덱스 테이블)를 복사하지만 물리적 메모리는 복사하지 않습니다. 이 복사는 많은 CPU 리소스를 소비하며 복사가 완료되기 전에 기본 스레드가 차단됩니다. 차단 시간은 메모리의 데이터 양에 따라 달라집니다. 복사가 완료된 후 상위 프로세스와 하위 프로세스는 동일한 메모리 주소 공간을 사용합니다.
하지만 메인 프로세스에서는 데이터를 쓸 수 있고 이때 물리적 메모리에 있는 데이터가 복사됩니다. 아래와 같이(프로세스 1은 메인 프로세스로 간주되고 프로세스 2는 하위 프로세스로 간주됩니다):
메인 프로세스에 데이터가 기록되어 있고 이 데이터가 우연히 페이지 c에 있으면 운영 체제는 이 페이지의 복사본(페이지 c의 복사본), 즉 현재 페이지의 물리적 데이터를 복사하여 기본 프로세스에 매핑하는 반면 하위 프로세스는 여전히 원본 페이지 c를 사용합니다.
로그를 다시 작성하는 전체 과정에서 메인 스레드는 어디에서 차단되나요?
AOF 다시 쓰기가 원본 AOF 로그를 재사용하지 않는 이유는 무엇입니까?
Redis 4.0에서는 AOF 로그와 메모리 스냅샷을 혼합하여 사용하는 방식을 제안합니다. 간단히 말해서, 메모리 스냅샷은 특정 빈도로 실행되며, 두 스냅샷 사이에 AOF 로그를 사용하여 이 기간 동안의 모든 명령 작업을 기록합니다.
이렇게 하면 스냅샷을 매우 자주 실행할 필요가 없으므로 메인 스레드에 자주 분기되는 영향을 피할 수 있습니다. 또한 AOF 로그는 두 스냅샷 사이의 작업만 기록하므로 모든 작업을 기록할 필요가 없습니다. 따라서 파일이 너무 크지 않고 재작성 오버헤드를 피할 수 있습니다.
아래 그림과 같이 T1과 T2의 수정사항은 AOF 로그에 기록됩니다. 두 번째로 전체 스냅샷을 찍을 때 이때의 수정사항이 AOF 로그에 기록되기 때문에 AOF 로그는 지워질 수 있습니다. 스냅샷은 복구 중에 삭제되며 더 이상 로그가 없습니다.
이 방법은 RDB 파일의 빠른 복구 이점을 누릴 수 있을 뿐만 아니라 AOF 전용 녹음 작업 명령의 간단한 이점도 누릴 수 있으며 실제 환경에서 널리 사용됩니다.
이제 데이터 백업 및 지속성이 완료되었으므로 이러한 영구 파일에서 데이터를 어떻게 복구합니까? 서버에 RDB 파일과 AOF 파일이 모두 있는 경우 어떤 파일을 로드해야 합니까?
사실 이러한 파일에서 데이터를 복구하려면 Redis를 다시 시작하기만 하면 됩니다. 우리는 여전히 다이어그램을 통해 이 프로세스를 이해합니다.
추천 학습: Redis 비디오 튜토리얼
위 내용은 Redis 지속성 완전 마스터: RDB 및 AOF의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!