騰訊雲Kafka海量服務自動化運營實踐

騰訊技術工程發表於2018-10-26


騰訊雲Kafka海量服務自動化運營實踐

騰訊雲CKafka是基於Apache Kafka 的分散式、高可擴充套件以及高吞吐的雲端Kafka服務。騰訊雲CKafka針對開源Kafka進行了多種最佳化,其中包括無鎖佇列最佳化、非同步刷盤最佳化、多版本支援以及GC最佳化等最佳化手段,對開源Kafka效能達到了數倍的提高。與使用者自己部署Kafka相比,騰訊雲CKafka無需使用者關心Kafka叢集細節,使用者無需維護Kafka叢集直接使用,同時為使用者提供豐富的監控指標。由於騰訊雲CKafka與社群Kafka的協議一致,使用者只需要夠買例項後便可無縫接入。再者,CKafka允許使用者動態進行例項的升降配,按需付費。最後騰訊雲CKafka與騰訊雲端儲存以及大資料EMR套件打通,使用方便。

當前騰訊雲CKafka執行規模已經達到了日訊息萬億的級別,同時日吞吐量已經達到了PB級別,單叢集最高峰值可達數十億。

在運營雲端CKafka不同叢集以及如此繁多的節點時候,我們遇到了的問題可以歸納為以下幾點:

1)如何選擇雲端CKafka版本

2)如何合理的建立分配例項才能實現資源的有效利用

3)怎樣實現例項動態升降配

4)如何實現叢集的負載均衡

5)怎樣合理規劃分割槽的建立、新增以及遷移

下文就針對這五個問題分別闡述騰訊雲CKafka是如何解決的。

多版本生產/消費相容

由於雲端面對的使用者不同,必然會出現對Kafka不同版本的要求。當前最新Kafka版本已經為1.1.0版本,對於底層儲存而言,主要是不同版本會有不同的訊息格式。

騰訊雲Kafka海量服務自動化運營實踐

圖1. 使用者版本的選擇

 第一種方案是部署多套Kafka叢集以滿足不同版本的要求,但是這種做法的代價是每當使用者購買例項的時候必須提供其使用版本,同時使用者必須持續使用這種Kafka版本。否則只能透過重新購買不同版本的例項才可以實現版本的替換。其次在運維過程中,由於每個節點有版本號的特異性,不同版本的節點不允許加入非對應版本的叢集。在叢集節點排程時不再對叢集透明,所以在後續對叢集維護的時候也增加了維護成本。

第二種方法也是目前CKafka使用的方法,改造Kafka底層以完成多種訊息格式的儲存。底層不再拒絕不同版本的訊息,根據magic欄位獲取訊息的格式進行相應處理。在不同版本之間的生產/消費進行訊息的轉換以滿足要求。這樣使用者即使使用不同版本也可以在同一個例項下完成,叢集排程也不會有節點特異性的問題。

提高資源利用率

伴隨著服務的運營以及越來越多的例項售賣,後端發現叢集出現了資源浪費的情況。由於CKafka是按照例項進行售賣,例項售賣又具有兩個緯度,分別為頻寬與磁碟。每個例項的服務能力會分佈在不同節點上,不合理的資源分配將會造成兩種資源的浪費。

騰訊雲Kafka海量服務自動化運營實踐

圖2. 例項分配浪費場景

CKafka目前採用類似裝箱演算法的方式進行例項分配,根據不同情況計算每次分配的權值,盡力保證每次的頻寬售賣與磁碟的售賣比例保持在1:1的狀態,選擇合理的分配方式進行分配。分配分為以下3種情況:

(a) 本次分配後,剩餘的容量不足以進行一個最小例項的售賣,這種情況需要對計算結果進行降權處理。

(b)本次分配後,剩餘的資源恰好足夠一個最小例項的售賣,這種情況屬於理想情況,我們賦予一個較大的常數權值。

(c)本次分配後,如果不屬於上述兩種情況,則採用頻寬售賣比例與磁碟售賣比例的比值作為權值計算引數計算權值。

根據上述三種情況進行節點的選擇,達到兩種資源售賣的相對均衡。

使用者動態升降配

在使用者使用CKafka的初期往往會購買一個相對較小的例項進行功能性測試,在完成功能性測試之後會希望進行例項升級以達到生產環境的標準。例項的升降配分為兩種情況:其一是例項所在的機器有足夠的資源完成本次升級要求,這種情況在節點上直接扣除資源可以完成升級操作。第二種情況是當前例項所在機器資源不足以完成本次例項升級,需要進行例項的遷移才可以完成例項升級。

這種情況下,我們會根據遷移後的服務節點數量生成多種遷移方案,每種方案下遷移的代價是不同的。當從少數機器遷移往多數機器時,每個機器所需要的服務能力會更小。遷移的時候,我們第一步會計算每種遷移方案下,應該選擇的節點。這個節點的選擇由我們前面提到的權值計算方式得出。

騰訊雲Kafka海量服務自動化運營實踐

圖3.遷移方案計算

得到所有遷移方案後,我們會開始計算每種方案的遷移代價,然後按照遷移代價最小的遷移方式進行例項的遷移。遷移完畢後就可以完成例項的升級,當前遷移主要考慮的指標為遷移的Partition的落盤資料大小,Partition遷移的數量為該例項所有Partition平均分佈在服務其節點上的一個平均值。這裡需要注意的是遷移過程分步遷移,從資料量小的Partition開始遷移,這樣可以保證整個遷移過程相對可控,同時也能便於遷移的回滾。

騰訊雲Kafka海量服務自動化運營實踐

圖4.遷移代價計算

集體的負載均衡

對於一個CKafka叢集,生產過程中避免不了對叢集中節點的新增以及減少,我們在如下幾種情況會考慮增加一個叢集中的節點:

(1)例項能力的擴充套件

當叢集中剩餘的資源不足以進行新的例項建立或者不足支援例項的升級時,我們會在叢集中新增機器增加資源,支援後續的售賣以及例項遷移擴容。

(2)節點資源碎片的整理

當節點存在資源碎片的時候,可以透過新增機器,將部分現有的機器上的例項進行遷移,對剩餘的資源碎片進行重新整合以滿足售賣要求。

(3)叢集節點間的機器負載均衡

當叢集的機器某些資源消耗達到設定的閾值時,透過增加機器對現有例項進行遷移。降低整個叢集中的節點負載。

在以下情況我們會對叢集中節點進行移除:

(1)例項的縮容

當使用者購買例項後發現,例項的服務能力大於自己所需要能力時,這時候需要對例項進行縮容,有些縮容會將Partition遷移到更少的機器上。當縮容後發現某些節點已經不存在服務的例項了。這時候我們會進行節點移除減少成本。

(2)節點異常

生產過程中避免不了節點的硬體異常情況,這種時候我們會將服務在該節點上的例項進行一個例項的遷移然後下架機器。

分割槽管理—建立、新增、遷移

前面提到的所有操作,都離不開最基本的Partition操作。對於CKafka運營過程中,會從整個Partition的生命週期入手進行管理。

騰訊雲Kafka海量服務自動化運營實踐

圖5.Partition的遷移選擇

(1)分割槽的建立:

對於每個例項的Partition新增,我們都會優先選擇該例項後端對應伺服器上Partition最少的節點進行建立。這樣可以避免分割槽不均勻情況。即使每次例項建立Partition的時候都只建立少量Partition,也能保證分配到Partition最少的機器上。

騰訊雲Kafka海量服務自動化運營實踐

圖6.Partition的建立選擇

(1)分割槽的遷移:

(a)遷移的目的

由於分割槽的遷移在訊息量大的情況下代價也是巨大的,所以每次遷移前必須考慮這個遷移是否必要的,是否可以不遷移來解決當前問題。當前我們遷移主要為了解決以下幾種問題:服務異常,這種情況必須遷移例項下的Partition,否則後續服務可能會受到影響;例項擴縮容,這種情況下必須遷移例項部分Partition,否則無法滿足使用者升級的需求;負載均衡,這種不屬於必須的遷移。即使不遷移也能保證叢集工作,只不過遷移後叢集會在一個更健康的環境下工作。

(b)遷移的方式

Leader遷移:這種遷移涉及Partition的角色切換,這種遷移的代價較Replica遷移偏小。角色切換後,新節點的CPU以及網路卡出流量會增加。這是因為壓縮和解壓縮的操作只會存在於Partition節點,同時Partition的消費只會發生在Leader節點上。

關於Leader遷移主要考慮兩點:Leader的分佈以及Leader的網路出流量。遷移的第一步會優先計算出Leader應該遷移的個數以及遷移的目的地,個數是根據Leader的數量以及Broker的數量求平均值計算出來,從Leader數目多的節點遷往Leader數目少的節點。再者會考慮每個Partition的Leader出流量,優先將出流量多的Partition和出流量少的Partition進行組合分配。這樣就可以達到一個相對均衡的分配狀態。

騰訊雲Kafka海量服務自動化運營實踐

圖7. Leader遷移方式

Replica遷移:這種遷移涉及Partition的資料搬遷,這種遷移的代價較大。涉及資料的全量轉移,在資料量大的時候往往導致遷移時間過久。其次每次遷移將會佔用新機器上一個Partition所應該佔用的所有資源。

關於Replica的遷移主要考慮兩點:遷移後節點的利用率以及資料遷移的代價  。在遷移前第一步先計算遷移Partition的數量,我們希望Partition儘量平均分佈在 服務其的所有節點上。根據遷移後一個例項可能佔用節點的數量不同生成多種遷移方案,同時根據裝箱售賣權值計算出哪些節點是符合本次遷移目的地候選的。接下來考慮每種遷移方案的代價,這裡主要考慮的是遷移的資料總量,優先選擇資料遷移少的遷移方案進行Replica的遷移操作。

騰訊雲Kafka海量服務自動化運營實踐

圖8. Replica遷移方式

自動化控制中心架構

為了滿足日常運維指標以及告警的實際需求,以及自動化排程功能實現,整個自動化控制中心架構的實現如下:

騰訊雲Kafka海量服務自動化運營實踐

圖9. CKafka控制中心架構圖

  • CKafka Cluster

    CKafka針對底層不同訊息格式進行了分析處理,允許不同版本生產者與消費者之間交叉使用。CKafka會對這些不同版本做相容以及轉換,對於使用者完全透明。叢集負責上報兩大類資料,第一種是生產/消費過程中的監控資料,此處具體到每個Partition級別,涵蓋Partition的生產/消費以及資料堆積等情況,Consumer Group消費進度。第二種是相對偏向硬體負載的機器資訊,比如機器的CPU、記憶體、IO以及網路卡流量等資訊,同時還會監控程式的存活情況。

  • Monitor

    負責收集CKafka上報的資料,對於生產/消費過程中的監控資料進行資料的彙總。匯聚成節點、叢集等多緯度的資料供日常監控。同時進行Barad資料的上報,在Barad上根據例項、Topic緯度進行彙總。當遇到節點異常時進行異常告警,同時通知控制中心進行節點例項遷移排程。在節點異常的情況下需要對於節點上所有服務的Partition進行全量遷移。

  •  Metric Center

    當前是採用Barad做資料彙總,將資料根據多維度聚合展示給使用者。使用者前端控制檯可以針對多種指標進行告警設定。

  • Inner OSS

    運營控制檯處可以感知到當前叢集所有例項分配情況,當例項建立時由OSS進行整個建立操作。若出現資源不足的情況下,OSS會通知管控中心進行叢集中資源的整合或者進行例項遷移,當遷移完畢後完成相關請求工作。同時OSS也可以手動觸發/取消遷移排程操作,每個遷移操作進度也能從此處得知。

  • Control Center

    管控中心主要根據不同事件進行不同的排程處理:

    1)根據上報資訊確認是否需要進行均衡排程,如果超過指定的閾值條件則觸發叢集負載均衡;

    2)叢集資源需要進行整理或資源不足以完成例項升配,此時進行合理的例項遷移,完成資源整合或者轉移相關資源達成目標;

    3)節點異常事件,此時遍歷此節點上存在的所有例項資源,進行例項遷移保證後續服務。

排程過程由Analyzer模組進行方案的生成,方案主要根據後端服務節點不同而確定,並且根據不同的觸發條件計算遷移代價確定最優方案。 當Analyzer模組生成最佳方案後,每個方案又會分解成多個小任務進行執行,這是因為這樣可以保證遷移過程任務相對獨立便於取消,同時如果需要回滾那麼過程相對可控,其次這樣在遷移過程中對現有節點上的使用者服務影響最小。這些細粒度任務由Task Manager模組進行管理,Task Manager模組會將任務進行儲存以便後續檢視操作記錄以及進行任務回滾。為了保證不對現有服務造成衝級,管控系統增加Flow Control模組動態的針對流量進行控制,根據遷移的例項規格以及遷移目標節點的負載,對遷移的流量進行合理分配,防止遷移過程造成對現有使用者的影響。

小結

針對CKafka的Broker節點底層改造以及利用自動化控制中心對遷移的合理管控,有效解決CKafka運營過程中遇到的例項分配、升降配、遷移以及叢集負載均衡排程等一系列問題,為海量節點運營提供了自動化運營手段。對於當前排程方案還有不足的地方:首先希望能夠從更多的緯度去進行排程管理,比如CPU/記憶體/IO等。其次當前排程是基於已經發生異常的情況下才會進行排程工作,後續希望透過叢集負載、資源佔用以及例項增長量對叢集的負載趨勢做預判,提前完成遷移以及均衡。最後對於資源的合理利用還有不足的地方,將來會透過實際的售賣情況更好的完善權值計算公式。歡迎各位對Kafka叢集運維以及資源排程的問題進行交流,互相學習,也誠邀各位有志之士加入我們CKafka團隊。

原文連結:https://mp.weixin.qq.com/s/ihBsGJ3b-1DBi3kNZA1cxQ

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31559354/viewspace-2217641/,如需轉載,請註明出處,否則將追究法律責任。

相關文章