diff --git a/redis/week06/taejun/Cluster.md b/redis/week06/taejun/Cluster.md new file mode 100644 index 0000000..bad73a0 --- /dev/null +++ b/redis/week06/taejun/Cluster.md @@ -0,0 +1,239 @@ +# Redis Cluster +- Redis3.0부터 지원한다. + - Cluster기능을 지원하는 Client를 사용해야 한다. +- 수평확장이다. + - 최대 1000개의 MasterNode를 가질 수 있다. +- Sharding, Replication, FailOver사용이 가능해진다. +- 하나의 Database(0)만 사용가능하다. + - StandAlone이나, Replication의 경우 16개 (0~15)가 기본적으로 사용가능하다. + - 데이터 관리의 단순화와 성능최적화 목적이다. +## Cluster 설정 +```shell +# redis.conf +cluster-enabled yes # Cluste Enable하여 ClusterMode로 실행한다. + +# cli +# [host:port]부분은 여러개가 들어 갈 수 있으며, 공백으로 구분된다. +# 처읍부터 MasterNode로 구성되고 나머지가 ReplciaNode로 구성된다. +# 갯수가 맞지 않는다면 충분한 수의 Node가 제공되지 않았다는 오류가발생한다. +redis-cli -cluster create [ip:port] --cluster-replicas 1 # MasterNode에 ReplicaNode를 1개씩 할당한다. +``` + +## Cluster 상태보기 +- Client Library(Lettuce...)는 이 Command를 통해서 Topology를 업데이트 한다. + - Topology 업데이트에 따라서, Connection Pool도 업데이트한다. +```shell +# 순서없이 랜덤으로 Cluster내의 Node들을 출력한다. +redis-cli cluster nodes + + ~ +``` + +| 필드명 | 설명 | +|---------------|----------------------------------------------------------------------| +| id | Node가 생성될 떄 자동으로 만들어지는 RandomString ClusterId이다. (Immutable) | +| ip:port@cport | Node의 IP 주소 및 Port, ClusterPort (RedisPort + 10000으로 자동설정된다) | +| flags | Node의 상태를 나타내는 Flag | +| master | MasterNode 일 경우 '-'가, ReplicaNode일 경우 'MasterNode의 ID'가 표시된다. | +| pingsent | 마지막으로 PING 메시지를 보낸 시간, 보류중인게 있다면 0 | +| pong-recv | 마지막으로 PONG 메시지를 받은 시간 | +| config-epoch | 클러스터 구성 변경을 추적하는 Flag (더 높은 값을 가질수록 우선순위를 가지며, 구성변경이 발생할 때 값이 증가한다) | +| link-state | ClusterBus에서 아요되는 Link의 상태 (connected/disconnected) | +| slot | node가 담당하는 HashSlot 범위 | +- flag + - myself: cli를 통해서 접근 가능한 Node + - master: MasterNode + - slave: ReplicaNode + - fail?: PFAIL상태를 의미하며, 다른Node에 확인을 요청한 상태이다. + - fail: FAIL인 상태 (과반수 이상의 Node가 Fail임을 인정, PFAIL의 다음상태이다.) + - handshake: 새로운 Node를 인지하고, handshaking을 하는 단계이다. + - nofailvoer: ReplicaNode가 FailOver를 시도하지 않을 것임을 의미한다. + - noaddr: 해당 Node의 주소를 알 수 없음을 나타낸다. + - noflags: 상태없음 + + +## Sharding +- Sharding에 필요한 모든 기능은, Redis내부적으로 지원된다. +- 하나의 Key는 항상 하나의 MasterNode와 매핑된다. + - StandAlone에서는 모든 Key가 한 Node에 존재하지만, Cluster는 그렇지 않다. +- Cluster의 모든 Node는 해당 Key에 맞는 Node를 알고있다. (HashSlot) + - 자신이 담당할 데이터가 아니라면, 해당 Node에게 Redirect 시킨다. + - 내부적으로 HashSlotMap을 가지고 있고, Redirect를 반영하고 어떤 HashSLot이 어떤 Node에 있는지를 저장한다. + - ```shell + # 일반모드 + redis-cli + set user:1 true # Data Set + (error) MOVED 10778 192.168.0.22:6379 # HashSlot은 10778이며 해당 HashSlot이 있는 192.168.0.22:6379로 Redirect하라 + + # Cluster 모드 + rediss-cli -c + set user:1 true # Data Set + -> Redirected to slot [10778] located at 192.168.0.22:6379 + OK # Redirect 및 저장 완료 + ``` + - MOVED: 영구적인 Redirection (다음 쿼리는 Redirect Node에게 보내라 / HashSlotMap Update(O)) + - ASK: 임시적인 Redirection (Slot Migration 도중, 다음 쿼리도 자신이 받겠다. / HashSlotMap Update(X)) + +### Resharding +- MasterNode가 갖고있던 HashSlot을 다른 MasterNode로 이동시키는 것이다. +```shell +redis-cli --cluster reshard 192.168.112.4:6379 +>>> Performing Cluster Check (using node 192.168.112.4:6379) +M: 8b35f9fa50b0f827408499d2dfb557620e74a9d4 192.168.112.4:6379 + slots:[0-5460] (5461 slots) master +S: 8bb7928fe3816ebd3ac058e69e939f8c8daa9eb9 192.168.112.2:6379 + slots: (0 slots) slave + replicates 58c705bdd539946720ac648e1400563bdd59fcbe +M: 58c705bdd539946720ac648e1400563bdd59fcbe 192.168.112.3:6379 + slots:[5461-16383] (10923 slots) master + 1 additional replica(s) +[OK] All nodes agree about slots configuration. +>>> Check for open slots... +>>> Check slots coverage... +[OK] All 16384 slots covered. +How many slots do you want to move (from 1 to 16384)? 100 +What is the receiving node ID? 58c705bdd539946720ac648e1400563bdd59fcbe +Please enter all the source node IDs. + Type 'all' to use all the nodes as source nodes for the hash slots. + Type 'done' once you entered all the source nodes IDs. +Source node #1: 8b35f9fa50b0f827408499d2dfb557620e74a9d4 +Source node #2: all + +Ready to move 100 slots. + Source nodes: + M: 8b35f9fa50b0f827408499d2dfb557620e74a9d4 192.168.112.4:6379 + slots:[0-5460] (5461 slots) master + Destination node: + M: 58c705bdd539946720ac648e1400563bdd59fcbe 192.168.112.3:6379 + slots:[5461-16383] (10923 slots) master + 1 additional replica(s) +``` +- Cluster중 하나의 Node를 지정한다. + - 해당 Node는 Orchestrator가 된다. + - 해당 Node는 Cluster내부의 다른 Node들에 대한 정보를 가져온다. + - Master가 아닌, ReplicaNode를 지정하더라도 Resharding의 동작은 동일하게 수행된다. +- **몇개를 옮길 것인지, 어디에서 어디로 옮길 것인지를 중점으로 한다.** +- 자동으로 일어나는 것이 아닌, 수동으로 관리자가 수행해야 한다. + + +### HashSlot +- 모든 데이터는 HashSlot에 저장된다. + - HashSlot은 16384개이며, 0~16383으로 나뉘어 있다. (Memory갯수와 상관없는 고정 갯수) + - 각 MasterNode들은 HashSlot을 나눠갖는다. (ex -> master1: 0~5460, master2: 5461~10922, master3:10923~16383) + - ```shell + # Key를 CRC16으로 암호화하고, modular 연산을 수행한다. + # 각 MasterNode들은 HashSlot Range를 할당받는다. + HASH_SLOT = CRC16(key) % 16384 + ``` + - Hashslot은 MasterNode에 해당되며, ReplicaNode에는 해당되지 않는다. +- Rebalancing 과정에서, Hashslot이 다른 MasterNode로 이동 할 수 있다. + - Migration 도중에도 Relocation대상 데이터에 접근 가능하다. +- Gossip을 통해서 전파된다. + - 하트비트 패킷: PING/PONG을 보낼 때, 자기가 갖고있는 HashSlot을 포함해서 보낸다. + - 업데이트 메세지: config-epoch 값을 포함하여 업데이트 메세지를 보낸다. + +### Rebalancing +```shell +# redis-cli --cluster rebalance 192.168.112.4:6379 +>>> Performing Cluster Check (using node 192.168.112.4:6379) +[OK] All nodes agree about slots configuration. +>>> Check for open slots... +>>> Check slots coverage... +[OK] All 16384 slots covered. +>>> Rebalancing across 2 nodes. Total weight = 2.00 +Moving 2831 slots from 192.168.112.3:6379 to 192.168.112.4:6379 +``` +- Cluster에 있는 MasterNode사이에 HashSlot을 균등하게 재분배한다. +- 자동으로 일어나는 것이 아닌, 수동으로 관리자가 수행해야 한다. + + +### HashTag +- MGET, MSET과 같은 다중 Key Command는 ClusterMode에서 잘 동작하지 않는다. + - 각 Key가 여러개의 HashSlot (= 여러개의 MasterNode)에 분산되어 저장되어 있을 수 있기 때문이다. + - 해당 Node는 그 Key를 처리할 수 있는 다른 Node로 Redirect시키는데, Redirect 대상이 여러개이면 동작할 수 없다. + - 다중 Key의 경우, 해당 Key들이 모두 같은 HashSlot에 위치해야 한다. + - 같은 MasterNode에 위치하는 복수의 HashSlot들 이더라도, 복수 KeyCommand는 동작하지 않는다. + - 다른 HashSlot에 분산되어있으면 원자성 보장이 어렵기 떄문에 간략화하기 위함이다. +- 위와 같은 다중 Key Command의 제약을 극복하는 방법이다. + - ```shell + # {} 사이에 있는 값을 해시하여, HashSlot을 배정한다. + users:{123}:profile + users:{123}:accout + ``` + - Key중간을 포함한 어느위치에도 들어갈 수 있다. +- **HashTag기능의 무분별한 사용은 특정 Node의 데이터 쏠림을 야기할 수 있다.** + +### Cluster Resharding +- Cluster 실행중에 Node 추가/삭제 가 가능하다. +- MasterNode가 갖고있던 HashSlot을 다른 MasterNode로 이동시키는 것을 의미한다. + - 새로운 MasterNode의 추가 및 기존 MasterNode의 제거시에 발생한다. + - Enterprise버전은 Auto-Resharding, Relocation을 지원하지만 Community버전은 지원하지 않는다. +- HashSlot이동에 따른 상태를 가진다. + - MIGRATING: 해당 HashSlot에 대한 쿼리를 수행하지만, Key가 존재하는 경우에만 처리하고, 없다면 이동 대상 Node로 Redirect한다. + - IMPORTING: ASKING명령이 선행된 경우에만, 해당 HashSlot 쿼리를 수락하고 아니라면 해당 HashSlot소유자에게 Redirect한다. + +## High-Availability +- 최소 3대의 Master와 Replica를 갖게하는 것이 권장설정이다. +- Cluster에 속한 Node들은 서로를 모니터링한다. + - 모든 Node가 연결되어있는 **Full-Mesh 토폴리지** 형태이다. + - ClusterBus라는 독립적인 통신을 이용한다. + - 추가적인 TCP포트를 사용한다. + - 일반적인 포트에 10000을 더한다. (default 16379) + - cluster_bus_port를 통해서 설정 가능하다. + - Gossip Protocol(가십 프로토콜)을 사용하여 오버헤드가 적다. + - Cluster가 정상적인 상태에서는 많은 Message를 교환하지 않는다. + - Node의 추가 삭제와 같은 동적설정변경도 Gossip Prtocol을 통해서 전파된다. + - 어떤 Node가 HashSlotRange를 가지는지도 Gossip을 통해 전파된다. + +## FailOver +- Sentinel과 같은 기능을 제공한다. + - MasterNode 장애시, ReplicaNode를 Master로 승격시킨다. + - Sentinel은 별도의 Instance를 추가적으로 띄워야했으나 그럴 필요가 없다. +- ClusterBus를 통해서 모든 Instance가 FullMesh 통신하는 구조이며 문제가 생겼을 때는 자동으로 구조를 재조정한다. +- 두가지 종류가 있다. + - Auto Failover: ReplicaNode를 MasterNode로 승격시킨다. + - Replica Migration: 잉여 ReplicaNode를 다른 MasterNode에 연결시킨다. + +### Master 승격 +- 아래의 조건에 해당하면 Replica가 FailOver를 직접 시도한다. + 1. Master가 Fail상태이다. + 2. Master는 1개이상의 HashSlot을 가지고 있다. + 3. Master와 Replication이 끊어진지 오래다. +- 위 조건이 만족하면 FailOver를 수행한다. + 1. config-epoch값을 1 증가시킨다. + 2. Cluster내에 존재하는 모든 MasterNode에 FAILOVER_AUTH_REQUEST 패킷을 보내서 투표를 요청한다. + - FAILOVER_AUTH_ACK 패킷은 긍정적인 응답을 나타낸다. + - 현재 config-epoch보다 낮은 값으로 온 FAILOVER_AUTH_ACK는 무시한다. + 3. 과반수 이상의 ACK를 받게되면 MasterNode로 승격된다. + - 과반수 이상의 ACK가 오지 않는다면 FailOver는 중단된다. +- 지연시간을 갖는다. + - 고정지연 (500ms) + - 랜덤지연 (0~500ms) + - SlaveRank에 따른 지연 + - ```shell + # Master로 승격될 우선순위가 높은대로 먼저 시도된다. + DELAY = 500ms + 랜덤 지연시간(0~500ms) + SLAVE_RANK * 1000ms + ``` + +### FailOver 설정 +- ```shell + # yes(default): Slave가 없는 MasterNode중 하나라도 장애가 발생했다면 전체 Cluster가 실패한다. + # no : 장애가 난 MasterNode를 제외하고는 다른 MastesrNode들은 Cluster에서 동작한다. + cluster-require-full-coverage yes + + # Replica의 이동에 해당하는 설정이다. + # 특정 MasterNode에 Replica가 집중되어있따면 다른 MasterNode로 옮겨서 균등하게 부하를 분산한다. + # 밑의 Barrier를 초과하면 대상이된다. + cluster-allow-replica-migration yes + + # MasterNode가 가지고 있어야하는 최소 ReplicaNode의 개수 (default: 1) + cluster-migration-barrier 1 + ``` +### 관련 플래그 +- [1] PFAIL (Probable Fail) + - 특정Node 에서 NODE_TIMEOUT이 발생하는 경우에 세워지는 Flag이다. + - Master, Replica상관없이 PFAIL이 가능하다. +- [2] FAIL + - 실제 MasterNode가 장애가 발생했다고 인지하며 FailOver를 Trigger하는 Flag이다. + - 과반수 이상의 MasterNode가 PFAIL로 설정했다면 해당 Node는 FAIL로 변경된다. + - Flag가 설정되면 FailOver프로세스가 시작된다. diff --git a/redis/week06/taejun/RDB&AOF.md b/redis/week06/taejun/RDB&AOF.md new file mode 100644 index 0000000..5e77c84 --- /dev/null +++ b/redis/week06/taejun/RDB&AOF.md @@ -0,0 +1,196 @@ +# Redis 영속성 +- 둘 중 하나만 사용하는 것도 가능하다. +- Cache 용도로 사용하는경우, 두가지 다 사용하지 않을 수도 있다. +- RDB + AOF를 같이 사용할 수도 있다. + - RDB와 AOF가 모두 존재할 때, AOF파일의 복구 우선순위가 높다. (더 신뢰성이 높다고 판단한다.) +- Redis가 복구에 필요한 Data File을 읽어오는 시점은 시작 시점 밖에 없다. + - 즉, 두가지 복구옵션 모두 Redis Server 재시작 시점에만 가능하다. + +## [1] RDB (Redis DataBase) +- 일반적으로 dump.rdb라는 파일에 저장된다. + - binary형식이며, 사람이 읽을 수 있는 형태가 아니다. + +### 장점 +- 복구가 빠르다. +- 특정시점의 Snapshot으로, BackUp을 하기에 유리하다. + - Data의 Snapshot이다. (Command의 Snapshot 아님) +- Disk에 저장하기 때문에, 충분한 공간을 확보해야 한다. + - 별도의 분산스토리지(S3, ...)에 저장하는 것도 가능하다. +- 장애 복구, 초기 데이터, Replica 수행에서 Snapshot 파일을 다시 사용하면 되기 때문에 복구가 빠르다. + +### 단점 +- RDB는 Snapshot을 찍는 주기를 가지기 떄문에, 유실이 발생할 수 있다. + - 다음 Snapshot을 준비하는 과정에서 장애가 발생하면, 데이터 유실이 발생 할 수 있다. + - 일반적으로 Snapshot은 5분단위로 생성된다. +- RDB의 수행은 자식 Process가 수행하며, fork()비용이 높다. + - Snapshot이 클 경우, 병목 현상이 발생 할 수 있다. + +## RDB 설정 +- redis.conf 파일에 저장되어있다. +- 기본 설정은 다음과 같다. + - ```shell + # 여기에 있는 save는 Command의 Save (동기 방식의 수동 RDB)와 다르다. + save 900 1 # 900초(15분) 동안 1개 이상의 키가 변경되었을 경우 + save 300 10 # 300초(5분) 동안 10개 이상의 키가 변경되었을 경우 + save 60 10000 # 60초(1분) 동안 10,000개 이상의 키가 변경되었을 경우 + save "" # RDB옵션 비활성화 / CONFIG SET으로 지정 가능하다. + ``` + - rdbcompression (yes) + - RDB 파일을 저장하기 전에 데이터 압축을 사용 + - 기본적으로 LZF 압축 알고리즘을 사용 + - rdbchecksum (yes) + - RDB 파일 저장 시 체크섬을 사용하여 데이터 무결성을 검사 + - dbfilename (dump.rdb) + - RDB 파일의 이름 + - dir (./) + - RDB 파일과 AOF 파일이 저장될 디렉토리를 지정 + - 기본적으로 현재 디렉토리에 저장 + +## 수동 RDB Command + +### [1] SAVE +- 동기 방식이다. +```text +[1] 부모 Process가 임시 RDB파일에 DataSet을 Write 한다. +[2] 부모 Process의 Write가 끝나면, 이전 RDB파일을 대체한다. +``` + +### [2] BGSAVE +- 비동기 방식이다. +```text +[1] Redis 부모 Process가 fork()를 통해서 자식 Process를 생성한다. +[2] 자식 Process는 임시 RDB파일에 DataSet을 Write한다. +[3] 자식 Process의 Write가 끝나면, 이전 RDB파일을 대체한다. +``` +- SAVE는 동기방식이다. + - 다른 Client의 요청을 차단한다. + +### Copy-On-Write +- Linux(Unix)에서, 부모가 자식 Process를 fork()할 경우, 같은 메모리 공간을 공유한다. +- 이 때, 부모 Process의 데이터 수정 (CUD)가 발생하면, 메모리의 공유가 불가능해진다. +- 이 때, 자식 Process를 위한 Memory Page를 복사해야하기 떄문에, 부하가 발생한다. + +## [2] AOF +- 실행된 Write Command가 Immutable하게 append된 형태이다. + - RESP형태로 저장된다. + - **데이터가 변경된 Command만 저장된다.** + - BRPOP과 같은 Blocking Command는 RPOP과 같은 NonBlocking Command로 변경된다 + - AOF파일에 Blocking을 굳이 명시할 필요가 없기 때문이다. +- 시간이 지남에 따라 AOF 파일의 크기가 커질 수 있다. + - 주기적으로 파일 재작성 (bgrewriteaof)프로세스를 수행한다. +- 우선적으로 AOF Buffer에 명령어들이 기록된다. + - 옵션에 따라서 fsync를 수행하며 Buffer를 비운다. + +### 설정 +```shell +appendonly yes # AOF 설정 Enable +appendfilename "appendonly.aof" # appendonly.aof (default) +appenddirname "appendonlydir" # aof파일 저장 디렉토리 +appendfsync everysync # 매초 저장 +aof-use-rdb-preamble yes # AOF Rewrite 시, AOF파일의 포맷을 rdb와 같은 포맷으로 가져감 +``` +- appendonly: AOF 설정 Enable 여부 +- no-appendfsync-on-rewrite: Rewrite설정 여부 +- aof-load-truncated: AOF파일 손상 시 로드 여부 + - yes: 손상된 부분을 무시하고 다른 부분 로드 + - no: 손상된 부분이 발견되면 로드를 중지 +- appendfsync: AOF에 기록하는 시점을 나타낸다. + - always: 명령 실행마다 수행 + - everysync: 1초마다 AOF에 기록한다. + - no: AOF가 기록하는 시점을 OS가 결정한다. +- aof-use-rdb-preamble: AOF Rewrite시의 파일 포맷 + - yes: RDB포맷도 함꼐 사용된다. + - RDB 포맷 + - AOF 포맷 + - no: 순수 AOF파일 포맷 (Rewrite는 그대로 실행, 포맷만 AOF 형식) + +### 장점 +- 원하는 시점으로의 복구가 가능하다. + - 예를들어서, FLUSHALL을 통해서 데이터를 다 날렸더라도, 그 이전까지의 AOF를 사용할 경우 복구가 가능하다. +- fsync를 사용하기 떄문에 내구성이 매우 좋다. + - Buffer에 있는 데이터를 디스크에 실제로 Write하게 강제한다. + - 실제 Disk I/O작업이기 때문에 장애에도 비교적 안전 할 수 있다. +- 하나의 파일이 커질 때를 대비하여 Rewrite를 제공한다. + +### 단점 +- Write가 많은 경우 많은 Memory를 사용하게된다. +- 동일한 양의 정보여도 RDB파일보다 크기가 커진다. + + +### Rewrite (압축) +- AOF를 더 안정적으로 사용하는 기능이다. + - 특정 조건에 따라 재구성하게 할 수 있다. +- 커져가는 파일을 분할하고 압축한다. + - **압축은 기존에 존재하는 AOF파일을 사용하지 않는다.** + - 현재 메모리를 읽어와서 새로운 데이터로 저장하는 과정이 발생한다. +- RDB와 마찬가지로 자식 Process를 fork()하고 자식 Process가 AOF파일을 Rewrite한다. +- Rewrite과정은 모두 Sequential I/O로 구성된다. +- 똑같이 fork()와 COW(Copy-On-Write)의 영향을 받는다. + +### Rewrite 후 AOF 파일의 구조 +```text +[Redis 버전 7.0 이전] + ++-----------------------------------+ +| RDB Preamble (Optional) | ++-----------------------------------+ +| AOF Logs (RESP Commands) | ++-----------------------------------+ +- 'RDB Preamble'은 'aof-use-rdb-preamble' 설정이 'yes'로 활성화되었을 때만 포함됩니다. +- 'AOF Logs'는 모든 데이터 변경 명령어를 순차적으로 기록합니다. + +[Redis 버전 7.0 이후] + +Manifest File + | + |----> AOF File(s) + | + + | + |----> RDB File + +- 'Manifest File': AOF 및 RDB 파일의 상태와 순서를 기술합니다. + - 어떤 AOF 파일 시퀀스와 RDB 파일 시퀀스를 결합해야 하는지 명시합니다. +- 'AOF File(s)': 데이터 변경 명령어를 기록한 하나 이상의 AOF 파일을 포함합니다. +- 'RDB File': 특정 시점에서의 데이터베이스 전체 스냅샷을 저장하는 RDB 파일을 포함합니다. +``` +### 수동 Rewrite +- BGREWRITEOF를 통해서 실행 가능하다. + - MainThread를 차단하지 않고 백그라운드에서 수행한다. +- **REWRITEOF는 존재하지 않는다.** + + +### Rewrite 수행과정 +```text +[Redis 버전 7.0 이전] + +[1] fork()를 통해서 자식 Process를 생성한다. +[2] 자식 Process는 Memory의 데이터를 읽어와서 임시 RDB파일을 생성 후 저장한다. +[3] 부모 Process는 1~2의 작업이 진행되는 동안 기존 AOF파일과 InMemoryBuffer에 데이터를 저장한다. +[4] 임시 RDB파일의 마지막에 InMemoryBuffer의 내용을 append한다. +[5] 임시 RDB파일을 기존 AOF파일에 덮어씌운다. + + +[Redis 버전 7.0 이후] +[1] fork()를 통해서 자식 Process를 생성한다. +[2] 백그라운드에서 자식 Process를 만드는 동안, 변경분은 새로운 AOF파일에 저장된다. +[3] 임시 Manifeset파일을 생성하고, 내용을 저장하고 기존 Manifest파일을 수정한다. +[4] 임시 Mainfest파일을 삭제하고, 이전버전의 AOF & RDB파일을 삭제한다. +``` +### Rewrite 자동 설정 +```shell +auto-aof-rewrite-percentage 100 # 이전 AOF파일과 비교해서 두배가 되었을 떄 Rewrite를 수행한다. +auto-aof-rewrite-min-size 64mb # AOF파일의 크기가 64mb를 넘어가면 Rewrite를 수행한다. +``` +- INFO PERSISTENCE를 통해서 AOF파일의 현황을 알 수 있다. + + +### AOF가 잘려있다면? +- 파일 기록도중 충돌하거나, 볼륨이 가득차면 발생할 수 있다. +- AOF는 이러한 경우, 명령을 버리고 계속 동작한다. + +### AOF 파일이 손상되었다면? +- 파일 내부에, 유요하지 않은 byte sequence가 존재한다면 손상된 것으로 간주한다. +- AOF는 작업을 중단하고 복구과정을 갖는다. + 1. AOF 백업본을 만든다. + 2. redis-check-aof 도구를 사용하여 검사 후 수정한다. +- 자동복구과정이 적합하지 않다면, 수동 복구과정이 필요하다. \ No newline at end of file