1. 성능 최적화 및 동시성 문제 해결
SQLite는 기본적으로 단일 쓰기(linear writes)만 허용하는 아키텍처적 특성 때문에 동시성 환경에서 SQLITE_BUSY
오류와 높은 지연 시간을 유발할 수 있습니다. 본 워크숍은 이러한 문제를 해결하기 위한 두 가지 핵심 방안을 제시합니다.
-
즉시 트랜잭션(Immediate Transaction) 도입: Rails 애플리케이션에서
default_transaction_mode: immediate
설정을 통해 트랜잭션 시작 시점에 쓰기 잠금을 즉시 획득하도록 변경합니다. 이는 트랜잭션 내에서 쓰기 작업이 발생할 때까지 잠금 획득을 지연하는 기본 동작(deferred transaction
)과 달리, 잠금 대기열을 생성하여 오류 발생을 방지하고 작업이 순차적으로 처리되도록 합니다. Rails 8에서는 이 설정이 기본으로 적용될 예정입니다. -
GVL(Global VM Lock) 해제 및 Busy Timeout 최적화: SQLite 작업 대기 중 Ruby의 GVL이 해제되지 않아 다른 Puma 워커의 Ruby 코드 실행이 지연되는 문제를 해결합니다. Ruby의
sleep
함수를 활용한 커스텀 Busy Timeout 핸들러를 구현하여, SQLite가 잠금을 기다리는 동안 GVL을 해제함으로써 다른 스레드가 Ruby 코드를 실행할 수 있도록 합니다. 이는 꼬리 지연 시간(long-tail latency)을 획기적으로 개선하며, 기존의 지수 백오프(exponential back-off) 방식 대신 일관된 대기 시간(consistent sleep)을 적용하여 지속적인 쓰기 부하 환경에서도 예측 가능한 성능을 제공합니다. Rails 7.x 사용자들을 위해active_record_enhanced_sqlite3_adapter
젬을 통해 이러한 개선 사항을 쉽게 적용할 수 있는 방법을 소개합니다.
2. 데이터 복원력 확보: Litestream 활용
SQLite 데이터베이스가 단일 파일로 존재하며 서버와 함께 소실될 위험이 있음을 강조하며, Litestream
젬을 통한 데이터 복원력 확보의 중요성을 역설합니다. Litestream
은 SQLite 데이터베이스의 변경 사항을 S3와 같은 버킷 스토리지로 실시간 스트리밍하여 시점 복구(point-in-time backups)를 가능하게 합니다. 설치 및 설정(환경 변수, Rails Credentials 연동, Puma 플러그인 활용) 과정을 상세히 설명하며, 백업 복원 방법과 함께 Litestream.verify!
메서드 및 주기적인 백그라운드 작업을 통한 백업 유효성 검증의 중요성을 강조합니다. 이는 실제 재해 발생 시 데이터 복구 가능성을 보장하는 핵심적인 절차입니다.
3. Rails 기능 확장 및 SQLite 아키텍처 활용
Rails의 다양한 기능을 SQLite 환경에서 효과적으로 사용하는 방법을 제시합니다. 주요 내용은 다음과 같습니다.
-
다중 데이터베이스 전략: 각 영구 데이터 컴포넌트(주요 데이터, 백그라운드 작업, 캐시, 웹소켓, 오류 모니터링 등)에 별도의 SQLite 데이터베이스 파일을 사용하는 것을 권장합니다. 이는 각 컴포넌트 간의 쓰기 작업 병목 현상을 줄여 동시성을 확보하는 데 기여합니다. Rails 8에서는
Solid Queue
(백그라운드 작업) 및Solid Cache
(캐싱)가 SQLite를 기본 백엔드로 사용하며, 별도의 데이터베이스를 활용하도록 설정됩니다. -
Solid Queue 및 Solid Cache: Rails 8의 새로운 기본 백엔드인
Solid Queue
와Solid Cache
를 Rails 7.x에서 설정하는 방법을 설명합니다. 특히Solid Queue
의 주기적인 작업(recurring jobs) 기능을 활용하여 백업 유효성 검증 작업을 자동화하는 유용한 사례를 제시합니다. -
Solid Errors를 통한 오류 모니터링: Rails의 내장된 오류 구독 기능을 활용하여 애플리케이션 오류를 SQLite 데이터베이스에 기록하고, 간단한 Rails 엔진을 통해 웹 UI로 시각화하는
Solid Errors
의 개념을 소개합니다. 이는 외부 서비스에 의존하지 않고도 기본적인 오류 모니터링 시스템을 구축할 수 있는 비용 효율적인 방안입니다. -
SQLite의 독특한 아키텍처 활용: Git 브랜치 이름에 따라 개발 데이터베이스 파일을 분리하거나(ERB 활용), SQLite 컴파일 플래그를 미세 조정하여 성능을 최적화하고, 다양한 SQLite 확장(예: 벡터 검색)을 활용하는 등 SQLite의 유연성을 극대화하는 고급 활용 사례를 제시합니다. 이는 개발 및 운영 효율성을 높이고 애플리케이션의 기능을 확장하는 데 기여합니다.