Notion이 Postgres 샤딩하면서 배운 것들
(notion.so)- 올해초 5분간 노션을 다운시키고 몇달간 진행해온 PostgreSQL 샤딩을 진행
ㅤ→ 엄청 빨라 졌다고 즉각적으로 반응이 나오기 시작
- 샤딩하기로 언제 결정 했나
ㅤ→ 5년간 몇만배 성장하면서, 잘 사용하던 Postgres Monolith가 용량을 초과하기 시작
ㅤ→ VACUUM이 지속적으로 중단되기 시작했고, 곧 TXID wraparound 가 발생할 것으로 예상되어 샤딩 작업 시작
- 샤딩 스킴 설계하기
ㅤ→ 어플리케이션 레벨 샤딩
ㅤㅤ⇨ 어떤 데이터를 샤딩할 것인가
ㅤㅤ⇨ 어떤 키로 파티셔닝 해서 데이터를 분할할것인가
ㅤㅤ⇨ 얼마나 많은 샤드를 만들고, 어떻게 구성해야 하나
ㅤ→ 결정 #1
ㅤㅤ⇨ 노션은 block 단위로 데이터 모델이 구성됨
ㅤㅤ⇨ block 테이블에서 연결되는 모든 테이블을 샤딩하기로 함 (Space, Discussion, Comment 등)
ㅤ→ 결정 #2
ㅤㅤ⇨ block 은 workspace ID로 파티셔닝
ㅤㅤ⇨ 각 workspace는 UUID가 부여되므로 이걸 이용
ㅤ→ 결정 #3
ㅤㅤ⇨ 480개의 논리적 샤드 와 32개의 물리적 DB로 구성
ㅤㅤㅤㅤ2의 제곱수인 512가 아닌 480을 선택한 이유는, 더 유연하게 나누어 지는 숫자이기 때문
- 샤드로 이관하기
ㅤ→ 1. Old & New DB에 이중으로 쓰기 (Audit Log와 함께)
ㅤ→ 2. 이중 쓰기 시작후 올드DB의 데이터를 새 DB로 Backfill 시작
ㅤ→ 3. 새 DB의 데이터 검증
ㅤ→ 4. 새 DB로 변경 (Incremental로 진행)
- 어렵게 배운 교훈들
ㅤ→ 더 일찍 샤딩 하세요 : 기존 DB부담이 커질때까지 기다렸기 때문에, 마이그레이션 자체도 부담을 주는게 되어서 천천히 할 수 밖에 없었음
ㅤ→ Zero 다운타임 이관을 목표로 하세요 : 이중 쓰기의 처리량이 최종 전환시에 핵심 병목이었음.
ㅤ→ 별도 파티션 키 대신, 복합 PK를 이용하세요 : 기존 DB의 PK인 id와 파티션 키인 space_id 를 묶어 버리면 앱 내에서 space_id 들을 패스할 필요를 없앨수 있었을 것
Postgres 의 TXID 얘기는 항상 나오는 주제중에 하나 입니다
- PostgreSQL의 결함들 https://news.hada.io/topic?id=1829
- 5년간 PostgreSQL 스케일링 하면서 배운 것 https://news.hada.io/topic?id=4101