- Bluesky atproto의 PDS 리팩터링 PR #1705는 PDS가 단일 테넌트 SQLite 데이터스토어를 사용하도록 바꾸고, 사용자별 repo와 비공개 계정 상태를 각자의 SQLite 파일에 저장하도록 변경함
- 사용자 DB는
/${dbDirectory}/${sha256Hex(did).slice(0,2)}/${did}경로 구조로 저장되며, 각 repo의 서명 키는 해당 SQLite 파일 옆에 함께 보관됨 - 기존 사용자 데이터 접근 추상화는 ActorStore로 대체되며, SQLite가 동시 트랜잭션을 지원하지 않기 때문에 쓰기 작업은 명시적으로 store와 트랜잭션을 맺어야 함
- 열린 DB 파일 핸들과 서명 키는 LRUCache로 관리되며, 최대 30k개의 열린 파일 핸들과 30k개의 키를 메모리에 유지하고 캐시에서 DB가 밀려나면 파일 핸들을 닫음
- 서비스 상태 관리를 위해 별도 SQLite DB 3개를 도입하고 WAL 모드로 실행해 동시 읽기와 스트리밍 복제를 가능하게 하며, PDS 배포판에는 Litestream 또는 유사 도구를 포함할 계획임
PR의 핵심 변경
- PR #1705는 PDS를 단일 테넌트 SQLite 데이터스토어 기반으로 리팩터링함
- 각 사용자는 자기 전용 SQLite 파일을 가지며, 이 파일에는 해당 사용자의 repo와 비공개 계정 상태가 저장됨
- 사용자 DB는 DID 해시를 이용한 계층형 경로에 저장됨
- 경로 형식:
/${dbDirectory}/${sha256Hex(did).slice(0,2)}/${did}
- 경로 형식:
- 각 repo의 repo signing key는 SQLite 파일과 같은 위치에 저장됨
ActorStore와 트랜잭션 모델
- 사용자 데이터 접근 추상화가 기존 “services”에서 ActorStore로 바뀜
- ActorStore의 주요 차이는 읽기와 쓰기를 위한 클래스가 분리되어 있다는 점임
- SQLite는 동시 트랜잭션을 지원하지 않기 때문에, 쓰기 작업을 하려면 명확하게 store와 트랜잭션을 맺어야 함
- 커밋 로그에는 reader와 transactor 재작업, actor store 트랜잭션 race 처리, store 인터페이스 정리 등이 포함됨
캐시와 파일 핸들 관리
- 서명 키와 데이터베이스를 위한 LRUCache가 유지됨
- 설정된 한도는 다음과 같음
- 열린 파일 핸들 최대 30k
- 메모리에 유지되는 키 최대 30k
- 데이터베이스가 캐시에서 밀려나면 파일 핸들을 닫도록 처리함
- 관련 커밋에는
actor store in lru cache,fix open handles가 포함됨
서비스 상태용 SQLite DB 3개
- 사용자별 DB 외에 서비스 상태 관리를 위한 별도 SQLite 데이터베이스 3개가 도입됨
- service DB: 계정 정보, 초대 코드, refresh token 등을 관리
- did cache DB: DID resolution 캐싱을 위한 단일 테이블만 포함
- sequencer DB: 한 서비스의 모든 repo 업데이트 순서를 관리하는 단일 테이블만 포함
- 각 SQLite 파일은 WAL mode로 실행됨
- WAL mode의 목적은 동시 읽기와 스트리밍 복제를 가능하게 하는 것임
- PDS 배포판에는 Litestream 또는 유사 도구를 포함할 계획이 있음
리뷰와 병합 상태
- 이 PR은 총 143 commits로 구성되어
pds-sqlite-refactor브랜치에서pds-v2브랜치로 병합됨 - 병합일은 2023년 11월 1일이며, 병합 커밋은
8449ceb임 - 리뷰어 devinivy는 여러 노트와 코멘트를 남긴 뒤 변경을 승인함
- devinivy는 리팩터링에 대해 “많은 훌륭한 단순화”가 있고 전체적으로 정돈된 느낌이라고 평가함
- 병합 후
pds-sqlite-refactor브랜치는 삭제됨
이후 질문
- 2025년 2월 28일, npetrangelo가 이 PR의 변경 규모를 살펴보며 이전 Postgres 아키텍처와 이 PR로 도입된 SQLite 아키텍처 사이의 트레이드오프 요약을 요청함
- 제공된 본문에는 해당 질문에 대한 Bluesky 측 답변이 포함되어 있지 않음