Apache Pulsar 技術系列 – 基於不同部署策略和配置策略的容災保障

語言: CN / TW / HK

導語 

Apache Pulsar 是一個多租户、高性能的服務間消息傳輸解決方案,支持多租户、低延時、讀寫分離、跨地域複製、快速擴容、靈活容錯等特性。其原生支持了跨洲際級別的跨地域複製的解決方案,並結合其自身的 Tenant 和 Namespace 級別的抽象,可以靈活的支持不多種類,不同場景下的跨地域複製解決方案。

需求背景

目前騰訊公司內部業務在使用 Pulsar 的過程中,綜合業務是否是在線影響用户體檢,是否產生營收影響,以及在降本增效趨勢下的成本考慮,會選擇不同級別的容災策略,下面從業務場景以及保障程度描述 Pulsar 以及客户端的容災部署和策略配置。

Pulsar 多副本機制以及強一致性

在一致性方面,Pulsar 採用 Quorum 算法,通過 Write Quorum 和 Ack Quorum 來保證分佈式消息隊列的副本數和強一致寫入的應答數(A>W/2)。在性能方面,Pulsar 採用 Pipeline 方式生產消息,通過順序寫和條帶化寫入降低磁盤 IO 壓力,多種緩存減少網絡請求加快消費效率。

1.png

另一方面,在單個 Bookie 寫入數據的時候可以配置強制刷盤寫 Journal 即 Wal.

這個 Journals 文件裏存儲的相當於 BookKeeper 的事務 Log 或者説是寫前 Log, 在任何針對 Ledger 的更新發生前,都會先將這個更新的描述信息持久化到這個 Journal 文件中。

Bookeeper 提供有單獨的 Sync 線程根據當前 Journal 文件的大小來作 Journal 文件的 Rolling;              

2.png

寫入的 EntryLog 和 Index 都是先緩存在內存中,再根據一定的條件週期性的 Flush 到磁盤,這就造成了從內存到持久化到磁盤的時間間隔,如果在這間隔內 BookKeeper 進程崩潰,在重啟後,我們需要根據 Journal 文件內容來恢復,這個 LastLogMark 就記錄了從 Journal 中什麼位置開始恢復;

運營實踐:

所以基於以上兩個特性,我們可以根據 Write Quorum 和 Ack Quorum,以及是否開啟寫 Journal 和是否同步異步寫 Journal 在成本和容災保障之間做一個合適的配置,目前線上在安全業務在數據量較大的情況下關閉了寫Journal,只有副本保障數據可靠性

機架感知策略

機架感知是 Ensemble Placement Policy(EPP)的一種,是 Bookkeeper Client 用來選擇 Ensemble 的算法,選擇的依據主要是依賴網絡拓撲屬性。

示例2:

Region A和B 有四個 Bookie, BK1 , BK2 , BK3 and BK4 ,它們的網絡位置是, Region-A/Rack-1/BK1 , /Region-A/Rack-1/BK2 , /Region-B/Rack-2/BK3 和 /Region-B/Rack-2/BK4 ,網絡拓撲結構如下:

              root

            /      \

      region-a      region-b

        |               |  

     rack-1          rack-2

      /   \            /     \

   bk1  bk2         bk3   bk4

RackawareEnsemblePlacementPolicy 會依賴 Rack 信息來從不同的 Rack 上選取 Bookie,可以保證 Write Quorum 至少包括兩個 Rack,這個策略要求網絡拓撲中至少包含兩個 Rack 信息。

運營實踐:

在支付和廣告場景中部署會將不同網絡分區的機器放在不同的 Rack 上面,例如深圳荔景、深圳深宇機器分配在 Rack-1、Rack-2,然後配置副本的 Write Quorum =Ack Quorum,這樣當其中一個例如深圳荔景網絡機房故障時,業務能繼續從深圳深宇生產消費數據,

這裏有兩點值得注意:

  1. Zookeeper 也需要跨3個可用區部署,至少兩個在深圳荔景、深圳深宇;
  2. 單個網絡分區需短暫支撐兩倍流量。

跨地域複製( GEO 模式)

Apache Pulsar 內置了多集羣跨地域複製的功能,GEO-Repliaaction 是指把分散在不同物理地域的集羣通過一定的配置方式讓其能在集羣之間進行數據的相互複製。

當前擁有兩個集羣,分別部署在北京和上海,當用户在北京的集羣中使用 Producer 發送數據時,首先會發送到北京機房的本地集羣中(Topic1)與此同時會去創建一個 Replication Cursor,用於專門複製數據的一個遊標,通過這個Cursor信息,你可以判斷當前數據究竟複製到哪一個階段。同時會去創建 Replication Producer,它會把數據從北京機房的 Topic1 中讀取數據,然後將數據寫到上海機房的 Topic1 中,上海機房的 Broker 收到 Producer 的請求之後,會寫到本地相同的 Topic 中來(Topic1)。此時如果上海機房的用户開啟 Consumer 去消費數據的話,會接收到由北京機房 Producer 生產的數據信息。

3.png

問題:

  1. Pulsar 只能保證單機房生產的消息順序,在多機房的場景下沒辦法保證多個機房的消息全局有序;

  2. 由於 Cursor Snapshot 是定期進行的,在時間上精確度不會太高,多少有些偏差。

運營實踐:

在廣告多份場景業務部署了深圳、上海、天津三地集羣,配置互相複製,業務一般從深圳寫入,上海、天津業務端本地消費,部分場景加工完寫回本地集羣,很好的解決了多份消費的時延問題。

MQ 運營過程中會發現一個非常棘手的問題是,如果一個業務滯後非常多,哪怕 Pulsar 是讀寫分離的,但是由於線程、內存等是共享的,大量的滯後讀還是要導致寫入時延變高,在非 SDD 盤變現更為明顯,這時候就可以用 GEO 模擬出多份數據,做到業務的隔離,讓那些不關心滯後的業務放在 GEO 的一個集羣,做到數據隔離。

業務雙寫,雙消費+跨地域複製(GEO模式)

在3中介紹了跨地域複製原理,但是實踐使用中業務有更高級別的容災要求,由於跨地域給地的寫入端還是隻有一個,如果在寫入過程中 Pulsar 集羣故障還是會導致業務寫入失敗,影響在線業務展示甚至影響公司營收,所以業務會採用雙寫和雙消費,每地部署兩個集羣。

4.png

運營實踐:

在廣告業務中,部署了兩套三地 GEO 集羣,在運管過程中,一套由於機器故障,或者業務滯後導致使用不當,完成不會影響業務的使用,這個過程業務寫入雖然可以失敗,但是消費端確是需要去重。

計費場景的版本及部署

計費場景為什麼需要單獨討論呢,因為同4廣告場景相比,廣告計費鏈路業務場景的計費特性強依賴消息隊列,不能跨城實時雙寫,避免曝光請求重複計費。而且計費業務需要每條消息都需要生產消費溯源,在對賬對不齊時,需要找到在那個過程中數據異常(沒消費,數據丟失)了,所以在計費版本 Pulsar 前面加入無狀態的生產消費代理 Proxy,各地會部署兩套以上集羣,在 Proxy 前面加上公司的l5,如果某個 Pulsar 集羣故障將l5中的節點關閉。

5.png

運營實踐:

目前計費業務實際中如上圖部署,當集羣故障時,將l5中集羣節點屏蔽,未消費的數據待集羣恢復時補錄數據,同時有 Tools 工具將數據備份到本地。

未來規劃

從上面4中我們可以看到,目前需要業務雙寫雙消費解決故障過程中集羣使用,會帶來幾個問題:

  1. 業務需要保障事務,下游需要去重;

  2. 雙寫雙消費業務客户端成本加倍.

平台側優化:

能不能所有容災都讓pulsar承擔,業務只是使用方完全不需要理會容災等,這是未來平台側一個巨大的挑戰

6.png

目前的一個比較清晰的方案大致是服務端側通過 GEO 將數據和消費 Cursor 在兩個集羣同步,同時 SDK 需要支持多個 Pulsar 集羣地址的切換,目前在2.10版本已經支持生產端 SDK 多集羣配置,但是消費端還不支持,而且 GEO 的數據同步和消費位點 Cursor 同步的失效性得也有待加強,這些將在新版本實現。