Database Table Partitioning

駱勁成
iCHEF
Published in
5 min readJan 16, 2023

前言

一年前人生突然遭遇變卦,當時寫到一半的草稿,就這樣被心靈分割出去塵封一年,讓我能專心面對人生的其他課題;本文要介紹的資料表分割(table partitioning)也有類似的功效,資料庫有機會將專注力限縮在當下該放的地方,讓資料從通鋪走入隔間。

因為文章延宕一年,這個機制也在 iCHEF production 環境多歷經了一年的驗證,本文所分享的基於 PostgreSQL v12 on AWS RDS 2xlarge instance。

問題

單一資料表資料量已到 billion 等級,以 iCHEF 為例,該資料表每天約有 600 萬筆新增資料,且該資料會被更新以及被 client 端不定時查詢。 隨著資料量越來越大,暗藏在生命中的困難也陸續出現:

  • 單一查詢/新增/更新所耗費資源漸漸提高
  • 如某一 index 超過能一次放進工作記憶體的大小時,效率顯著下降
  • 資料表的自動維護動作(autovacuum)占用的資源更高、耗時更久

前置處理

上述問題,在資料表分割前,還是有一些可先做的

  • 如商業邏輯上允許,定期清理/搬移舊資料
  • 刪除不必要的 index,例如可參考另一篇分享 More or less, less is more
  • 調整 db 自動維護動作的閥值,讓它少量多餐,不要一次得清理過億筆的資料,如商業上允許,也可在系統離峰時定期觸發資料表維護工作

Table Partitioning

Table partitioning 仍然維持了對原 table 的操作(雖然其實該 table 底下已無實體資料,而是各 partition 擁有實體資料),對大量使用 ORM 操作資料庫的 iCHEF,仍算是可無痛轉移。

PostgreSQL 提供了三種分割資料表的方式

  • Range Partitioning
    以欄位的數值區間來分割,例如有一資料表儲存使用者的生日,那麼你可指定生日在同一天的使用者放同在一個 partition,如果有個要以生日發動的操作就會更有效率,因為資料庫不需要去看其他 365 天的 partition
  • List Partitioning
    類似上述 Range Partitioning,只是是指定欄位的值而不是區間,例如有一欄位儲存公司使用者的部門(管理、財會、開發、維運等),那麼你可以指定管理一組、財會一組、開發和維運一組
  • Hash Partitioning
    指定你想要的 partition 數量,會以指定欄位組成的 hash 值取餘數,來分配該資料所屬的 partition,因此如欄位組成選擇恰當,可以達到平均將資料分配到各 partition 的目的,例如以資料的 id 來 hash

MySQL 也有類似的設計,可參考官方文件

Partition Key 的選擇案例

看完上述相信也對 table partitioning 有點概念了,上述 partition key 的選擇是成敗的關鍵,必須根據該資料的特性和商業邏輯上操作這些資料的方式來選擇,以下是我們選用了兩種分割方式各自的優缺點供各位參考:

  1. Range Partitioning by create date
    因商業邏輯上允許超過某一時間段的資料可刪除,且該資料特性是幾乎九成的資料都是當天進行新增/更新/查詢操作
    Pros:
    .定期清理資料可直接 DROP TABLE 非常快速高效
    .partition 有明顯的冷熱區
    .DB 自動維護動作效率明顯上升
    Cons:
    .需定期新建 partition table 抖抖的
    .在應用中效率不夠高,因為是以資料的 task_id 為基礎進入,而不是建立時間
  2. Hash Partitioning by task_id
    該資料有一 task_id,是資料生成時就被賦予的,也是與 client 端溝通的根據
    Pros:
    .在應用中效率夠高,只需查詢/更新單一 partition 內的資料及其 index
    .partition 固定,不用擔心該資料的 partition 尚未被建立
    .如未來要轉移到 Cassandra/AWS Dynamo,平均分散式的 partition 類型應能更無痛轉移,也更能有效利他們分散式架構的優勢
    Cons:
    .以建立時間清理資料時,無法直接 DROP TABLE 這麼高效

成效

最終我們選用了 Hash Partitioning by task_id 的方式,將一 table 切成 32 個 partition,該資料查詢總時間降為原本的 30%,其餘操作如資料更新、autovacuum 所消耗的系統資源也下降了。

有隔間真的比較好嗎?筆者分享一個在湖口營區服役時的小故事,當時同袍們一百多人睡在大通鋪,突然一老鼠從天而降想偷吃我們藏在包包內的零食,這隻老鼠就這樣在通舖上的同袍們身上逃竄,有時候有隔間還是蠻好的。
資料表分割後就無法輕易回頭,希望我們都能陸續走出隔間,有興趣來 iCHEF 一起工作歡迎點我看職缺

--

--