NotionがPostgresをシャーディングして学んだこと
(notion.so)- 今年初めに5分間Notionをダウンさせつつ、数か月にわたって進めてきたPostgreSQLのシャーディングを実施
→ 劇的に速くなったという反応がすぐに出始めた
- いつシャーディングを決断したのか
→ 5年間で数万倍に成長する中で、うまく使っていたPostgresモノリスが容量の限界を超え始めた
→ VACUUMが継続的に中断されるようになり、まもなくTXID wraparoundが発生すると見込まれたため、シャーディング作業を開始
- シャーディングスキームの設計
→ アプリケーションレベルのシャーディング
⇨ どのデータをシャーディングするのか
⇨ どのキーでパーティショニングしてデータを分割するのか
⇨ いくつのシャードを作り、どう構成するか
→ 決定 #1
⇨ Notionは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の負荷が大きくなるまで待っていたため、マイグレーション自体も負荷を与えるものになり、ゆっくり進めるしかなかった
→ ゼロダウンタイム移行を目標にすべき : 二重書き込みのスループットが最終切り替え時の主要なボトルネックだった。
→ 別個のパーティションキーではなく、複合PKを使うべき : 既存DBのPKであるidとパーティションキーであるspace_idをまとめてしまえば、アプリ内でspace_idを渡す必要をなくせたはず
1件のコメント
Postgres の TXID の話は、いつも話題に上るテーマの一つです
PostgreSQLの欠陥たち https://ja.news.hada.io/topic?id=1829
5年間 PostgreSQL をスケーリングしながら学んだこと https://ja.news.hada.io/topic?id=4101