《高可用架構第1卷【1】》——高可用架構案例精選

  • 內容老,15年16年的,篇數多因此就很細碎,都是博客文之類的,沒用node

  • 微信公衆號的合集 略貴。 不少內容講述 比較淺顯 沒有涉及到技術細節 。mysql

  • 能夠參考,但不少知識、技術是2015年左右的,不適合如今;每篇文章末尾的QA頗有意思,不少問題問到點子上了nginx

     

     

    第1 章 高可用架構案例精選 1
    郭斯傑/1.1 Twitter 高性能分佈式日誌系統架構解析 1
    1.1.1 爲何須要分佈式日誌. 1
    1.1.2 Twitter 如何考慮這個問題 4
    1.1.3 基於Apache BookKeeper 構建DistributeLog 5
    1.1.4 DistributeLog 案例分享13
    1.1.5 疑問與解惑.13golang

    如何使用日誌在Manhattan(Twitter 的最終一致性分佈式 KV數據庫)中實現 compare-and-set CAS這樣的強一致性操做redis

     

    用日誌來序列化全部請求;算法

    到此爲止,你能夠看出日誌的好處。它將一個本來複雜的問題變得簡單。

    這種解決問題的思路叫作 Pub/Sub。而日誌就是 Pub/Sub 模式的基礎。

    由於 Pub/Sub 這個模式是那麼簡單並且強有力,這讓咱們思考,是否是能夠構建一個高可用的分佈式日誌服務,全部在 Twitter 的分佈式系統均可以複用這個日誌服務?

    構建一個分佈式日誌系統,首要的事情就是找出咱們須要解決什麼問題,知足什麼樣的需求。sql

     

    首先做爲一個基本設施,存儲在日誌中的數據須要持久化,這樣它能夠容忍宕機,避免數據丟失。數據庫

     

    由於須要做爲分佈式系統的基礎設施,那麼在單機上持久化是遠遠不夠的。咱們須要將數據複製到多臺機器上,提升數據和系統的可用性。後端

     

    當數據被複制到多臺機器上的時候,咱們就須要保證數據的強一致性。不然,若是咱們出現丟數據、數據不一致,那麼勢必影響到構建在分佈式日誌上的全部系統。若是日誌都不能相信了,你的生活還能相信誰呢 :)api

     

     

     

     持久化 多副本 一致性

     

    在設計這個分佈式日誌系統 DistributedLog 的時候,咱們進行了各類調研。也同時基於運維已有系統 (kestrel, Kafka) 的經驗,咱們最終決定基於 Apache BookKeeper進行構建。

    主要由於 Apache BookKeeper 提供的三個核心特性:I/O 分離、並行複製和容易理解的一致性模型。它們可以很好地知足咱們對於持久化、多副本和一致性的要求。

     

    Apache BookKeeper 沒有將很複雜的一致性機制捆綁在一塊兒。寫者和讀者之間也沒有很複雜的協同機制。全部的一致性的協調就是經過這個 LAC 指針 (Last Add Confirmed)。這樣的作法,能夠使得擴展寫者和擴展讀者相互分離。

     

     

     

    Q & A
    一、日誌順序方面,日誌的序列號(1,2,3,4……),是否使用了 Twitter 的 snowflake 服務?獲取序列號後再推送日誌?是上面提到的什麼組件作的?

    沒有使用 Twitter 的 snowflake 服務。由於 Writer 是 single writer,存在 ownership。全部的寫會 forward 給 owner 進行序列化

     

    二、這是 Kafka 的替代產品嗎?

    是的。Kafka 目前沒有被使用在數據庫日誌的場景。由於 Kafka 的每一個 topic 對應一個文件,在 topic 數量特別多,且須要持久化的場景,Kafka 的性能比較差。很難適用於 Twitter 的多租戶場景。

     

    三、請問是否研究過 ELK,請問在前面分享的架構中,哪一個對應 ELK 中的 Logstash(或fluentd)部分?或是 BookKeeper 就是替換它的?

    這裏的日誌就是數據庫的日誌。跟平常的文本日誌不同。在 ELK 架構中,E 是文本的索引,K 是 UI。這兩個部分不是 DistributedLog/BookKeeper 所解決的問題。DistributedLog/BookKeeper 能夠做爲 PUB/SUB 這樣的消息中間件來作日誌的中轉,也就是能夠用在 L 的部分。

     

    四、分享中提到的 Kestrel 和 Kafka 一個在線 ,一個離線,具體差別是什麼?

    Kestrel 主要是 producer/consumer queue 的模型。而 Kafka 是 pub/sub 模型Kestrel 支持 per item 的 transaction,粒度是 item。而 Kafka 的粒度是 partition

     

    五、Name Log 的具體機制是什麼樣的? Client 刪除日誌時怎樣保證與讀者和寫者不衝突?

    Name Log 是 DistributedLog 提供的用戶接口。底層分塊成不一樣的 Ledgers 進行存儲。元數據記錄在 ZooKeeper。使用 ZooKeeper 的 CAS 操做和 notification 機制來協調。

     

    六、想多瞭解一下跨數據中心複製,感受很差作。能否介紹一下?

    這個問題比較寬泛。跨數據中心,能夠是異步複製,也能夠是同步複製。不一樣場景有不一樣的權衡。

     

    七、若是 LAC 以後的那條記錄始終不能寫成功,是否是就阻塞在那裏,LAC 就無法移動了?

    這是一個很好的問題。Ensemble Change 可以保證寫永遠 go through。因此 LAC 會被 update 到 bookies。讀方面的 Speculative 機制保證能讀到 LAC。

    八、 這裏的 writer 是 Write Proxy 嗎?若是是的話,single writer 的吞吐量就是這個 ledger 的最大寫的吞吐量了吧,會不會成爲瓶頸?

    這裏的 Writer 是指 Write Proxy。首先,一個 Ledger 的吞吐量,取決於 Bookie 的磁盤/網絡帶寬。假設,Bookie 的網卡是 1Gbps,一塊磁盤做爲日誌寫的磁盤,那麼在保證低延時的狀況下,Bookie 的吞吐能夠達到 50MB/s~70MB/s。在 BookKeeper,能夠經過配置 Ledger 的 Ensemble Size, Write Quorum Size 和 Ack Quorum Size,經過 Stripping 寫的方式來提升 Ledger 的吞吐。好比,設置 Ensemble Size 爲 6, Write Quorum Size 爲 3, Ack Quorum Size 爲 2。那麼吞吐量能夠提升到 2 倍。這是 Ledger 內的 Scalability。

    九、 Failover 到其餘 Proxy Server 時,如何繼續產生遞增的 Entry ID?
    在 failover 到其餘 Proxy Server 時,DistributedLog 並不會複用上一個 Proxy Server 的 ledger。因此 failover 以後,它會關閉上個 Proxy Server 寫的 ledger,而後從新開一個 ledger 進行寫入。遞增的 Entry ID 是基於當前 ledger 生成的。從整個日誌的角度來看,<ledger id, entry id> 構成了 unique 的記錄 ID。若是對於 consensus 算法有所瞭解,可能會知道 `epoch` 的概念。每一個 epoch 會有一個 designated 的 leader。而在 DistributedLog 中,`ledger id` 其實扮演着 `epoch` 的概念。
    ————————————————
    版權聲明:本文爲CSDN博主「高可用架構」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處連接及本聲明。
    原文連接:https://blog.csdn.net/weixin_45583158/article/details/100142918

     


    顏國平/1.2 騰訊基於用戶畫像大數據的電商防刷架構.16
    1.2.1 背景介紹16
    1.2.2 黑產現狀介紹16
    1.2.3 騰訊內部防刷架構18
    1.2.4 騰訊大數據收集維度.20
    1.2.5 騰訊大數據處理平臺——魔方21
    1.2.6 疑問與解惑.24

     

     

     

     

     
     

    二、矩陣式邏輯框架

     

    咱們以黑分類器爲例來剖析下分類器的整個邏輯框架。

     

    總的來說咱們採用了矩陣式的邏輯框架,最開始的黑分類器咱們也是一把抓,隨意的創建一個個針對黑產的檢測規則、模型。

     

    結果發現不是這個邏輯漏過了,而是那個邏輯誤傷量大,要對那一類的帳號增強安全打擊力度,改動起來也很是麻煩。

     

    所以咱們就設計了這個一個矩陣式的框架來解決上述問題。

     

    矩陣的橫向採用了Adaboost方法,該方法是一種迭代算法,其核心思想是針對同一個訓練集訓練不一樣的弱分類器,而後把這些分類器集合起來,構成一個最終的分類器。

     

    而咱們這裏每個弱分類器都只能解決一種賬號類型的安全風險判斷,集中起來才能解決全部帳戶的風險檢測。

     

    那麼在工程實踐上帶來三個好處:

     

    1. 便於實現輕重分離,好比某平臺虛假帳號集中在郵箱帳號,策略就能夠加大對郵箱帳號的打擊力度,影響範圍也侷限在郵箱賬號,而不是該平臺全部的帳號。

    2. 減小模型訓練的難度,模型訓練最大的難度在於樣本的均衡性問題,拆分紅子問題,就不須要考慮不一樣帳號類型之間的數據配比、均衡性問題,大大下降了模型訓練時正負樣本比率的問題。

    3. 邏輯的健壯性,某一個分類器的訓練出現了問題,受影響的範圍不至於擴展到全局。

     

    矩陣縱向採用了Bagging方法,該方法是一種用來提升學習算法準確度的方法,該方法在同一個訓練集合上構造預測函數系列,而後以必定的方法將他們組合成一個預測函數,從而來提升預測結果的準確性。

     


    王淵命/1.3 如何設計相似微信的多終端數據同步協議:Grouk 實踐分享.26
    1.3.1 移動互聯網時代多終端數據同步面臨的挑戰26
    1.3.2 多終端數據同步與傳統消息投遞協議的差別27
    1.3.3 Grouk 在多終端數據同步協議上的探索實踐.28
    1.3.4 疑問與解惑.32
    周 洋/1.4 如何實現支持數億用戶的長連消息系統:Golang 高併發案例33
    1.4.1 關於push 系統對比與性能指標的討論.33
    1.4.2 消息系統架構介紹35
    1.4.3 哪些因素決定推送系統的效果37
    1.4.4 GO 語言開發問題與解決方案.38
    1.4.5 消息系統的運維及測試41
    1.4.6 疑問與解惑.42

    360消息系統介紹

     

    360消息系統更確切的說是長鏈接push系統,目前服務於360內部多個產品,開發平臺數千款app,也支持部分聊天業務場景,單通道多app複用,支持上行數據,提供接入方不一樣粒度的上行數據和用戶狀態回調服務。

     

    目前整個系統按不一樣業務分紅9個功能完整的集羣,部署在多個idc上(每一個集羣覆蓋不一樣的idc),實時在線數億量級。一般狀況下,pc,手機,甚至是智能硬件上的360產品的push消息,基本上是從咱們系統發出的。

     

    關於push系統對比與性能指標的討論

     

    不少同行比較關心go語言在實現push系統上的性能問題,單機性能究竟如何,可否和其餘語言實現的相似系統作對比麼?甚至問若是是創業,第三方雲推送平臺,推薦哪一個?

     

    其實各大廠都有相似的push系統,市場上也有相似功能的雲服務。包括咱們公司早期也有erlang,nodejs實現的相似系統,也一度被公司要求作相似的對比測試。我感受在討論對比數據的時候,很難保證你們環境和需求的統一,我只能說下我這裏的體會,數據是有的,但這個數據前面估計會有不少定語~

     

    第一個重要指標:單機的鏈接數指標

     

    作過長鏈接的同行,應該有體會,若是在穩定鏈接狀況下,鏈接數這個指標,在沒有網絡吞吐狀況下對比,其實意義每每不大,維持鏈接消耗cpu資源很小,每條鏈接tcp協議棧會佔約4k的內存開銷,系統參數調整後,咱們單機測試數據,最高也是能夠達到單實例300w長鏈接。但作更高的測試,我我的感受意義不大。

     

    由於實際網絡環境下,單實例300w長鏈接,從理論上算壓力就很大:實際弱網絡環境下,移動客戶端的斷線率很高,假設每秒有1000分之一的用戶斷線重連。300w長鏈接,每秒新建鏈接達到3w,這同時連入的3w用戶,要進行註冊,加載離線存儲等對內rpc調用,另外300w長鏈接的用戶心跳須要維持,假設心跳300s一次,心跳包每秒須要1w tps。單播和多播數據的轉發,廣播數據的轉發,自己也要響應內部的rpc調用,300w長鏈接狀況下,gc帶來的壓力,內部接口的響應延遲可否穩定保障。這些集中在一個實例中,可用性是一個挑戰。因此線上單實例不會hold很高的長鏈接,實際狀況也要根據接入客戶端網絡情況來決定

     

    第二個重要指標:消息系統的內存使用量指標

     

    這一點上,使用go語言狀況下,因爲協程的緣由,會有一部分額外開銷。可是要作兩個推送系統的對比,也有些須要肯定問題。好比系統從設計上是否須要全雙工(即讀寫是否須要同時進行)若是半雙工,理論上對一個用戶的鏈接只須要使用一個協程便可(這種狀況下,對用戶的斷線檢測可能會有延時),若是是全雙工,那讀/寫各一個協程。兩種場景內存開銷是有區別的。

     

    另外測試數據的大小每每決定咱們對鏈接上設置的讀寫buffer是多大,是全局複用的,仍是每一個鏈接上獨享的,仍是動態申請的。另外是否全雙工也決定buffer怎麼開。不一樣的策略,可能在不一樣狀況的測試中表現不同。

     

    第三個重要指標:每秒消息下發量

     

    這一點上,也要看咱們對消息到達的QoS級別(回覆ack策略區別),另外看架構策略,每種策略有其更適用的場景,是純粹推?仍是推拉結合?甚至是否開啓了消息日誌?日誌庫的實現機制、以及緩衝開多大?flush策略……這些都影響整個系統的吞吐量。

     

    另外爲了HA,增長了內部通訊成本,爲了不一些小几率事件,提供閃斷補償策略,這些都要考慮進去。若是全部的都去掉,那就是比較基礎庫的性能了。

     

    因此我只能給出大概數據,24核,64G的服務器上,在QoS爲message at least,純粹推,消息體256B~1kB狀況下,單個實例100w實際用戶(200w+)協程,峯值能夠達到2~5w的QPS...內存能夠穩定在25G左右,gc時間在200~800ms左右(還有優化空間)。

     

    咱們正常線上單實例用戶控制在80w之內,單機最多兩個實例。事實上,整個系統在推送的需求上,對高峯的輸出不是提速,每每是進行限速,以防push系統瞬時的高吞吐量,轉化成對接入方業務服務器的ddos攻擊因此對於性能上,我感受你們能夠放心使用,至少在咱們這個量級上,經受過考驗,go1.5到來後,確實有以前投資又增值了的感受。

     

    關於推送的服務端架構

     

    常見的推送模型有長輪訓拉取,服務端直接推送(360消息系統目前主要是這種),推拉結合(推送只發通知,推送後根據通知去拉取消息).

     

    拉取的方式不說了,如今並不經常使用了,早期不少是nginx+lua+redis,長輪訓,主要問題是開銷比較大,時效性也很差,能作的優化策略很少。

     

    直接推送的系統,目前就是360消息系統這種,消息類型是消耗型的,而且對於同一個用戶並不容許重複消耗,若是須要多終端重複消耗,須要抽象成不一樣用戶。

     

    推的好處是實時性好,開銷小,直接將消息下發給客戶端,不須要客戶端走從接入層到存儲層主動拉取.

     

    但純推送模型,有個很大問題,因爲系統是異步的,他的時序性沒法精確保證。這對於push需求來講是夠用的,但若是複用推送系統作im類型通訊,可能並不合適。

     

    對於嚴格要求時序性,消息能夠重複消耗的系統,目前也都是走推拉結合的模型,就是隻使用咱們的推送系統發通知,並附帶id等給客戶端作拉取的判斷策略,客戶端根據推送的key,主動從業務服務器拉取消息。而且當主從同步延遲的時候,跟進推送的key作延遲拉取策略。同時也能夠經過消息自己的QoS,作純粹的推送策略,好比一些「正在打字的」低優先級消息,不須要主動拉取了,經過推送直接消耗掉。

     

    哪些因素決定推送系統的效果?

    首先是sdk的完善程度,sdk策略和細節完善度,每每決定了弱網絡環境下最終推送質量.

     

    SDK選路策略,最基本的一些策略以下:有些開源服務可能會針對用戶hash一個該接入區域的固定ip,實際上在國內環境下不可行,最好分配器(dispatcher)是返回散列的一組,並且端口也要參開,必要時候,客戶端告知是retry多組都連不上,返回不一樣idc的服務器。由於咱們會常常檢測到一些case,同一地區的不一樣用戶,可能對同一idc內的不一樣ip連通性都不同,也出現過同一ip不一樣端口連通性不一樣,因此用戶的選路策略必定要靈活,策略要足夠完善.另外在選路過程當中,客戶端要對不一樣網絡狀況下的長鏈接ip作緩存,當網絡環境切換時候(wifi、2G、3G),從新請求分配器,緩存不一樣網絡環境的長鏈接ip。

     
     

    客戶端對於數據心跳和讀寫超時設置,完善斷線檢測重連機制

     

    針對不一樣網絡環境,或者客戶端自己消息的活躍程度,心跳要自適應的進行調整並與服務端協商,來保證鏈路的連通性。而且在弱網絡環境下,除了網絡切換(wifi切3G)或者讀寫出錯狀況,何時從新創建鏈路也是一個問題。客戶端發出的ping包,不一樣網絡下,多久沒有獲得響應,認爲網絡出現問題,從新創建鏈路須要有個權衡。另外對於不一樣網絡環境下,讀取不一樣的消息長度,也要有不一樣的容忍時間,不能一刀切。好的心跳和讀寫超時設置,可讓客戶端最快的檢測到網絡問題,從新創建鏈路,同時在網絡抖動狀況下也能完成大數據傳輸。

     

    幾個大概重要組件介紹以下:

     

    dispatcher service 根據客戶端請求信息,將應網絡和區域的長鏈接服務器的,一組IP傳送給客戶端。客戶端根據返回的IP,創建長鏈接,鏈接Room service.

     

    room Service,長鏈接網關,hold用戶鏈接,並將用戶註冊進register service,自己也作一些接入安全策略、白名單、IP限制等。

     

    register service 是咱們全局session存儲組件,存儲和索引用戶的相關信息,以供獲取和查詢。

     

    coordinator service 用來轉發用戶的上行數據,包括接入方訂閱的用戶狀態信息的回調,另外作須要協調各個組件的異步操做,好比kick用戶操做,須要從register拿出其餘用戶作異步操做.

     

    saver service是存儲訪問層,承擔了對redis和mysql的操做,另外也提供部分業務邏輯相關的內存緩存,好比廣播信息的加載能夠在saver中進行緩存。另一些策略,好比客戶端sdk因爲被惡意或者意外修改,每次加載了消息,不回覆ack,那服務端就不會刪除消息,消息就會被反覆加載,造成死循環,能夠經過在saver中作策略和判斷。(客戶端老是不可信的)。

     

    center service 提供給接入方的內部api服務器,好比單播或者廣播接口,狀態查詢接口等一系列api,包括運維和管理的api。

     

    舉兩個常見例子,瞭解工做機制:好比發一條單播給一個用戶,center先請求Register獲取這個用戶以前註冊的鏈接通道標識、room實例地址,經過room service下發給長鏈接Center Service比較重的工做如全網廣播,須要把全部的任務分解成一系列的子任務,分發給全部center,而後在全部的子任務裏,分別獲取在線和離線的全部用戶,再批量推到Room Service。一般整個集羣在那一瞬間壓力很大。

     

    deployd/agent service 用於部署管理各個進程,收集各組件的狀態和信息,zookeeper和keeper用於整個系統的配置文件管理和簡單調度

     

    結合服務端作策略

     

    另外系統可能結合服務端作一些特殊的策略,好比咱們在選路時候,咱們會將同一個用戶儘可能映射到同一個roomservice實例上。斷線時,客戶端儘可能對上次鏈接成功的地址進行重試。主要是方便服務端作閃斷狀況下策略,會暫存用戶閃斷時實例上的信息,從新連入的時候,作單實例內的遷移,減小延時與加載開銷.

     

    客戶端保活策略

     

    不少創業公司願意從新搭建一套push系統,確實不難實現,其實在協議完備狀況下(最簡單就是客戶端不回ack不清數據),服務端會保證消息是不丟的。但問題是爲何在消息有效期內,到達率上不去?每每由於本身app的pushservice存活能力不高。選用雲平臺或者大廠的,每每sdk會作一些保活策略,好比和其餘app共生,互相喚醒,這也是雲平臺的pushservice更有保障緣由。我相信不少雲平臺旗下的sdk,多個使用一樣sdk的app,爲了實現服務存活,是能夠互相喚醒和保證活躍的。另外如今push sdk自己是單鏈接,多app複用的,這爲sdk實現,增長了新的挑戰。

     

    綜上,對我來講,選擇推送平臺,優先會考慮客戶端sdk的完善程度。對於服務端,選擇條件稍微簡單,要求部署接入點(IDC)越要多,配合精細的選路策略,效果越有保證,至於想知道哪些雲服務有多少點,這個羣裏來自各地的小夥伴們,能夠合夥測測。

     
     

    當時出現問題,如今總結起來,大概如下幾點

     

    1.散落在協程裏的I/O,Buffer和對象不復用。

     

    當時(12年)因爲對go的gc效率理解有限,比較奔放,程序裏大量short live的協程,對內通訊的不少io操做,因爲不想阻塞主循環邏輯或者須要及時響應的邏輯,經過單獨go協程來實現異步。這回會gc帶來不少負擔。

    針對這個問題,應儘可能控制協程建立,對於長鏈接這種應用,自己已經有幾百萬併發協程狀況下,不少狀況不必在各個併發協程內部作異步io,由於程序的並行度是有限,理論上作協程內作阻塞操做是沒問題。

    若是有些須要異步執行,好比若是不異步執行,影響對用戶心跳或者等待response沒法響應,最好經過一個任務池,和一組常駐協程,來消耗,處理結果,經過channel再傳回調用方。使用任務池還有額外的好處,能夠對請求進行打包處理,提升吞吐量,而且能夠加入控量策略.

     

    2.網絡環境很差引發激增

     

    go協程相比較以往高併發程序,若是作很差流控,會引發協程數量激增。早期的時候也會發現,時不時有部分主機內存會遠遠大於其餘服務器,但發現時候,全部主要profiling參數都正常了。

     

    後來發現,通訊較多系統中,網絡抖動阻塞是不可免的(即便是內網),對外不停accept接受新請求,但執行過程當中,因爲對內通訊阻塞,大量協程被建立,業務協程等待通訊結果沒有釋放,每每瞬時會迎來協程暴漲。但這些內存在系統穩定後,virt和res都並沒能完全釋放,降低後,維持高位。

     

    處理這種狀況,須要增長一些流控策略,流控策略能夠選擇在rpc庫來作,或者上面說的任務池來作,其實我感受放在任務池裏作更合理些,畢竟rpc通訊庫能夠作讀寫數據的限流,但它並不清楚具體的限流策略,究竟是重試仍是日誌仍是緩存到指定隊列。任務池自己就是業務邏輯相關的,它清楚針對不一樣的接口須要的流控限制策略。

     

    3.低效和開銷大的rpc框架

     

    早期rpc通訊框架比較簡單,對內通訊時候使用的也是短鏈接。這原本短鏈接開銷和性能瓶頸超出咱們預期,短鏈接io效率是低一些,但端口資源夠,自己吞吐能夠知足須要,用是沒問題的,不少分層的系統,也有http短鏈接對內進行請求的

     

    但早期go版本,這樣寫程序,在必定量級狀況,是支撐不住的。短鏈接大量臨時對象和臨時buffer建立,在本已經百萬協程的程序中,是沒法承受的。因此後續咱們對咱們的rpc框架做了兩次調整。

     

    第二版的rpc框架,使用了鏈接池,經過長鏈接對內進行通訊(複用的資源包括client和server的:編解碼Buffer、Request/response),大大改善了性能。

     

    但這種在一次request和response仍是佔用鏈接的,若是網絡情況ok狀況下,這不是問題,足夠知足須要了,但試想一個room實例要與後面的數百個的register,coordinator,saver,center,keeper實例進行通訊,須要創建大量的常駐鏈接,每一個目標機幾十個鏈接,也有數千個鏈接被佔用。

     

    非持續抖動時候(持續逗開多少無解),或者有延遲較高的請求時候,若是針對目標ip鏈接開少了,會有瞬時大量請求阻塞,鏈接沒法獲得充分利用。第三版增長了Pipeline操做,Pipeline會帶來一些額外的開銷,利用tcp的全雙特性,以儘可能少的鏈接完成對各個服務集羣的rpc調用。

     

    4.Gc時間過長

     

    Go的Gc仍舊在持續改善中,大量對象和buffer建立,仍舊會給gc帶來很大負擔,尤爲一個佔用了25G左右的程序。以前go team的大咖郵件也告知咱們,將來會讓使用協程的成本更低,理論上不須要在應用層作更多的策略來緩解gc.

     

    改善方式,一種是多實例的拆分,若是公司沒有端口限制,能夠很快部署大量實例,減小gc時長,最直接方法。不過對於360來講,外網一般只能使用80和433。所以常規上只能開啓兩個實例。固然不少人給我建議可否使用SO_REUSEPORT,不過咱們內核版本確實比較低,並無實踐過。

     

    另外可否模仿nginx,fork多個進程監控一樣端口,至少咱們目前沒有這樣作,主要對於咱們目前進程管理上,仍是獨立的運行的,對外監聽不一樣端口程序,還有配套的內部通訊和管理端口,實例管理和升級上要作調整。

     

    解決gc的另兩個手段,是內存池和對象池,不過最好作仔細評估和測試,內存池、對象池使用,也須要對於代碼可讀性與總體效率進行權衡。

     

    這種程序必定狀況下會下降並行度,由於用池內資源必定要加互斥鎖或者原子操做作CAS,一般原子操做實測要更快一些。CAS能夠理解爲可操做的更細行爲粒度的鎖(能夠作更多CAS策略,放棄運行,防止忙等)。這種方式帶來的問題是,程序的可讀性會愈來愈像C語言,每次要malloc,各地方用完後要free,對於對象池free以前要reset,我曾經在應用層嘗試作了一個分層次結構的「無鎖隊列」

    上圖左邊的數組其實是一個列表,這個列表按大小將內存分塊,而後使用atomic操做進行CAS。但實際要看測試數據了,池技術能夠明顯減小臨時對象和內存的申請和釋放,gc時間會減小,但加鎖帶來的並行度的下降,是否能給一段時間內的總體吞吐量帶來提高,要作測試和權衡…

     

    在咱們消息系統,實際上後續去除了部分這種黑科技,試想在百萬個協程裏面作自旋操做申請複用的buffer和對象,開銷會很大,尤爲在協程對線程多對多模型狀況下,更依賴於golang自己調度策略,除非我對池增長更多的策略處理,減小忙等,感受是在把runtime作的事情,在應用層很是不優雅的實現。廣泛使用開銷理論就大於收益。

     

    但對於rpc庫或者codec庫,任務池內部,這些開定量協程,集中處理數據的區域,能夠嘗試改造~

     

    對於有些固定對象複用,好比固定的心跳包什麼的,能夠考慮使用全局一些對象,進行復用,針對應用層數據,具體設計對象池,在部分環節去複用,可能比這種無差異的設計一個通用池更能進行效果評估.

    消息系統的運維及測試

    下面介紹消息系統的架構迭代和一些迭代經驗,因爲以前在其餘地方有過度享,後面的會給出相關連接,下面實際作個簡單介紹,感興趣能夠去連接裏面看

     

    架構迭代~根據業務和集羣的拆分,能解決部分灰度部署上線測試,減小點對點通訊和廣播通訊不一樣產品的相互影響,針對特定的功能作獨立的優化.

     

    消息系統架構和集羣拆分,最基本的是拆分多實例,其次是按照業務類型對資源佔用狀況分類,按用戶接入網絡和對idc布點要求分類(目前沒有條件,全部的產品都部署到所有idc)

     


    唐福林/1.5 雪球在股市風暴下的高可用架構改造分享.46
    1.5.1 雪球公司的介紹46
    1.5.2 雪球當前整體架構47
    1.5.3 雪球架構優化歷程48
    1.5.4 關於架構優化的總結和感想.53
    1.5.5 疑問與解惑.54

    四. 聊聊關於架構優化的一些總結和感想

     

    在各類場合常常據說的架構優化,通常都是優化某一個具體的業務模塊,將性能優化到極致。而在雪球,咱們作的架構優化更多的是從問題出發,解決實際問題,解決到能夠接受的程度便可。可能你們看起來會以爲很凌亂,並且每一個事情單獨拎出來好像都不是什麼大事。

     

    咱們在對一個大服務作架構優化時,通常是往深刻的本質進行挖掘;當咱們面對一堆架構各異的小服務時,「架構優化」的含義實際上是有一些不同的。大部分時候,咱們並不須要(也沒有辦法)深刻到小服務的最底層進行優化,而是去掉或者優化原來明顯不合理的地方就能夠了。

     

    在快速迭代的創業公司,咱們可能不會針對某一個服務作很完善的架構設計和代碼實現,當出現各類問題時,也不會去追求極致的優化,而是以解決瓶頸問題爲先

     

    即便咱們經歷過一回將 snowball 拆分服務化的過程,但當咱們從新上一個新的業務時,咱們依然選擇將它作成一個大一統的服務。只是這一次,咱們會提早定義好每一個模塊的 service 接口,爲之後可能的服務化鋪好路。

     

    在創業公司裏,重寫是不能接受的;大的重構,從時間和人力投入上看,通常也是沒法承擔的。而「裱糊匠」式作法,哪裏有性能問題就加機器,加緩存,加數據庫,有可用性問題就加劇試,加log,出故障就加流程,加測試,這也不是雪球團隊工做方式。咱們通常都採用最小改動的方式,即,準肯定義問題,定位問題根源,找到問題本質,制定最佳方案,以最小的改動代價,將問題解決到可接受的範圍內

     

    咱們如今正在全部的地方強推3個數據指標:qps,p99,error rate。每一個技術人員對本身負責的服務,必定要有最基本的數據指標意識。數字,是發現問題,定位根源,找到本質的最重要的依賴條件。沒有之一。

     

    咱們的原則:保持技術棧的一致性和簡單性,有節制的嘗試新技術,保持全部線上服務依賴的技術可控,簡單來講,能 hold 住

    能用cache的地方毫不用db,能異步的地方,毫不同步。俗稱的:吃一塹,長一智。

     

    特事特辦:業務在發展,需求在變化,實現方式也須要跟着變化。簡單的來講:遺留系統的優化,最佳方案就是砍需求,呵呵

    當前,雪球內部正在推行每一個模塊的方案和代碼實現的 review,在 review 過程當中,我通常是這樣要求的:

     

    技術方案:

     

    • 20倍設計,10倍實現,3倍部署

    • 擴展性:凡事留一線,之後好相見

     

    技術實現:

     

    • DevOps:上線後仍是你本身維護的項目,實現的時候記得考慮各類出錯的處理

    • 用戶投訴的時候須要你去解釋,實現的時候注意各類邊界和異常

    • 快速實現,不是「隨便實現」,萬一火了呢:性能,方便擴容

     
       

    麥俊生/1.6 億級短視頻社交美拍架構實戰591.6.1 短視頻市場的發展591.6.2 美拍的發展.601.6.3 短視頻所面臨的架構問題611.6.4 爲支持億級用戶,美拍架構所作的一些改進621.6.5 後續發展68劉道儒/1.7 微博「異地多活」部署經驗談691.7.1 微博異地多活建設歷程691.7.2 微博異地多活面臨的挑戰701.7.3 異地多活的最佳實踐.731.7.4 異地多活的新方向74孫宇聰/1.8 來自Google 的高可用架構理念與實踐751.8.1 決定可用性的兩大因素761.8.2 高可用性方案771.8.3 可用性7 級圖表801.8.4 疑問與解惑.81那 誰/1.9 深刻理解同步/異步與阻塞/非阻塞區別841.9.1 同步與異步.841.9.2 阻塞與非阻塞851.9.3 與多路複用I/O 的聯繫86第2 章 高可用架構原理與分佈式實踐.88黃東旭/2.1 Codis 做者細說分佈式Redis 架構設計882.1.1 Redis、Redis Cluster 和Codis882.1.2 咱們更愛一致性902.1.3 Codis 在生產環境中的使用經驗和坑912.1.4 分佈式數據庫和分佈式架構.942.1.5 疑問與解惑.95霍泰穩/2.2 給你介紹一個不同的硅谷.982.2.1 Uber .982.2.2 Coursera.992.2.3 Airbnb1022.2.4 硅谷行帶給個人一些影響1062.2.5 疑問與解惑106金自翔/2.3 解耦的藝術——大型互聯網業務系統的插件化改造1102.3.1 插件化.1102.3.2 如何處理用戶交互1152.3.3 如何處理數據.1152.3.4 總結116沈 劍/2.4 從零開始搭建高可用IM 系統1172.4.1 什麼是IM1172.4.2 協議設計1182.4.3 WEB 聊天室.1222.4.4 IM 典型業務場景1262.4.5 疑問與解惑126陳宗志/2.5 360 分佈式存儲系統Bada 的架構設計和應用.1292.5.1 主要應用場景.1292.5.2 總體架構1302.5.3 主要模塊1312.5.4 數據分佈策略.1322.5.5 請求流程1332.5.6 多機房架構1342.5.7 FAQ1382.5.8 疑問與解惑139張 亮/2.6 新一代分佈式任務調度框架:噹噹Elastic-Job 開源項目的10 項特性1432.6.1 爲何須要做業(定時任務).1432.6.2 噹噹以前使用的做業系統1442.6.3 Elastic-Job 的來歷.1442.6.4 Elastic-Job 包含的功能1452.6.5 Elastic-Job 的部署和使用.1462.6.6 對開源產品的開發理念.1472.6.7 將來展望1482.6.8 疑問與解惑149付海軍/2.7 互聯網DSP 廣告系統架構及關鍵技術解析1522.7.1 優秀DSP 系統的特色1522.7.2 程序化購買的特色1532.7.3 在線廣告的核心問題1562.7.4 在線廣告的挑戰.1562.7.5 DSP 系統架構.1572.7.6 RTB 投放引擎的架構.1582.7.7 DMP1602.7.8 廣告系統DMP 數據處理的架構.1602.7.9 用戶畫像的方法.1622.7.10 廣告行業的反做弊.1652.7.11 P2P 流量互刷1662.7.12 CPS 引流做弊1672.7.13 疑問與解惑168王衛華/2.8 億級規模的Elasticsearch 優化實戰1702.8.1 索引性能(Index Performance) .1702.8.2 查詢性能(Query Perofrmance) 1712.8.3 其餘1732.8.4 疑問與解惑174楊衛華/2.9 微博分佈式存儲考試題:案例講解及做業精選1792.9.1 訪問場景1792.9.2 設計1802.9.3 sharding 策略1802.9.4 案例精選181李 凱/2.10 架構師須要瞭解的Paxos 原理、歷程及實戰.1842.10.1 數據庫高可用性難題1842.10.2 Paxos 協議簡單回顧.1852.10.3 Basic Paxos 同步日誌的理論模型1862.10.4 Multi Paxos 的實際應用.1872.10.5 依賴時鐘偏差的變種Paxos 選主協議簡單分析1902.10.6 疑問與解惑191溫 銘/2.11 OpenResty 的如今和將來1932.11.1 OpenResty 是什麼,適合什麼場景下使用.1932.11.2 某安全公司服務端技術選型的標準1942.11.3 如何在項目中引入新技術.1962.11.4 如何入門以及學習的正確方法1972.11.5 OpenResty 中的測試和調試.1992.11.6 NginScript 是否會替代OpenResty2012.11.7 將來重點解決的問題和新增特性.2022.11.8 開源社區建設2032.11.9 疑問與解惑.203第3 章 電商架構熱點專題.205張開濤/3.1 億級商品詳情頁架構演進技術解密.2053.1.1 商品詳情頁2053.1.2 商品詳情頁發展史2093.1.3 遇到的一些問題和解決方案2203.1.4 總結2283.1.5 疑問與解惑229楊 超/3.2 大促系統全流量壓測及穩定性保證——京東交易架構.2323.2.1 交易系統的三個階段2323.2.2 交易系統的三層結構2333.2.3 交易系統的訪問特徵2343.2.4 應對大促的第1 步:全鏈路全流量線上壓測.2343.2.5 應對大促的第2 步:根據壓力錶現進行調優.2373.2.6 異步和異構2403.2.7 應對大促的第3 步:分流與限流2423.2.8 應對大促的第4 步:容災降級.2443.2.9 應對大促的第5 步:完善監控.2453.2.10 疑問與解惑246呂 毅/3.3 秒殺系統架構解密與防刷設計.2483.3.1 搶購業務介紹.2483.3.2 具體搶購項目中的設計.2493.3.3 如何解耦先後端壓力2503.3.4 如何保證商品庫的庫存可靠2523.3.5 如何與第三方多方對帳.2543.3.6 項目總結2553.3.7 疑問與解惑255王富平/3.4 Lambda 架構與推薦在電商網站實踐.2573.4.1 Lambda 架構2573.4.2 1 號店推薦系統實踐2603.4.3 Lambda 的將來2623.4.4 思考2633.4.5 疑問與解惑263楊 碩/3.5 某公司線上真實流量壓測工具構建.2653.5.1 爲何要開發一個通用的壓測工具2653.5.2 常見的壓測工具.2663.5.3 構建本身的壓測工具2663.5.4 疑問與解惑271第4 章 容器與雲計算.273陳 飛/4.1 微博基於Docker 容器的混合雲遷移實戰.2734.1.1 爲何要採用混合雲的架構2734.1.2 跨雲的資源管理與調度.2754.1.3 容器的編排與服務發現.2784.1.4 混合雲監控體系.2844.1.5 前進路上遇到的那些坑.2864.1.6 疑問與解惑286高 磊/4.2 互聯網金融創業公司Docker 實踐2874.2.1 背景介紹2874.2.2 容器選型2874.2.3 應用遷移2884.2.4 彈性擴容2914.2.5 將來規劃2954.2.6 疑問與解惑295高永超/4.3 使用開源Calico 構建Docker 多租戶網絡.2974.3.1 PaaS 平臺的網絡需求.2974.3.2 使用Calico 實現Docker 的跨服務器通信.2984.3.3 利用Profile 實現ACL3014.3.4 性能測試3064.3.5 Calico 的發展3084.3.6 疑問與解惑309彭哲夫/4.4 解析Docker 在芒果TV 的實踐之路3104.4.1 豆瓣時期3104.4.2 芒果TV 的Nebulium Engine .3114.4.3 Project Eru .3124.4.4 細節3134.4.5 網絡3144.4.6 存儲3154.4.7 Scale3164.4.8 資源分配和集羣調度3164.4.9 服務發現和安全.3174.4.10 實例3174.4.11 總結3184.4.12 疑問與解惑318王關勝/4.5 微博基於Docker 的混合雲平臺設計與實踐3234.5.1 微博的業務場景及混合雲背景.3234.5.2 三大基礎設施助力微博混合雲.3264.5.3 微博混合雲DCP 系統設計核心:自動化、彈性調度3284.5.4 引入阿里雲做爲第3 機房,實現彈性調度架構3304.5.5 大規模集羣操做自動化.3314.5.6 不怕峯值事件.332第5 章 運維保障333王 康/5.1 360 如何用QConf 搞定兩萬以上服務器的配置管理.3335.1.1 設計初衷3335.1.2 總體認識3345.1.3 架構介紹3355.1.4 QConf 服務端3365.1.5 QConf 客戶端3365.1.6 QConf 管理端3405.1.7 其餘3415.1.8 疑問與解惑343尤 勇/5.2 深度剖析開源分佈式監控CAT3475.2.1 背景介紹3475.2.2 總體設計3485.2.3 客戶端設計3495.2.4 服務端設計3525.2.5 總結感悟357楊尚剛/5.3 單表60 億記錄等大數據場景的MySQL 優化和運維之道3595.3.1 前言3595.3.2 數據庫開發規範.3605.3.3 數據庫運維規範.3635.3.4 性能優化3685.3.5 疑問與解惑375秦 迪/5.4 微博在大規模、高負載系統問題排查方法3795.4.1 背景3795.4.2 排查方法及線索.3795.4.3 總結3845.4.4 疑問與解惑385秦 迪/5.5 系統運維之爲何每一個團隊存在大量爛代碼3875.5.1 寫爛代碼很容易.3875.5.2 爛代碼終究是爛代碼3885.5.3 重構不是萬能藥.3925.5.4 寫好代碼很難.3935.5.5 悲觀的結語394秦 迪/5.6 系統運維之評價代碼優劣的方法3955.6.1 什麼是好代碼.3955.6.2 結語4035.6.3 參考閱讀403秦 迪/5.7 系統運維之如何應對爛代碼4045.7.1 改善可維護性.4045.7.2 改善性能與健壯性4095.7.3 改善生存環境.4125.7.4 我的感想414第6 章 大數據與數據庫415王 勁/6.1 某音樂公司的大數據實踐.4156.1.1 什麼是大數據.4156.1.2 某音樂公司大數據技術架構4186.1.3 在大數據平臺重構過程當中踩過的坑4256.1.4 後續的持續改進.430王新春/6.2 實時計算在點評.4316.2.1 實時計算在點評的使用場景4316.2.2 實時計算在業界的使用場景4326.2.3 點評如何構建實時計算平臺4336.2.4 Storm 基礎知識簡單介紹.4346.2.5 如何保證業務運行的可靠性4366.2.6 Storm 使用經驗分享4386.2.7 關於計算框架的後續想法4426.2.8 疑問與解惑442王衛華/6.3 百姓網Elasticsearch 2.x 升級之路.4466.3.1 Elasticsearch 2.x 變化4466.3.2 升級之路4486.3.3 優化或建議4516.3.4 百姓之道4526.3.5 後話:Elasticsearch 5.04536.3.6 升級2.x 版本成功,5.x 版本還會遠嗎454董西成 張虔熙/6.4 Hadoop、HBase 年度回顧4576.4.1 Hadoop 2015 技術發展4576.4.2 HBase 2015 年技術發展4606.4.3 疑問與解惑466常 雷/6.5 解密Apache HAWQ——功能強大的SQL-on-Hadoop 引擎.4696.5.1 HAWQ 基本介紹4696.5.2 Apache HAWQ 系統架構.4726.5.3 HAWQ 中短時間規劃.4796.5.4 貢獻到Apache HAWQ 社區4796.5.5 疑問與解惑480蕭少聰/6.6 PostgresSQL HA 高可用架構實戰.4826.6.1 PostgreSQL 背景介紹.4826.6.2 在PostgreSQL 下如何實現數據複製技術的HA 高可用集羣4836.6.3 Corosync+Pacemaker MS 模式介紹4846.6.4 Corosync+Pacemaker M/S 環境配置4856.6.5 Corosync+Pacemaker HA 基礎配置4886.6.5 PostgreSQL Sync 模式當前的問題4926.6.6 疑問與解惑492王晶昱/6.7 從NoSQL 歷史看將來.4956.7.1 前言4956.7.2 1970 年:We have no SQL4966.7.3 1980 年:Know SQL 4976.7.4 2000 年:No SQL .5026.7.5 2005 年:不只僅是SQL 5046.7.6 2013 年:No,SQL .5056.7.7 阿里的技術選擇.5056.7.8 疑問與解惑506楊尚剛/6.8 MySQL 5.7 新特性大全和將來展望.5086.8.1 提升運維效率的特性5086.8.2 優化器Server 層改進.5116.8.3 InnoDB 層優化5136.8.4 將來發展5176.8.5 運維經驗總結.5186.8.6 疑問與解惑519譚 政/6.9 大數據盤點之Spark 篇5216.9.1 Spark 的特性以及功能5216.9.2 Spark 在Hulu 的實踐.5256.9.3 Spark 將來的發展趨勢5286.9.4 參考文章5306.9.5 疑問與解惑530蕭少聰/6.10 從Postgres 95 到PostgreSQL 9.5:新版亮眼特性5326.10.1 Postgres 95 介紹5326.10.2 PostgresSQL 版本發展歷史5336.10.3 PostgresSQL 9.5 的亮眼特性5346.10.4 PostgresSQL 還能夠作什麼5446.10.5 疑問與解惑547畢洪宇/6.11 MongoDB 2015 回顧:全新里程碑式的WiredTiger 存儲引擎5516.11.1 存儲引擎的發展5516.11.2 複製集改進.5556.11.3 自動分片機制5566.11.4 其餘新特性介紹5566.11.5 疑問與解惑.558王曉偉/6.12 基於Xapian 的垂直搜索引擎的構建分析5616.12.1 垂直搜索的應用場景5616.12.2 技術選型.5636.12.3 垂直搜索的引擎架構5646.12.4 垂直搜索技術和業務細節.5666.12.5 疑問與解惑568第7 章 安全與網絡572郭 偉/7.1 揭祕DDoS 防禦——騰訊雲大禹系統5727.1.1 有關DDoS 簡介的問答.5747.1.2 有關大禹系統簡介的問答5757.1.3 有關大禹系統硬件防禦能力的問答5767.1.4 有關算法設計的問答5777.1.5 大禹和其餘產品、技術的區別.578馮 磊 趙星宇/7.2 App 域名劫持之DNS 高可用——開源版HttpDNS 方案詳解5807.2.1 HttpDNSLib 庫組成.5817.2.2 HttpDNS 交互流程5827.2.3 代碼結構5837.2.4 開發過程當中的一些問題及應對.5867.2.5 疑問與解惑593馬 濤/7.3 CDN 對流媒體和應用分發的支持及優化5957.3.1 CDN 系統工做原理.5957.3.2 網絡分發過程當中ISP 的影響6027.3.3 防盜鏈.6037.3.4 內容分發系統的問題和應對思路6047.3.5 P2P 穿牆打洞6077.3.6 疑問與解惑609馬 濤/7.4 HTTPS 環境使用第三方CDN 的證書難題與最佳實踐611蔣海滔/7.5 互聯網主要安全威脅分析及應對方案6137.5.1 互聯網Web 應用面臨的主要威脅6137.5.2 威脅應對方案.6167.5.3 疑問與解惑624

相關文章
相關標籤/搜索