brpc 摘要

Cacheline

1.背景:cpu的L1和L2級cache為每個核獨有押搪,cpu的L3cache為所有核心共享
2.原因:核寫入自己的L1級cache是極快的树酪,但當另一核讀寫同一處內(nèi)存時,由于每個核有l(wèi)ocal cache大州,需要進行一致性同步续语,確保內(nèi)存和所有l(wèi)ocal cache的數(shù)據(jù)是一致的,這個復(fù)雜的硬件算法使得原子操作變得很慢
3.例子:所有線程頻繁修改一個計數(shù)器厦画,性能就會很差疮茄,讓每個線程修改獨立的thread_local變量,在需要時再同步
4.解決方法:避免共享力试,變量按訪問規(guī)律排列,頻繁修改的線程要放在獨立的cacheline中

Memory fence

1.背景:cpu和編譯器重排指令導(dǎo)致讀寫順序的變化

Non-blocking wait-free& lock-free

1.Non-blocking:一個線程的失敗或掛起不會導(dǎo)致其他線程的失敗或掛起排嫌。 通過Non-blocking實現(xiàn)高并發(fā)
2.Non-blocking算法如果保證每個線程始終在做有用的事畸裳,那么就是wait-free,如果保證至少有一個線程在做有用的事淳地,那就是lock-free
3.wait-free&lock-free并不保證高性能怖糊,因為需要處理更多更復(fù)雜的race condition和ABA problem
4.mutex:鎖導(dǎo)致低性能的原因是臨界區(qū)過大,或者上下文切換頻繁
5.使用鏈表記錄 處理多線程寫的問題颇象,通過swap(head)的方式伍伤,競爭寫權(quán)限,如果返回null遣钳,則成功扰魂,否則swap(head)->next 。如果數(shù)據(jù)量較大,會啟動keep Write寫線程批量寫出

Socket

1.Create/Address/SetFailed
2.Socket類似shared_ptr劝评,SocketId類似于weak_ptr姐直,SetFailed可以再需要時確保Socket不能被繼續(xù)Address而最終引用計數(shù)歸0.
3.存儲SocketUniquePtr還是SocketId取決于是否需要強引用。如果需要大量數(shù)據(jù)交互蒋畜,存放的是SocketUniquePtr简肴。epoll主要提醒對應(yīng)fd上發(fā)生了事件,如果socket回收了百侧,那這個事件可有可無,所以存放SocketId

自適應(yīng)限流

1.背景:服務(wù)能力有上限能扒,請求速度超過處理速度佣渴,服務(wù)會過載。通過設(shè)置最大并發(fā)能直接拒絕一部分請求初斑。
2.原因:當服務(wù)數(shù)量多辛润,拓撲復(fù)雜,且處理能力會逐漸變化的局面下见秤,固定最大并發(fā)數(shù)帶了了巨大測試工作量
3.Little' Law: 服務(wù)穩(wěn)定時:concurrency = qps*latency砂竖, noload_latency 單純?nèi)蝿?wù)處理的延時,peak_qps是處理或回復(fù)的qps
3.解決方案:besk_max_concurrrency = noload_latency * peak_qps鹃答。 自適應(yīng)限流就是要找到服務(wù)的noload_latency 和 peak_qps乎澄,并將最大并發(fā)設(shè)置為靠近兩者乘積的一個值
max_concurrency = max_qps * ((2+alpha) * min_latency - lantency)。 不斷對請求進行采樣测摔,通過窗口采樣獲得樣本的平均延遲和當前qps置济, 計算出下一個窗口的max_concurrency。 通過定期降低max_concurrency
為避免流量損失太多的情況 1.請求數(shù)量足夠多時锋八,直接提交當前采樣窗口 2.計算公式方面浙于,當current_qps > max_qps時,直接進行更新挟纱,不進行平滑處理羞酗。 2秒左右將qps打滿

雪崩

1.解決方法:1)設(shè)置合理的max_concurrency,最大qps*非擁塞時的延時來評估最大并發(fā)紊服。2)注意重試設(shè)置檀轨。只有當連接錯誤時重試,而不是連接超時時重試围苫。如果需要連接時重試裤园,可以設(shè)置backup request,這種重試只有一次剂府,放大程度降低到最低拧揽。3)brpc默認在bthread中處理請求,個數(shù)是軟件限制

backup request

1.設(shè)置backup_request_ms,先發(fā)送請求淤袜,經(jīng)過backup_request_ms后再發(fā)送一次請求痒谴,之后誰先返回取哪一個

bthread

單核reator,libevent等為典型铡羡,實質(zhì)是把多段邏輯按事件觸發(fā)順序交織在一個系統(tǒng)線程中
N:1 線程庫积蔚,所有協(xié)程運行于一個系統(tǒng)線程中,計算能力與各種eventloop庫等價烦周。 由于不跨線程尽爆,可以高效的利用 local cache, 無上下文切換代價读慎,但不能高效的利用多核漱贱,代碼必須非阻塞。 更適合寫運行時間確定的IO服務(wù)器夭委,典型如http server
多核reator幅狮,以boost::asio為典型,一般由一個或者多個線程分別運行event dispatcher株灸,待事情發(fā)生后把event_handler交給一個worker線程崇摄。由于cache一致性,未必能獲取線性與核心數(shù)的性能慌烧。
M:N 線程庫逐抑,用戶態(tài)的實現(xiàn)以go為主。一個bthread被卡住不會影響其他bthread杏死,關(guān)鍵技術(shù)兩點: work stealing調(diào)度和butex

lambda是一種語法糖泵肄,可以讓異步編程沒那么麻煩,但無法降低多線程編碼難度

bvar

多線程環(huán)境下的計數(shù)器類庫淑翼,方便記錄和查看用戶程序中各類數(shù)值腐巢,利用local cache減少了cache bouncing。本質(zhì)是將寫時的競爭轉(zhuǎn)移到了讀玄括,讀得合并所有寫過的線程數(shù)據(jù)冯丙,不可避免的慢了
適合: 寫多讀少
不適合:基于最新值做邏輯判斷,讀多寫多
方式:定期把監(jiān)控項目打入固定目錄下的文件

內(nèi)存管理

內(nèi)存管理都存在如下兩點權(quán)衡
1.線程間競爭小遭京,resource pool通過批量發(fā)送和歸還避免全局競爭胃惜,并降低單次的開銷
2.浪費的空間少,需要共享內(nèi)存
多線程框架廣泛地通過傳遞對象的ownership來讓問題異步化哪雕,如何讓分配這些小對象的開銷變得更小是值得研究的問題:大多數(shù)結(jié)構(gòu)是等長的
對象可以被歸還船殉,但歸還后并沒有被刪除,也沒有被析構(gòu)斯嚎,而是僅僅進入freelist
一個pool中所有的bthread的棧必須一樣大

ABA問題

A->B->A 通過加入版本號解決
A1->B2->A3
id通過 (32位偏移量 + 32位版本)決定 利虫,偏移量相當于指針

DoublyBufferData

背景:讀遠多于寫的數(shù)據(jù)結(jié)構(gòu)挨厚。一個方法是雙緩沖,實現(xiàn)無鎖查找1)數(shù)據(jù)分前臺和后臺2)檢索線程只讀前臺糠惫,不用加鎖3)另一個寫線程:修改后臺數(shù)據(jù)疫剃,切換前后臺,睡眠一段時間硼讽,以確保老前臺不再被檢索線程訪問
解決方案:讀拿一把thread-local鎖巢价,寫需要拿所有的thread-local鎖。
1.數(shù)據(jù)分前臺和后臺
2.讀拿到自己所在線程的thread-local鎖固阁,執(zhí)行查詢邏輯后釋放
3.同時只有一個寫壤躲,修改后臺數(shù)據(jù),切換前后臺备燃,挨個獲得所有thread-local鎖并立刻釋放柒爵,結(jié)束后再改一遍新后臺(保證之前的讀線程所在的thread-local已結(jié)束,即所有讀線程都看到了新前臺)

健康檢查

只要一個節(jié)點不從NamingService刪除赚爵,它要么是正常的,要么在做健康檢查

cpu profile

在定期被調(diào)用的SIGPROF handler中采用所在線程的棧法瑟,cpu profiler在運行一段時間后能以很大概率采集到所有活躍線程中的活躍函數(shù)冀膝,最后根據(jù)棧代表的函數(shù)調(diào)用關(guān)系匯總為調(diào)用圖,并把地址轉(zhuǎn)為符號

heap profiler

每分配滿一些內(nèi)存就采樣被調(diào)用處的棧

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末霎挟,一起剝皮案震驚了整個濱河市窝剖,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌酥夭,老刑警劉巖赐纱,帶你破解...
    沈念sama閱讀 219,490評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異熬北,居然都是意外死亡疙描,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,581評論 3 395
  • 文/潘曉璐 我一進店門讶隐,熙熙樓的掌柜王于貴愁眉苦臉地迎上來起胰,“玉大人,你說我怎么就攤上這事巫延⌒澹” “怎么了?”我有些...
    開封第一講書人閱讀 165,830評論 0 356
  • 文/不壞的土叔 我叫張陵炉峰,是天一觀的道長畏妖。 經(jīng)常有香客問我,道長疼阔,這世上最難降的妖魔是什么戒劫? 我笑而不...
    開封第一講書人閱讀 58,957評論 1 295
  • 正文 為了忘掉前任半夷,我火速辦了婚禮,結(jié)果婚禮上谱仪,老公的妹妹穿的比我還像新娘玻熙。我一直安慰自己,他們只是感情好疯攒,可當我...
    茶點故事閱讀 67,974評論 6 393
  • 文/花漫 我一把揭開白布嗦随。 她就那樣靜靜地躺著屋摔,像睡著了一般舔涎。 火紅的嫁衣襯著肌膚如雪微王。 梳的紋絲不亂的頭發(fā)上距芬,一...
    開封第一講書人閱讀 51,754評論 1 307
  • 那天酵颁,我揣著相機與錄音羡榴,去河邊找鬼兴溜。 笑死却妨,一個胖子當著我的面吹牛蜻直,可吹牛的內(nèi)容都是我干的盯质。 我是一名探鬼主播,決...
    沈念sama閱讀 40,464評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼概而,長吁一口氣:“原來是場噩夢啊……” “哼呼巷!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起赎瑰,我...
    開封第一講書人閱讀 39,357評論 0 276
  • 序言:老撾萬榮一對情侶失蹤王悍,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后餐曼,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體压储,經(jīng)...
    沈念sama閱讀 45,847評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,995評論 3 338
  • 正文 我和宋清朗相戀三年源譬,在試婚紗的時候發(fā)現(xiàn)自己被綠了集惋。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,137評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡踩娘,死狀恐怖芋膘,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情霸饲,我是刑警寧澤为朋,帶...
    沈念sama閱讀 35,819評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站厚脉,受9級特大地震影響习寸,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜傻工,卻給世界環(huán)境...
    茶點故事閱讀 41,482評論 3 331
  • 文/蒙蒙 一霞溪、第九天 我趴在偏房一處隱蔽的房頂上張望孵滞。 院中可真熱鬧,春花似錦鸯匹、人聲如沸坊饶。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,023評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽匿级。三九已至,卻和暖如春染厅,著一層夾襖步出監(jiān)牢的瞬間痘绎,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,149評論 1 272
  • 我被黑心中介騙來泰國打工肖粮, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留孤页,地道東北人。 一個月前我還...
    沈念sama閱讀 48,409評論 3 373
  • 正文 我出身青樓涩馆,卻偏偏與公主長得像行施,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子魂那,可洞房花燭夜當晚...
    茶點故事閱讀 45,086評論 2 355

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