擁有權
一個服務寫一份資料。其餘所有人讀它的契約。
「擁有者」是項目 30 裡承重的那個詞,所以這裡給它一個定義,而不是一種語感:
一份資料的擁有者,是唯一被允許寫入它的服務。擁有者決定 schema,也是唯一可以不問任何人就改它的一方。其他所有應用 —— 包含同一個團隊底下的其他服務 —— 都經由擁有者的契約取用那份資料。
不對稱:寫與讀不是同一個問題
第二個寫入者和第二個讀取者,壞掉的東西不一樣。把兩者混為一談,正是「是不是所有東西都要走 API」會吵起來的原因。
| 第二個寫入者 | 第二個讀取者 | |
|---|---|---|
| 壞掉的是 | 不變量。兩個寫入者無法同時維持「一張訂單至少有一筆明細」—— 因為誰都看不到對方的交易。 | 變更能力。讀方的查詢把 schema 釘住,擁有者從此改不動。 |
| 救得回來嗎 | 不行。等你發現的時候,資料已經不一致了。 | 可以,但前提是找得出所有讀方 —— 見 02 · 03。 |
| 規則 | 絕不允許。 永遠只有一個寫入者。 | 走契約,但下面那個分析型例外除外。 |
分析型的例外很重要:大量或歷史查詢根本不該進同步 API。它們走項目 27 的資料倉儲或項目 28 的事件匯流排 —— 這件事寫在05 · 遷移。
擁有權怎麼決定
照順序問,問到第一個有明確答案的就停:
- 今天是誰在寫? 如果恰好只有一個服務寫某一組資料表,那個服務就是擁有者。多數資料在這一步就解決了。
- 不變量是誰的? 如果有好幾個在寫,擁有者是「資料要說得通就必須靠它正確」的那個服務 —— 是執行規則的那個,不是寫最多列的那個。
- 出事時打給誰? 如果不變量也講不清楚,擁有權跟著 on-call 走。半夜被叫起來的那個團隊,其實已經在每一種意義上擁有它了,只差沒被記錄下來。
第 1 步要從資料庫側回答 —— 稽核輸出、pg_stat、proxy log —— 不是發問卷。問卷記的是各團隊記得什麼;這個環境的實況與他們記得什麼無關。
真的不明確的時候
有些資料就是找不到合理的擁有者:一張所有東西都在讀、三個東西在寫的共用對照表;或是一個已經退役的系統留下來的表。
向上呈報。不要預設丟給用最多的那個。 把資料交給碰它最多次的人,紙上有擁有者、實際沒有;它發布的契約也不會有人負責維護。誠實的處理方式是這三種:
- 拆開。 看起來像一份的資料,通常其實是兩份,各自都有明顯的擁有者。
- 給它一個容身的服務。 真正共用的參考資料,可以由一個小服務專門擁有它,那就是它唯一的職責。
- 退役。 一張沒有人願意擁有的表,經常是一張沒有人需要的表。
在里程碑 30.1 裡記下「不明確」是有效的結果,而且比猜一個答案更好。