轉(zhuǎn)自戈神 ?brpc的研發(fā)經(jīng)歷

RPC是個老概念,五花八門的實(shí)現(xiàn)非常多垦江。在14年我剛轉(zhuǎn)到基礎(chǔ)架構(gòu)部時,其實(shí)是不想做RPC框架的。我的想法可能和很多工程師一樣:之前做了那么多系統(tǒng)比吭,現(xiàn)在就讓我來搞個編程框架绽族?而且這能做出什么花頭?但事實(shí)很快證明我錯了衩藤,編程上的事真的需要實(shí)踐吧慢,否則看問題就很淺。像搞深度學(xué)習(xí)赏表,vgg rcnn gan嘴上可以說得不停检诗,但只要沒在真正嚴(yán)肅的項(xiàng)目中調(diào)過參數(shù),你就是門外漢瓢剿。

RPC的深度在于現(xiàn)代的互聯(lián)網(wǎng)公司中幾乎所有服務(wù)都是使用RPC的逢慌,大部分工程師和它打交道。如果你能看到其中的痛點(diǎn)间狂,提高了效率攻泼,那么整個公司的開發(fā)效率都會有明顯的提升。大家都是從學(xué)生時代過來的鉴象,心里清楚一個東西在正確的條件下正確運(yùn)行很容易忙菠,但要在所有情況下能正確運(yùn)行就非常困難。前兩天我修了個問題:brpc在fedora 26下一個weak function莫名其妙地沒有被tcmalloc中的對應(yīng)版本覆蓋纺弊,導(dǎo)致heap profiler啟用不了牛欢,ubuntu,centos下都是好的淆游。這種問題往往和系統(tǒng)或ld有關(guān)氢惋,要精確定位很麻煩,最后我找到了一個workaround稽犁。但這個事情耗了我?guī)讉€小時焰望,因?yàn)樾枰诤芏嘞到y(tǒng)上驗(yàn)證沒有regression。RPC里大量此類東西已亥,雖然麻煩但能提高用戶體驗(yàn)熊赖。那個問題其實(shí)和brpc對tcmalloc的支持方式有關(guān),brpc默認(rèn)不鏈接tcmalloc虑椎,但用戶在程序中鏈接tcmalloc后震鹉,我們希望cpu和heap profiler要自動開啟(這兩個功能依賴tcmalloc的API),同時用戶不用重編brpc捆姜。所以我們得在brpc中動態(tài)判定是否鏈接了tcmalloc传趾,這就沒那么容易了。對我們很麻煩泥技,但用戶的體驗(yàn)更好了浆兰,甚至用戶會覺得理所當(dāng)然。

知識是需要大量實(shí)踐的,你也許可以在正確的條件下用dlsym有效地覆蓋一個glibc中的函數(shù)簸呈,但你可能不知道dlsym在有多版本符號存在時可能無效榕订,或dlsym和一些庫合用時(比如用于展開棧的libunwind)會死鎖,或dlsym對靜態(tài)鏈接是無效的除非編譯加了-rdynamic蜕便。你也許可以基于一些上下文切換庫三下五除二搞出個libcoroutine劫恒,但你可能不知道的是JNI會檢查stack layout而不能使用自定義棧,或程序運(yùn)行在valgrind中需要注冊棧地址才不會報(bào)錯轿腺,或一個棧跑到另一個LWP上展開時會觸發(fā)gcc4以上版本的thread-local誤優(yōu)化两嘴。這些知識,成千上萬條這種知識族壳,通過實(shí)踐才會深深地刻畫在腦中溶诞,構(gòu)成一個工程師真正的競爭力。

我一直堅(jiān)信所有的用戶體驗(yàn)都是端到端的决侈,只有站在用戶的角度,把整個流程以既高效又不失擴(kuò)展性的方式走通喧务,才是最好的選擇赖歌。良好的文檔正是這種理念的體現(xiàn):給新用戶鋪好路能快速上手,讓老用戶知其所以然更上一層樓功茴。這種想法也體現(xiàn)在代碼中的方方面面:每個選項(xiàng)都有合理的默認(rèn)值庐冯,用戶不設(shè)也能用;在注釋中提示best practice坎穿,避免用戶走彎路展父;用戶界面、日志內(nèi)容不啰嗦玲昧,讓用戶一眼看清楚問題的全貌栖茉。不做并不意味著我們沒能力做,而是早已被事實(shí)證明可能出現(xiàn)非常subtle的bug而被淘汰掉的選擇孵延。知道的越多吕漂,你就越會有一種責(zé)任感,需要幫助用戶修一條好路尘应,避免陷到你已經(jīng)踩過的成百上千個坑中惶凝。

說到性能,RPC的性能評估其實(shí)很像VC投資初創(chuàng)公司:每家都在說自己的東西好犬钢,并能拿出數(shù)據(jù)苍鲜,可真的好不好天曉得。所以VC只能看團(tuán)隊(duì)玷犹,查背景混滔,憑感覺,這錢花出去了能不能拿回來心里都慌的很。RPC其實(shí)也這樣遍坟,每個實(shí)現(xiàn)都有大量獨(dú)特的設(shè)計(jì)和接口拳亿,用戶不太可能輕易地從一個RPC切換到另一個RPC,并在完全相同的環(huán)境下進(jìn)行對比愿伴。每個RPC實(shí)現(xiàn)都在說自己高性能肺魁,輕量級。這是個自賣自夸的游戲隔节,用戶只能看臉鹅经。但就像我們奇怪古人連那么簡單的東西都不知道一樣,人的認(rèn)知就是這樣怎诫,內(nèi)行的常識可能對外行非常困難瘾晃,甚至這個常識非常簡單。在很多年以前幻妓,我們對“高性能”的認(rèn)識還停留在“極限QPS”和“延時”兩個維度的時候蹦误,被一個復(fù)雜系統(tǒng)中的擁塞問題搞的焦頭爛額,大家就覺得莫名其妙啊肉津,每個環(huán)節(jié)都很快强胰,這延時怎么就嘩嘩嘩地漲上去了。最后在反反復(fù)復(fù)的思考和分析后才發(fā)現(xiàn)妹沙,QPS和延時的乘積與程序的最大服務(wù)能力緊密相連偶洋。我們搞了個概念叫volume,發(fā)現(xiàn)串行系統(tǒng)的volume可以相加距糖,并行系統(tǒng)的volume可以求min玄窝,然后一層層地迭代上去從而計(jì)算出復(fù)雜系統(tǒng)同時能處理的最大請求數(shù),并解決了擁塞問題悍引。

不過就是個乘法恩脂。

今天我們知道這個原理是little's law,tcp中的BDP也是類似的道理趣斤。我們在文檔中描述了相關(guān)的知識东亦。但即使是這樣,根據(jù)我們在百度內(nèi)的支持經(jīng)驗(yàn)(沒人會否認(rèn)百度研發(fā)的整體素質(zhì)吧)唬渗,大部分RPC的用戶對這個乘法理解還是有困難的典阵,更別提理解串行相加,并行求min镊逝,在系統(tǒng)設(shè)計(jì)中活學(xué)活用了壮啊。一個乘法尚且同此,更深入的可想而知撑蒜。普通用戶是很難看明白性能測試的道道的歹啼。我們團(tuán)隊(duì)里有個老梗:“處處是熱點(diǎn)玄渗,處處不是瓶頸”。這說的是如果整個程序?qū)懙亩己艽直├暄郏豢紤]性能藤树,最后用profiler一跑,發(fā)現(xiàn)每個點(diǎn)都只有1%拓萌,2%岁钓,然后得出結(jié)論,“性能非常好微王,優(yōu)化空間已經(jīng)不大”屡限。但實(shí)際上你去分析下hot path,會發(fā)現(xiàn)有太多可以大幅提高的點(diǎn)了炕倘。性能就是這樣钧大,設(shè)計(jì)確保了流程是最優(yōu)化的,但實(shí)現(xiàn)也非常重要罩旋,細(xì)節(jié)全靠摳啊央。brpc上關(guān)鍵路徑上的代碼多一次new都需要討論,最熱的路徑上甚至不允許出現(xiàn)申明一個可能無用的空std::string涨醋,因?yàn)槔习姹緂libc中的空string是要加引用計(jì)數(shù)的瓜饥,對cache有影響。

摳細(xì)節(jié)的背后需要工程師對性能的深入理解东帅。一個函數(shù)的性能是可以估算出來的,測試只是驗(yàn)證球拦。如果不符合預(yù)期靠闭,你就要深入地去看,最終理解背后的原因坎炼。為什么一次激烈的cacheline同步大約是700ns愧膀?或是一次調(diào)度延時至少是3us,99%以內(nèi)是20us谣光?或是linux下的timed condition有60us的延時檩淋?或是一次上下文切換可以在200ns內(nèi)做完?或是無競爭的mutex可以實(shí)現(xiàn)為兩條20ns左右wait-free的原子指令萄金?掌握了這些知識蟀悦,你才能抓大放小,把精力放在最關(guān)鍵的事情上氧敢,并把它做到世界上最好的水平日戈。

但即使到現(xiàn)在,brpc中仍然有一些極具挑戰(zhàn)性的問題孙乖,比如bthread的調(diào)度如何能更好地保持cache locality浙炼,如何在NUMA機(jī)器上跑得更好份氧,如何盡量消除內(nèi)核調(diào)度的延時,如何更高效率地重用棧...如此種種弯屈。我們把brpc開源出來蜗帜,正是為了讓感興趣的伙伴一起加入進(jìn)來,做出一個更上一層樓的RPC框架资厉。與大家共勉厅缺。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市酌住,隨后出現(xiàn)的幾起案子店归,更是在濱河造成了極大的恐慌,老刑警劉巖酪我,帶你破解...
    沈念sama閱讀 211,194評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件消痛,死亡現(xiàn)場離奇詭異,居然都是意外死亡都哭,警方通過查閱死者的電腦和手機(jī)秩伞,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評論 2 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來欺矫,“玉大人纱新,你說我怎么就攤上這事∧屡浚” “怎么了脸爱?”我有些...
    開封第一講書人閱讀 156,780評論 0 346
  • 文/不壞的土叔 我叫張陵,是天一觀的道長未妹。 經(jīng)常有香客問我簿废,道長,這世上最難降的妖魔是什么络它? 我笑而不...
    開封第一講書人閱讀 56,388評論 1 283
  • 正文 為了忘掉前任族檬,我火速辦了婚禮,結(jié)果婚禮上化戳,老公的妹妹穿的比我還像新娘单料。我一直安慰自己,他們只是感情好点楼,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,430評論 5 384
  • 文/花漫 我一把揭開白布扫尖。 她就那樣靜靜地躺著,像睡著了一般掠廓。 火紅的嫁衣襯著肌膚如雪藏斩。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,764評論 1 290
  • 那天却盘,我揣著相機(jī)與錄音狰域,去河邊找鬼媳拴。 笑死,一個胖子當(dāng)著我的面吹牛兆览,可吹牛的內(nèi)容都是我干的屈溉。 我是一名探鬼主播,決...
    沈念sama閱讀 38,907評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼抬探,長吁一口氣:“原來是場噩夢啊……” “哼子巾!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起小压,我...
    開封第一講書人閱讀 37,679評論 0 266
  • 序言:老撾萬榮一對情侶失蹤线梗,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后怠益,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體仪搔,經(jīng)...
    沈念sama閱讀 44,122評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,459評論 2 325
  • 正文 我和宋清朗相戀三年蜻牢,在試婚紗的時候發(fā)現(xiàn)自己被綠了烤咧。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,605評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡抢呆,死狀恐怖煮嫌,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情抱虐,我是刑警寧澤昌阿,帶...
    沈念sama閱讀 34,270評論 4 329
  • 正文 年R本政府宣布,位于F島的核電站恳邀,受9級特大地震影響懦冰,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜轩娶,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,867評論 3 312
  • 文/蒙蒙 一儿奶、第九天 我趴在偏房一處隱蔽的房頂上張望框往。 院中可真熱鬧鳄抒,春花似錦、人聲如沸椰弊。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,734評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽秉版。三九已至贤重,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間清焕,已是汗流浹背并蝗。 一陣腳步聲響...
    開封第一講書人閱讀 31,961評論 1 265
  • 我被黑心中介騙來泰國打工祭犯, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人滚停。 一個月前我還...
    沈念sama閱讀 46,297評論 2 360
  • 正文 我出身青樓沃粗,卻偏偏與公主長得像,于是被迫代替她去往敵國和親键畴。 傳聞我的和親對象是個殘疾皇子最盅,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,472評論 2 348

推薦閱讀更多精彩內(nèi)容