https://www.notion.so/blog/sharding-postgres-at-notion - 올해초 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 들을 패스할 필요를 없앨수 있었을 것 |