- rqlite는 Go로 작성된 경량의 오픈 소스 분산 관계형 데이터베이스
- Raft 합의 프로토콜을 기반으로 구축되었으며 SQLite를 스토리지 엔진으로 사용함
- 9.0 개발이 시작되었으며 디스크 사용량을 약 50% 줄이는 것을 목표로 함
- 이 목표는 rqlite의 디스크 소비 주요 원인을 제거하는 하는 고수준 설계 개편을 통해 달성될 것
현재 디스크 사용량을 주로 차지하는 것은 무엇인가?
- Raft 로그:
- 시스템에 대한 변경 사항의 로그
- 이 로그는 Raft 합의 시스템의 핵심
- 작업 SQLite 데이터베이스:
- rqlite가 읽기와 쓰기를 제공하는 데 사용하는 라이브 데이터베이스
- SQLite 문이 Raft 로그에 성공적으로 커밋되면 해당 문은 작업 SQLite 데이터베이스에 적용됨
- 작업 SQLite 데이터베이스의 스냅샷:
- Raft 로그가 무제한 증가하는 것을 방지하기 위해 rqlite 내의 Raft 하위 시스템은 주기적으로 작업 SQLite 데이터베이스의 시점 사본을 생성하고 저장함
- 이 사본을 스냅샷이라고 함
- 스냅샷이 생성되면 rqlite는 Raft 로그를 잘라낼 수 있음
- 이 스냅샷된 사본은 노드가 다시 시작할 때 rqlite가 노드를 복원하는 데 사용되거나 다른 노드가 기존 rqlite 클러스터의 상태를 "따라잡아야" 할 때 해당 노드로 전송됨
- 스냅샷 생성과 로그 잘라내기는 Raft 기반 시스템의 핵심 개념임
rqlite 9.0을 위한 고수준 설계
- 디스크 사용량을 줄이기 위한 주요 전략은 Raft 시스템에서 작업 SQLite 데이터베이스의 스냅샷된 사본을 저장할 필요성을 제거하는 것임
- Raft 로그는 스냅샷 생성으로 인해 주기적으로 잘려지고 일정 시점 이후에는 증가를 멈추지만, 작업 SQLite 데이터베이스는 더 많은 데이터가 기록됨에 따라 계속 증가함
- 그리고 SQLite 데이터베이스의 스냅샷 사본은 작업 SQLite 데이터베이스와 거의 같은 크기이므로 크기도 증가함
- 따라서 스냅샷 사본을 제거할 수 있다면 rqlite는 50% 적은 디스크를 사용할 것임
- 그러나 rqlite 노드는 특정 시점에 스냅샷된 사본이 필요함. 이는 피할 수 없음.
- 그렇다면 어떻게 사본을 건너뛰면서도 스냅샷 생성 및 복원의 필요성을 충족시킬 수 있을까?
- 스냅샷 과정에서 추가 사본을 저장하지 않고 피할 수 있는 방법을 이해하려면 rqlite가 기본 SQLite 데이터베이스를 Write-Ahead Log(WAL) 모드로 실행한다는 것을 아는 것이 중요함
- 제안된 9.0 설계에서 작업 SQLite 데이터베이스 파일(관련 WAL 파일 제외)과 Raft 시스템의 스냅샷된 사본은 논리적으로 동일함
- 이 사실을 활용하여 Raft 시스템에 별도의 스냅샷된 사본을 저장할 필요성을 제거할 수 있음
새로운 스냅샷 생성 접근 방식
- 스냅샷 생성 및 WAL 체크포인팅:
- 스냅샷 생성 시점에 rqlite는 작업 SQLite 데이터베이스의 Write-Ahead Log(WAL)를 체크포인트함
- 이후의 모든 쓰기는 새로운 WAL 파일로 전달되어 주 SQLite 파일은 스냅샷이 생성된 시점부터 변경되지 않은 상태로 유지됨
- 결과적으로 다음 스냅샷이 발생할 때까지 주 SQLite 파일은 Raft 스냅샷 저장소에 필요한 시점 상태를 나타냄
- 이 접근 방식을 통해 일반적인 읽기 및 쓰기 작업에는 결합된 SQLite 파일과 WAL 파일을 사용하고, 변경되지 않은 주 SQLite 파일은 Raft 스냅샷 저장소의 데이터 세트 역할을 함
- 더 이상 추가 사본이 필요하지 않음!
- 스냅샷 저장소에 참조 쓰기:
- 전체 SQLite 파일을 복사하는 대신 rqlite는 체크섬과 같은 참조를 스냅샷 저장소에 씀
- 이 참조는 스냅샷 데이터가 필요할 때마다 주 SQLite 파일이 스냅샷 저장소에서 참조하는 것과 일치하는지 확인하는 데 사용할 수 있음
- (이 확인은 버그, 운영 실수 또는 디스크 손상으로부터 보호하지만 엄격히 필요하지는 않음)
- 스냅샷에서 복원:
- 앞서 언급했듯이 스냅샷 프로세스 이후의 모든 쓰기는 WAL 파일로 전달되므로 주 SQLite 파일은 노드 재시작 시 또는 스냅샷을 다른 노드로 전송할 때와 같이 스냅샷에서 복원 프로세스에 사용될 준비가 되어 있음
- 즉, 주 SQLite 파일(관련 WAL 파일 무시)은 rqlite가 실제로 중복 사본을 만들었다면 Raft 스냅샷 저장소에 기록되었을 것과 논리적으로 동일하게 유지됨
- 이 새로운 설계를 "참조 스냅샷" 이라고 부름
보너스 개선 사항
- 참조 스냅샷은 몇 가지 다른 중요한 개선 사항도 가져올 것임
- 더 빠른 스냅샷 생성: Raft 스냅샷 저장소에 최소한의 데이터를 쓰므로 스냅샷 프로세스가 훨씬 더 빨라질 것임
- SQLite WAL 체크포인트 시간(일반적으로 매우 짧음)과 체크섬 계산 시간으로 구성될 것임
- 스냅샷을 생성할 때마다 대량의 SQLite 데이터를 스냅샷 저장소에 복사할 필요가 없음
- 스냅샷 프로세스 동안 rqlite에 대한 쓰기가 차단된다는 것을 알면 더 빠른 스냅샷의 장점이 분명해짐
- 더 빠른 재시작: 여러 기가바이트의 SQLite 데이터가 있는 노드도 훨씬 더 빠르게 재시작됨
- 현재 재시작 시 rqlite는 Raft 스냅샷 저장소의 사본에서 작업 SQLite 데이터베이스 파일을 복원해야 함
- 그러나 이 새로운 설계에서는 시작 시 작업 SQLite 데이터베이스 파일이 이미 올바른 위치에 있을 것임
- 최대한 rqlite는 스냅샷 저장소의 체크섬을 작업 SQLite 데이터베이스의 체크섬과 비교만 하면 됨
- 멀티 GB 시스템은 몇 초 내에 재시작되어야 함
다음 단계
- rqlite 9.0으로의 이동은 rqlite의 효율성을 최적화하는 데 있어 중요한 발걸음이 될 것임
- 참조 스냅샷을 구현함으로써 디스크 사용량을 크게 줄이고 스냅샷 생성 속도를 높이며 노드 재시작 시간을 개선할 것으로 기대함
- SQLite WAL 관리, 이전 릴리스에서의 원활한 업그레이드, 체크섬 선택 등 올바르게 처리해야 할 세부 사항이 많음
- 따라서 이 주요 릴리스를 향해 진행함에 따라 추가 업데이트를 계속 확인하기 바람