可消费消息数量_战疫情!CKafka助力腾讯课堂百万消息实现稳定互动
導語:疫情期間,為了保障國內學子的正常學習進度,積極響應國家"停工不停學"的號召,緊急上線疫情期間專用的"老師極速版",使廣大師生足不出戶,即可快速便捷的完成線上開課。面對線上課堂百萬量級的互動消息,如何保證消息的實時性和準確性無疑是一個技術挑戰。那么如何解決問題呢?接下來,就和小編一起來看看騰訊云中間件CKafka如何為騰訊課堂百萬級消息提供技術支撐。(編輯:中間件小Q妹)
背景
兩年前,騰訊在線教育部就在探索如何實現架構轉型。在梳理過騰訊課堂初始技術架構的痛點后,規劃出架構演進的三個重點方向:微服務、中間件、DevOps。尤其在消息中間件的選取上,從自研Hippo消息隊列切換到云CKafka。這主要歸于以下幾點原因:
· 實現技術棧的統一,降低組件適配成本。
· 使用符合開源標準的組件,便于系統切換優秀的開源組件。
· CKafka具備高性能、高可用性和高可靠性的特點:免除復雜的參數配置,提供專業的性能調優;磁盤高可靠,即使服務器壞盤50%也不影響業務;多副本備份,更有多可用區容災方案可選,零感知服務遷移。
· CKafka提供安全的數據保障:提供鑒權與授權機制、主子賬號等功能,為企業數據做好安全防護。
在剛剛過去的2019年,騰訊在線教育部已全面實現了業務上云,不僅提升了團隊研發效率,還實現了快速交付。同時,CKafka在消息流處理上的高性能特點得以實踐驗證。
而現在,疫情當前,面對全國千萬師生同時在線的線上課堂,互動消息猛增至百萬級別,無疑對在線教育平臺的穩定性提出更高要求。為了保證線上課堂廣大師生的穩定互動,CKafka作為騰訊課堂的底層消息支撐,在消息的實時性和可靠性上提供了更優化的技術方案。
騰訊課堂在線課程頁面
CKafka在騰訊課堂的實踐
Ckafka在騰訊課堂系統架構中的應用是非常典型的場景,即消息總線和業務解耦。使用了GB帶寬、TB存儲規格的實例。我們先來看一下CKafka作為消息總線在騰訊課堂的架構中所處的位置,如下圖:
從架構圖可知,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也可以配置跨機房容災和跨可用區容災,來保證數據的可靠性。關于跨可用區容災相關的技術點可以查閱:。
我們可以通過參數配置來盡可能的保證可靠性傳輸和消費,用告警來做兜底策略,讓研發感知介入處理。下面來看一下生產和消費端的參數調優。
客戶端參數調優
生產的可靠傳輸,主要來看一下如下三個配置: 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在公有云多租戶和大規模集群場景下的性能分析和優化。
總結
以上是生活随笔為你收集整理的可消费消息数量_战疫情!CKafka助力腾讯课堂百万消息实现稳定互动的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 多线程 转账_多线程编程不可错过——彻底
- 下一篇: linux中时间片,能讲一下在Linux