線上課堂百萬級消息如何實現穩定互動?

CKafka助力騰訊課堂,實現百萬級消息實現穩定互動算法

導語:疫情期間,爲了保障國內學子的正常學習進度,騰訊課堂積極響應國家「停工不停學」的號召,緊急上線疫情期間專用的「老師極速版」,使廣大師生足不出戶,便可快速便捷的完成線上開課。面對線上課堂百萬量級的互動消息,如何保證消息的實時性和準確性無疑是一個技術挑戰。那麼如何解決問題呢?接下來,就和小編一塊兒來看看騰訊雲中間件CKafka如何爲騰訊課堂百萬級消息提供技術支撐。segmentfault

背景

兩年前,騰訊在線教育部就在探索如何實現架構轉型。在梳理過騰訊課堂初始技術架構的痛點後,規劃出架構演進的三個重點方向:微服務、中間件、DevOps。尤爲在消息中間件的選取上,從自研Hippo消息隊列切換到雲CKafka。這主要歸於如下幾點緣由:後端

  • 實現技術棧的統一,下降組件適配成本。
  • 使用符合開源標準的組件,便於系統切換優秀的開源組件。
  • CKafka具有高性能、高可用性和高可靠性的特色:免除複雜的參數配置,提供專業的性能調優;磁盤高可靠,即便服務器壞盤50%也不影響業務;多副本備份,更有多可用區容災方案可選,零感知服務遷移。
  • CKafka提供安全的數據保障:提供鑑權與受權機制、主子帳號等功能,爲企業數據作好安全防禦。

在剛剛過去的2019年,騰訊在線教育部已全面實現了業務上雲,不只提高了團隊研發效率,還實現了快速交付。同時,CKafka在消息流處理上的高性能特色得以實踐驗證。安全

而如今,疫情當前,面對全國千萬師生同時在線的線上課堂,互動消息猛增至百萬級別,無疑對在線教育平臺的穩定性提出更高要求。爲了保證線上課堂廣大師生的穩定互動,CKafka做爲騰訊課堂的底層消息支撐,在消息的實時性和可靠性上提供了更優化的技術方案。服務器

騰訊課堂在線課程頁面微信

CKafka在騰訊課堂的實踐

Ckafka在騰訊課堂系統架構中的應用是很是典型的場景,即消息總線和業務解耦。使用了GB帶寬、TB存儲規格的實例。咱們先來看一下CKafka做爲消息總線在騰訊課堂的架構中所處的位置,以下圖:
session

從架構圖可知,CKafka處於消息管道的中心位置。同時接收多個消息源數據,等待下游組件的訂閱消費。並利用其自身高分佈式、高吞吐、高可靠的特性,實現流量削峯和業務解耦。騰訊課堂中的聊天消息、簽到、舉手、獻花、答題卡等功能都使用了該能力。架構

在線課堂的業務場景不容許出現如消息延遲、數據丟失等狀況,不然就會馬上被在線課堂的師生們感知業務的不穩定,形成不良的用戶體驗。咱們來假設一個場景:老師在課堂發佈一個問題,學生們舉手回答問題,若是老師發出的消息出現延時或丟失的狀況,學生們就不能收到消息,沒法及時給老師反饋問題答案,線上課堂的互動效果就會不好,嚴重影響課堂教學質量。併發

如何避免上述問題呢?咱們從CKafka保障消息的實時性和可靠性兩方面進行闡述。分佈式

消息的實時性

Apache Kafka架構上設計的底層數據讀寫和存儲是以分區爲最小單位進行的。首先來看一下Kafka Topic的生產消費模型。

如上圖所示,生產者將數據寫入到分佈在集羣內不一樣節點的不一樣分區上,一個或多個消費者從多臺Borker的分區上消費訂閱數據。

從這個模型可知,若是數據的讀寫都集中在單個分區上,則Topic的的全部壓力都會集中在該分區上,從而落到單臺Broker上面。假設單臺機器能承受的流量是300MB,則此時以騰訊教育的GB/s的流量規模,則會出現消息處理過慢,會致使消息延時。那怎麼辦呢?此時就應該提高分區的數量,提升數據處理的並行度,從而將整個topic的壓力均分到多臺機器上。

這時就會有一個疑問,Topic須要多少分區合適呢?是否是越多的分區越好呢?

影響分區數量的因素

從生產者的角度來看,數據向不一樣的分區寫入是徹底並行的;從消費者的角度來看,併發數徹底取決於分區的數量(若是 consumer 數量大於 分區 數量,則必有 consumer 閒置)。所以選取合適的分區對於發揮 CKafka 實例的性能十分重要。

Topic的分區數量是由多種因素決定的,通常能夠根據如下幾個因素綜合考慮:

  • 生產者的峯值帶寬

假設單機單partiton的生產消費吞吐各自最高爲300,峯值生產帶寬是900MB,則單純生產至少須要3個Partiton。

  • 消費者的峯值帶寬

有人可能會以爲消費的峯值帶寬應該等於生產的峯值帶寬。這樣是不對的。生產者只會生產一份數據,可是能夠有N個消費者消費同一份數據,則此時消費帶寬=N*生產帶寬。 另外若是是離線計算,可能會在某一時刻,消費歷史全部數據,此時消費帶寬可能會遠遠高於生產帶寬。 此時若是Topic只設計3個分區就有問題了。假設消費峯值帶寬是生產帶寬的2倍。則此時至少須要6個分區。

  • 消費者的處理能力

假設建立了6個分區。此時6個分區最多隻會有6個消費者,每一個消費者最多每秒能夠從Kafka Server拉到300MB的數據。可是每一個消費者由於還需處理業務邏輯的關係,只能消費100MB的數據,這樣就會容易致使出現消費堆積的狀況。 爲了增大消費能力,則須要多加入消費者。由於Kafka的consumer group機制裏同一個消費組裏同一個分區只能被一個消費者消費。因此,就應該增大分區的數量。爲知足如上需求,此時至少須要18個分區,18個消費者,才能知足消費需求。

在上面的Case中,分區數的設計也須要存在必定的冗餘,由於不少狀況下,性能是沒法達到最優的。因此,分區數量須要綜合考慮多個因素,能夠適當的多一點分區數量,以提升實例的性能。但也不能太大,太大也會致使一系列的其餘問題。

選取合適的分區數量

考慮到上面提到的實際因素,是否有一個相對簡單的判斷方法來設計分區數量呢?

在理想狀況下,能夠經過以下公式來判斷分區的數目:

Num = max( T/PT , T/CT ) = T / min( PT , CT )

其中,Num 表明分區數量,T 表明目標吞吐量,PT 表明生產者寫入單個 分區 的最大吞吐,CT 表明消費者從單個分區消費的最大吞吐。則分區數量應該等於 T/PT 和 T/CT 中的較大值。

在實際狀況中,生產者寫入分區的最大吞吐 PT 的影響因素和批處理的規模、壓縮算法、確認機制、副本數等有關。消費者從單個分區消費的最大吞吐 CT 的影響因素和業務邏輯有關,須要在不一樣場景下實測得出。

一般建議分區的數量必定要大於等於消費者的數量來實現最大併發。 若是消費者數量爲5,則分區的數目也應該 ≥ 5 的。但須要注意的是:過多的分區會致使生產吞吐的下降和選舉耗時的增長,所以也不建議過多分區。

提供以下信息供參考:

  1. 單個分區是能夠實現消息的順序寫入的。
  2. 單個分區只能被同消費者組的單個消費者進程消費。
  3. 單個消費者進程可同時消費多個分區,即分區限制了消費端的併發能力。
  4. 分區越多,當Leader節點失效後,其餘分區從新進行Leader選舉的耗時就會越長。
  5. 分區的數量是能夠動態增長的,只能增長不能減小。但增長會出現消息 rebalance 的狀況。

在上述方法的基礎上,咱們還綜合考慮了騰訊課堂的生產消費峯值帶寬、消費的行爲特徵和單個消費者的消費能力等因素,爲其設計了合理的分區數量,以知足其對消息實時性的要求。

消息的可靠性

消息的可靠性從不一樣的角度看是不同的。從Apache Kafka自身角度看來,消息的可靠性是消息的可靠存儲。從業務的角度來看,消息的可靠性是指消息傳輸、存儲、消費的可靠性。

從服務提供商來看,咱們但願消息的可靠性是站在客戶這一邊的,便可靠的傳輸,存儲,消費。CKafka在作好可靠性存儲的基礎上,還從配置調優、異常告警等方面儘可能作到消息的可靠傳輸和消費。

關於副本

在介紹下面的方案前,咱們先聊聊一下副本。爲何要有副本的存在呢?

在分佈式的場景下,數據損壞和機械故障是被認爲常見事件。數據副本是指在不一樣節點上持久化同一份數據,當某一個節點上存儲的數據丟失時,能夠從副本上讀取該數據,這是解決分佈式系統數據丟失問題最爲有效的方法。

那麼咱們來思考下:有多少個副本的數據纔是安全的?理論上2個副本就能夠大機率範圍的保證數據安全,可是當兩個副本都損壞時,數據也會丟失,此時就須要更多的副本,或者須要副本跨可用區、跨地域分佈。固然更多的副本就意味着要存儲更多的數據,須要更高的成本投入。因此用戶須要在冗餘和安全之間權衡出一種平衡。這也是騰訊雲上建立topic須要用戶指定副本數量的緣由,以下圖:

圖片

服務端的可靠性

假設TopicA有3個分區,每一個分區有三個副本。來看一下以下的Topic分區分佈示意圖。

如圖所示,三個分區和三個副本均勻的分佈在三個Broker中,每臺Broker分佈了一個分區的Leader分區。從上一節關於副本的描述可知,除非全部的Broker在同一時間掛掉,不然即便同時掛掉2臺Borker,服務也能夠正常運行。而在咱們當前的運營架構中,三臺broker同時掛掉的機率微乎其微,固然若是真的出現這種狀況,那就是整個機房掛掉了。

爲了不整個機房掛掉的狀況,騰訊雲Ckafka也能夠配置跨機房容災和跨可用區容災,來保證數據的可靠性。關於跨可用區容災相關的技術點能夠查閱:《蘑菇街千億級消息Kafka上雲實踐》

咱們能夠經過參數配置來儘量的保證可靠性傳輸和消費,用告警來作兜底策略,讓研發感知介入處理。下面來看一下生產和消費端的參數調優。

客戶端參數調優

生產的可靠傳輸,主要來看一下以下三個配置: ack、retries。

  • ack

    Kafka producer 的 ack 有 3 種機制,分別說明以下:

    -1:Broker 在 leader 收到數據並同步給全部 ISR 中的 follower 後,才應答給 Producer 繼續發送下一條(批)消息。 這種配置提供了最高的數據可靠性,只要有一個已同步的副本存活就不會有消息丟失。

0:生產者不等待來自 broker 同步完成的確認,繼續發送下一條(批)消息。這種配置生產性能最高,但數據可靠性最低(當服務器故障時可能會有數據丟失) 。

1:生產者在 leader 已成功收到的數據並獲得確認後再發送下一條(批)消息。這種配置是在生產吞吐和數據可靠性之間的權衡(若是leader已死可是還沒有複製,則消息可能丟失)

用戶不顯式配置時,默認值爲1。若是是須要可靠性要求高的,建議設置爲-1。設置爲-1會影響吞吐的性能。

  • retries

請求發生錯誤時重試次數,建議將該值設置爲大於0,失敗重試最大程度保證消息不丟失。

消費的穩定,看一下如下配置,主要避免重複消費和頻繁的消費組Rebalance:

  • auto.offset.reset

表示當Broker端沒有offset(如第一次消費或 offset超過7天過時)時如何初始化 offset。earliest:表示自動重置到 分區 的最小 offset

latest:默認爲 latest,表示自動重置到分區的最大 offset

none:不自動進行 offset 重置,拋出 OffsetOutOfRangeException 異常

默認值爲latest。當設置爲earliest的時候,須要注意的是:當offset失效後,就會從現存的最先的數據開始消費的狀況,可能會出現數據重複消費的狀況。

  • session.timeout.ms

使用 Kafka 消費分組機制時,消費者超時的時間。當 Broker 在該時間內沒有收到消費者的心跳時,就會認爲該消費者發生故障,Broker 發起從新 Rebalance 過程。目前該值的在 Broker 的配置必須在group.min.session.timeout.ms=6000和group.max.session.timeout.ms=300000 之間。

  • heartbeat.interval.ms

使用 Kafka 消費分組機制時,消費者發送心跳的間隔。這個值必須小於 session.timeout.ms,通常小於它的三分之一。

  • max.poll.interval.ms

使用 Kafka 消費分組機制時,再次調用 poll 容許的最大間隔。若是在該時間內沒有再次調用 poll,則認爲該消費者已經失敗,Broker 會從新發起 Rebalance 把分配給它的分區 分配給其餘消費者。

參數調優只能最大程度保證服務的可用,並不能保證服務的百分百可用。客戶端須要具備捕獲生產,消費等行爲異常的行爲。當出現異常時,可以告警,以便人工處理。這樣才能最大的保證業務的高可用。

CKafka的其餘優點

CKafka除了做爲消息管道幫助業務實現數據解耦、流量削峯外,還能夠在其餘場景有所做爲。

日誌分析系統

CKafka 結合大數據套件 EMR,可構建完整的日誌分析系統。首先經過部署在客戶端的 agent 進行日誌採集,並將數據聚合到消息隊列 CKafka,以後經過後端的大數據套件如 Spark 等進行數據的屢次計算消費,而且對原始日誌進行清理,落盤存儲或進行圖形化展現。

流數據處理平臺

CKafka 結合流計算 SCS , 可用於實時/離線數據處理及異常檢測,知足不一樣場景須要:

  1. 對實時數據進行分析和展現,並作異常檢測,快速定位系統問題。
  2. 消費歷史數據進行落盤存儲和離線分析,對數據進行二次加工,生成趨勢報表等。

結語

騰訊雲CKafka做爲高性能、高吞吐量的消息中間件,爲千萬師生有序穩定的線上課堂提供了性能支撐,有效的解決了數據的實時性和可靠性問題。特別是在業務故障時,可實現快速擴縮容,並以其全面的容錯機制和故障處理機制爲用戶提供解決方案。

在2020年突如其來的疫情期間,CKafka將與騰訊課堂一塊兒努力,爲莘莘學子們百萬級的課堂互動消息作好技術支撐,爲構建良好的線上課堂體驗貢獻一份力量。

做者簡介

許文強, 騰訊雲中間件消息隊列資深研發工程師。騰訊雲Ckafka核心研發,擁有多年分佈式系統研發經驗。主要負責騰訊雲CKafka定製化開發及優化工做。專一於Kafka在公有云多租戶和大規模集羣場景下的性能分析和優化。

歡迎掃碼關注咱們的微信公衆號,期待與你相遇~

相關文章
相關標籤/搜索