Beamer의 핵심 작동 방식은 데이터베이스 복제 시스템을 처음부터 구축하는 과정을 통해 상세히 설명됩니다. 기본적인 복제 시스템은 프라이머리 데이터베이스의 변경 사항을 캡처하여 복제본으로 전송하고, 이를 복제본에 적용하는 세 가지 단계를 포함합니다. Beamer는 이 과정을 다음과 같이 구현합니다.
1. 변경 사항 캡처 (Capture Changes)
- 트랜잭션 및 페이지 단위: Beamer는 관계형 데이터베이스의 트랜잭션 단위 변경을 캡처하며, SQLite의 4KB 고정 크기 페이지 단위 저장 방식을 활용합니다.
- WAL(Write-Ahead Log) 모드: SQLite의 WAL 모드는 쓰기 작업을 WAL 파일에 추가하고 읽기 시 WAL에서 최신 페이지를 조회하여 동시성을 확보합니다. WAL 파일은 트랜잭션별 변경 페이지 스트림을 제공하여 복제 로그로 이상적입니다.
- VFS(Virtual File System) Shim: SQLite의 플러그인 가능한 VFS 레이어에 사용자 정의 VFS shim을 구현하여 페이저(Pager) 레이어의 트랜잭션 커밋 이벤트를 가로챕니다. 이를 통해 각 트랜잭션 커밋 시 WAL 파일에서 변경 페이지들을 추출합니다.
2. 변경 사항 전송 (Transmit Changes)
- 캡처된 변경 페이지 데이터는 표준 HTTP를 통해 프라이머리에서 복제본으로 전송됩니다.
3. 변경 사항 적용 (Apply Changes)
- SQLite DB Page 가상 테이블: 복제본에서는
sqlite_dbpage가상 테이블을 활용합니다. 이 테이블은 페이저의 기능을 노출하여 페이지 번호와 4KB 데이터 청크를 삽입함으로써, 페이저가 이를 데이터베이스에 직접 안전하게 기록하도록 합니다. 이는 트랜잭션 및 동시성 안전성을 보장합니다.
Beamer의 Rails/Kamal 통합 및 활용
- Rails Gem 및 Kamal Docker 이미지: Rails 애플리케이션은 Beamer Gem으로 VFS shim을 활성화하며, Kamal 배포 환경에서는 Beamer 프로세스를 Docker 이미지로 실행하여 노드 간 통신 및 명령 처리를 담당합니다.
beamer switch명령:beamer switch명령으로 프라이머리 앱 서버를 지정합니다. 프라이머리는 쓰기 허용 및 변경 캡처를 수행하며, 다른 노드는 읽기 전용 복제본으로 동작합니다. 이는 장애 조치 및 프라이머리 이동을 유연하게 지원합니다.- Kamal Proxy 로드 밸런싱: Kamal Proxy는 HTTP 메서드(GET은 읽기, POST/PUT 등은 쓰기)를 기반으로 트래픽을 분산하여 읽기 요청은 복제본으로, 쓰기 요청은 프라이머리로 라우팅합니다.
- 지리적 분산 배포: 이 기능을 통해 메인 배포 지역에 프라이머리를, 다른 지역에 읽기 복제본을 배치하여 고객의 읽기 지연 시간을 단축할 수 있습니다. 고객을 여러 쓰기 가능한 데이터베이스로 분할하여 지리적으로 분산함으로써 읽기/쓰기 모두의 지연 시간을 최적화하는 것도 가능합니다.