Facebook 數(shù)據(jù)庫項目負責(zé)人:我做基礎(chǔ)架構(gòu)學(xué)到的42件事
?最近讀到了分布式系統(tǒng)研究者 Mahesh Balakrishnan 的一篇博客《42 things I learned from building a production database》。同樣做基礎(chǔ)架構(gòu),看完大佬總結(jié)的經(jīng)驗后拍案叫絕,其中有幾條簡直是真知灼見,故翻譯了全文。
Mahesh Balakrishnan 是 Facebook Delos 項目的負責(zé)人。Delos 對標(biāo) ZooKeeper,關(guān)于 Delos 更多詳細細節(jié)其團隊已經(jīng)發(fā)了兩篇 paper,感興趣的同學(xué)可以自行搜索。
IC = Individual Contributor,即獨立貢獻者,F(xiàn)acebook 開發(fā)團隊的一個術(shù)語,指那些不是經(jīng)理、不是 team leader、不是任何領(lǐng)導(dǎo)職位的編碼人員,可以理解為一線開發(fā)人員。
對客戶(用戶)
1)讓你的客戶開心,否則這篇文章的其余部分都無關(guān)緊要。
2)要注意擁有正確數(shù)量的客戶(剛開始時,就一個)和合適的客戶(他允許你構(gòu)建關(guān)鍵技術(shù)),并小心地增加這個數(shù)字。
3)直接與客戶對接。很多團隊內(nèi)部沖突可以通過一句“我剛才和客戶談過,他們說......”來解決。在做基礎(chǔ)架構(gòu)時,我們往往不需要猜測客戶的需求,我們可以直接問他們。
4)但要意識到客戶可能無法表達他們真正需要的東西。不要只看到需求的表面價值,而要花時間詳細地理解他們的用例,閱讀他們的代碼。
項目管理
5)要有一個簡單明了的使命宣言來表達你存在的理由,Delos 的宣言是:我們將成為 FB infra 的可靠基礎(chǔ)。
6)反復(fù)進行任務(wù)難度的評估。決策者可能沒有時間、傾向、上下文或培訓(xùn)來進行評估,而且可能會把它們弄錯(簡直是)幾個數(shù)量級。
7)對 IC 的任務(wù)分配很關(guān)鍵。要求自己處于任何決策的關(guān)鍵路徑上,因為你通常比經(jīng)理更了解問題、代碼庫和 IC 們的優(yōu)勢。如果你和其他 IC 自己解決任務(wù)分配問題,大多數(shù)經(jīng)理都會很高興。
8)Road-map 是一種手段,而不是目的。
9)如果你有好的或一致的經(jīng)理,要盡可能地理解、支持和包容。如果你沒有這樣的經(jīng)理人......好吧,我還沒有想明白這個問題,如果你想明白了,請告訴我。
10)使你的項目對組織架構(gòu)調(diào)整有足夠的魯棒性。一個公司的管理層級本質(zhì)上是脆弱的(畢竟,樹是一個單連接的圖),所以要不斷地與未來可能接手這個項目的經(jīng)理進行交流,不惜一切代價,確保經(jīng)理人的變動不會給 IC 們帶來不公平的職業(yè)結(jié)果。
通常來說,公司組織架構(gòu)調(diào)整是非常頻繁的,經(jīng)常一年就會調(diào)整一次,確保經(jīng)理人的變動不會帶來不公平的職業(yè)結(jié)果,這點其實很難(我也很想知道怎么做到)。
11)追蹤類似的功能,在你所在領(lǐng)域的其他項目中花費了多長時間,并以此作為任務(wù)難度評估的依據(jù)(例如,“功能 X 在系統(tǒng) Y 中花了 3 年時間;這不是一個 IC 的一半工作”)。
設(shè)計
12)對 API 要保守,對實現(xiàn)要寬松(Be conservative on APIs and liberal with implementations)。
13)但要堅持謹慎地推出新的實現(xiàn)(灰度、分階段推出)。
14)設(shè)計 API 時,寫代碼完成第一個實現(xiàn)(implementation),積極計劃第二個實現(xiàn),并希望/祈禱事情將在第三個實現(xiàn)中發(fā)揮作用。(When designing APIs, write code for one implementation; plan actively for the second implementation; and hope/pray that things will work for a third implementation.)
15)設(shè)計 API 時,首要考慮向新實現(xiàn)的遷移。自定義遷移會造成巨大的時間消耗且不可靠。每個主要的 API 都應(yīng)該有一個單一的 CLI 驅(qū)動的調(diào)用來切換實現(xiàn)。
16)作為一個團隊去設(shè)計,作為個人實現(xiàn)(Design as a team; implement as individuals)。這將使設(shè)計成為瓶頸,但這是值得的:抵制并行化設(shè)計的沖動。
17)對于存儲系統(tǒng),在開始時就要重點關(guān)注一致性和持久性,而不是可用性。一致性和持久性更難衡量,如果出問題也更難修復(fù),由于可用性更容易衡量,所以會有外部壓力要求優(yōu)先考慮它;推到后面去。
18)在測試中維護 API 的多個實現(xiàn),比較它們之間的結(jié)果。這樣做的代價是值得的(這將有助于正確性,也可以防止實現(xiàn)細節(jié)的泄露)。
19)對設(shè)計進行后期綁定(Late-bind):鼓勵團隊思考整個設(shè)計空間,而不是承諾使用某個特定的解決方案。與一群高智商、有主見的 IC 們一起開頭腦風(fēng)暴會議是一門值得掌握的藝術(shù)。鼓勵在設(shè)計的關(guān)鍵路徑上進行粗略的原型設(shè)計。
20)對實現(xiàn)者進行后期綁定:一旦設(shè)計完成,任何 IC 都應(yīng)該能夠編寫代碼。
21)擁有適當(dāng)數(shù)量的抽象(這很難)。太少了,你會得到一個混亂的單體;太多了,團隊會被理解每個抽象的語義的認知開銷所淹沒。
22)避免使用實時性來保證正確性或在機器間比較時鐘,除非你有(并理解)時鐘的錯誤界限。
23)有一個單一的真理來源。在各種類型的狀態(tài)之間建立簡單的不變量。
24)創(chuàng)造一種文化,讓 IC 不斷地思考完全不同的設(shè)計,不要停止關(guān)于假設(shè)性替代設(shè)計的對話,鼓勵好奇心。
25)了解你的 SKU。云計算使人們很容易忽視硬件,但對硬件(和硬件趨勢)的理解對設(shè)計來說至關(guān)重要。
Code Review
26)在一個具有快速評審周期的透明代碼庫中,除非你把關(guān),否則 API 會泄露實現(xiàn)細節(jié)。
27)鼓勵 IC 對 diffs 進行批判性的思考,并創(chuàng)造一個人們可以自由表達的環(huán)境。作為 diffs 作者,你對指出 diffs 問題的人的反應(yīng)應(yīng)該是感激,而不是沮喪。
28)對于關(guān)鍵組件,考慮非正式的規(guī)則,例如要求兩個接受(即兩個 LGTM)或甚至是某個子集的 IC 的一致接受。
29)對于關(guān)鍵組件,落地時間不是衡量其重要性的標(biāo)準(zhǔn),要抵制衡量這一標(biāo)準(zhǔn)和優(yōu)化它的沖動。創(chuàng)造一種讓 IC 可以接受 diffs 不能快速落地的文化(創(chuàng)造性的工作——書籍、論文等等——由于高質(zhì)量 review 的成本,通常需要漫長的 review 周期;為什么代碼應(yīng)該有所不同?)
30)有時候,你只有在一個 IC 寫出了一個候選的設(shè)計方案后,才意識到這個設(shè)計是正確的。要抵制說“哦,好吧,讓我們先落地,然后再修復(fù)它”的沖動;你這樣做對 IC 和項目都沒有幫助。創(chuàng)造一種文化,讓 IC 感覺到如果這不是正確的解決方案,就可以丟棄代碼(以身作則)。
策略
31)以某種節(jié)奏問自己:為什么這個團隊/項目會存在?如果它不存在,會發(fā)生什么(哪個其他團隊/系統(tǒng)會填補這個空白)?該團隊是如何為公司增加價值的,以及它如何在未來繼續(xù)這樣做?
32)跟蹤公司內(nèi)你所在領(lǐng)域的每個其他主要項目,你應(yīng)該能夠比他們自己的 IC 更好地解釋他們的技術(shù)設(shè)計。抓住任何機會去與其他類似項目的負責(zé)人辯論項目范圍:你應(yīng)該能夠闡明你的項目如何適合更大的生態(tài)系統(tǒng)。團隊間的競爭是健康和必要的。與這些項目中的 IC 交朋友:他們比公司里的其他人更了解你的技術(shù)挑戰(zhàn)。
33)不要在原始性能或效率上與其他團隊競爭。這將升級為一場軍備競賽,兩個團隊都會浪費時間為工作負載優(yōu)化他們的系統(tǒng),產(chǎn)生蘋果與橘子的比較,等等。在基本設(shè)計特性上進行競爭。
34)如果客觀上有人在你的使用場景有更好的系統(tǒng),并想接手它,那就去找別的事做吧。
可觀測性
35)測量是一種手段,而不是目的。
36)你應(yīng)該能夠在你的客戶之前發(fā)現(xiàn)你的服務(wù)中的問題。
37)在盡可能的情況下,可觀察性應(yīng)該在 API 之上,并在實現(xiàn)(implementations)之外。這可以確保你可以切換實現(xiàn)并比較性能,而不會在測量代碼中引入錯誤。它還可以簡化實現(xiàn);并降低新實現(xiàn)的門檻。
38)任何不容易測量的東西(例如,一致性)往往被遺忘,要特別注意那些難以測量的屬性。
39)盡可能將關(guān)鍵的檢查(例如一致性)推到部署本身,盡量減少對外部服務(wù)的檢查(否則你現(xiàn)在有兩件事要跟蹤,而不是一件)。
研究
40)追蹤你所在領(lǐng)域的研究成果。很快你就會和你的 IC 有一個速記,可以實現(xiàn)超快的溝通。"如果我們嘗試項目 X 中的那個東西呢?并將其與項目 Y 中的技術(shù)相結(jié)合?"。
41)嘗試新事物。在可行的解決方案內(nèi),偏向于新的東西。抵制逐字逐句地復(fù)制設(shè)計的沖動。每一個重要的系統(tǒng)在某些時候都只是某人頭腦中的一個半生不熟的想法。
42)寫論文。為那些對你正在做的事情沒有任何背景的聽眾寫作,將迫使你檢查和澄清你的假設(shè)。論文可以使你更容易雇用到優(yōu)秀的人才,也更容易讓他們上崗。研究生應(yīng)該能夠向你解釋你的設(shè)計(并發(fā)現(xiàn)錯誤?。?。當(dāng)被要求做講座時,盡量答應(yīng)。它們很有趣,而且你可以認識新的人。?