白瑜庆:知乎基于Kubernetes的kafka平台的设计和实现
歡迎大家前往騰訊云+社區,獲取更多騰訊海量技術實踐干貨哦~
本文首發在云+社區,未經許可,不得轉載。自我介紹
我是知乎的技術中臺工程師,現在是負責知乎的存儲相關組件。我的分享主要基于三個,一個是簡單介紹一下Kafka在知乎是的應用,另外一個是為什么做基于Kubernetes的Kafka平臺,還有我們如何去實現了基于Kubernetes平臺
Kafka在知乎的應用
Kafka一個是非常優秀的,消息或者是數據流的組件,在知乎承載了日志,數據收集,消息隊列的服務日志,顯而易見就包括業務,包括運行的DEBUG日志關鍵性日志。
數據傳輸,比如我們在瀏覽知乎的時候,有些用戶行為或者內容特征,通過我們這個平臺做數據的流失處理。
另外一個是Kafka實現對消息服務。簡單地,就是我關注的A用戶,我是不是應該基于關注用戶行為上做很多事情,這是一個消息隊列的服務。我們那個平臺現在是部署超過有40個Kafka集群,這些集群都是獨立的。另外上面有超過一千個topic,我們的Broker數有超過有兩千個Kafka。平臺從上線到現在已經運行有兩年了,承載的數據量都是百TB級的,我們現在這個設計是Kafka集群,我們要實現多集群。因為是對于公司內部的平臺,我們要保證高可用,平臺架構底層其實是廣大Broker管理員,上層是抽象出來的。Kafka的集群對業務其實也無感,。另外就是一個管理平臺管理,我創建topic,去創建分區,或者做故障處理。第一,上層只可能有管理平臺和客戶端是對R業務有感,客戶端我們要對客戶端進行收斂,有一個客戶端是原生支持的——Java。不同客端會有不同的表現,現在我們需要去收斂這個詞,
為什么采用Kubernetes?
因為我們遇到的問題在早期的時候,知乎的Kafka是一個單集群,在大家使用率不高,或者在數據量增長不爆炸的時候,單集群大家用得還OK時有天發現有一個Broker掛了,等到大家都掛了,這時候才發現其實是一條路是不可以常走的。因此我們覺得我們認為集群和大型社科系統單點,大家會依賴集權,不管任何的業務,我寫日志也好,發消息也好,或者我去做數據傳輸也好,這是不可以的。對于Kafka來,我們有一個開發,有各國的Top的概念,其實發生到業務來,每個topic都代表了不同的一個業務的場景,我們覺得對業務場景在內部要做分級,比如我重要的數據,我要做分析,我們的業務與Kafka的深耦合。當我先做了規劃,去梳理一下發現為什么我會這么多,它topic為什么集中掛掉之后有人還沒事,還非常的憤怒,覺得簡單就是天災。
那時候我們發現,其實我們的日志里面topic有很多類型,抽樣出來,一種是日志,一種是數據和消息。數據,比如在做一個離線計算的時候,收集了用戶數據或者我在APP里有埋點,這些數據可以通過開發管道或者spa或者我們的計算任務。另外一個是消息剛才也提到,比如我用戶去做了一次關注或者點贊,觸發后面一系列處理流程,很顯然看出他們其實是有分級的。我們要把Kafka集群在內部要做成多集群的方式,然而根據我們套配合做出劃分。
同類型的topic做不同集群的管理和配置。其實最簡單的法是Kafka有分片,我們是做高可用,日志的分片可以少。消息容量是小的,對于數據大家都做,比如用Kafka做數據分析,肯定知道在離線技術,在數據分析時候看一下數據量是跟在線的時候應該是千倍萬倍的這種關系,那就會出現一個問題——我們去規劃一個設計就去實施的,最后結果我們的需求會變的非常多,比如一個A業務,我認為非常的重要,去做一個但是承載了一個,我每天有幾百幾十T的數據,那我是不是可以申請一個新的Broker。新的集群,別人不要跟我摻到一起,我提供的是基礎數據,這樣的話我們遇到問題是集群會越來越多,事實上現在很多已經是超過四十億四十個了。服務器資源怎么去使用?因為早期部署的時候肯定單機部署,但又不是,比如我有一個普通的,比如我做了一個G,承載的數量有四個T,這樣的話我部署一個消息任務是不是有點浪費?那不數數任務它是有點就太太小,其實我們提供一個提高資源利用率,希望從單機上部署更多的Broker,并且能夠做到它們之間的相互的影響降到最低。實際上在我們實驗實踐中,磁盤其實是Kafka一個繞不開的問題。
首先磁盤不可以做數據持久化,但是我們遇到了很多的問題,有量突增的或者流量大的時候,磁盤首先容量會有問題,比如我有申請了1T的磁盤,那可能我現在寫一天給我寫兩天就已經寫到了3T。
另外一個問題就是磁盤的LUTOC其實IOPS過高這種問題出現的話,開發的性能是有很大的下降的。既然Broker可以做到多部署,那我們就在磁盤層面上做隔離,先在保證這種不要互相影響,就是比如數據和消息,Broker在磁盤這個層面要做好,做到互相不影響,因此我們想到的方法就是磁盤是不是可以分開,在物理層面就分開,并且開它本身又有副本。
這種物理存在分開是可以接受的,而且如果出現故障,完全是在可控范圍之內的,而是可期的。因此我覺得把分開,我們當時選服務器,正好黑石這邊也提供了一種叫高性能的服務器,其實非常滿足我們需求,它有12個高性能的磁盤,是單盤的,他不做瑞的,每個盤就是容量還不小。它的CPU和內存上面其實有優勢的,因為Kafka是對內存是有要求的,比如走的文件緩存,內存是滿足我需求的CPU,現在英特爾的CPU性能還蠻。我們就采用了黑色這款高性能服務器,現在我們的平臺都主要部署在這種服務器。底層的服務器想好了,資源劃分想好了,就是怎么去管理它?
我們先講一個有意思的,我們平臺之前有一個開發的管理平臺是自寫自演的,實現了部署Broker,包括渲染配置,去做遷移的,這個平臺比較私有,而且在運維上面或者管理上面不是很方便,而且觀眾很高興來同事都要從代碼層面學習,從那一套我們的平臺學習影響,或者是有一個更好的方案來去解決。如果激情數增加到了保證的不可數增加,并且是服務器如果壞掉了,你看我們如何感染管理他,調度的時候我們如何去考慮到按照磁盤這個維度做調度。因此我們想到QQ那鐵絲,因為之前我們有很多的一個在容器化方面的實踐,早期在開發上QQ來此之前其實知乎在ks上部署了很多計算任務,在這上面有很多積累,所以我們想利用它的管理功能和容器的技術進行資源管理。另外一個是應用程序管理。
Kafka on Kubernetes
首先解決問題設計Kafka容器,無非就是四個問題——內存,CPU,網絡和存儲。另外一個問題是我們怎么實現具體調度Kafka容器。
首先是內存和CPU。其實CPU是比較難以預估的,因為根據咨詢類型不同,對于內存和CPU消耗是不同的,Kafka本身是不強,依賴于CPU。但是在實際使用中還是有些問題的,比如咱們Kafka不是做批量,但很多時候有時候大家對它比較理解得透的時候,會把批量會得很小,比如我降低延遲,要保證每一條消息都確切的投放過去,把Brokers收得很小,這時候會造成一個什么問題?CPU會高,但是很這種問題我們可以通過調高CPU來解決。如果不出現這種大流量的話,一般內存是不會超過八個G的,而且一般使用會更低,所以我們的基準的容器會設置成8G根據實際使用時間長,經常會做調整,這個調整可以在IT市場很容易改。
另外網絡方面就是我們對外服務,采用的是一種獨立的內網ip方式,比如我每一個Broker都有一個獨立的ip,實際上因為我們的單機上會部署很多容器,所以每個都有IP,并且將這個ip注冊在內網DNS上面,這樣照好處是對于使用者來說,不需要知道具體容器的ip。這個是網絡又有一個很好的方式——可以做單機的多ip網絡設計,至少可以滿足我們的需求,這是容器方面的設計。默認支持的磁盤的掛載方式是HostParh Volume,這種方式是最優的,因為Kafka在本地磁盤性能最好的,而且能夠充分利用到本地的這種高效的文件緩存,我們本身的磁盤性能也是非常棒的,至少我可以滿足我的需求。
因此我們就應該是本地的目錄一個cosplay,也就到K2起來之后是給他的,請求的配置掛載到服務器的磁盤,黑色框是我們的一個容器,開發目錄指向的藍色框是服務器上的一個磁盤或者服務器上的目錄。雖然我們的集群看來就是這個樣子的,每一個方塊代表網上有很多的部署的Broker。業務上面可以反過來看,每個藍色的地方代表Broker。
第一,CPU和內存并不是問題,網絡其實已過測試過的,服務器網絡是二世紀的20G帶寬,每個盤我們經過測試,是有一點幾個G性能,即便把每個盤所有人都跑滿,其實這是災難情況,他只有不會超過20個G,因此我們不在考慮范圍之內,我們考慮的是磁盤的高可用目標,讓單個集群的Broker在節點要盡量做到分散。
第二是節點上的存儲使用盡量均勻。
算法是根據服務器磁盤狀態計算分數,分數高者被調度。另外就是磁盤的使用情況,如果有更多的可用盤,我們傾向于把Broker掛在了上面。其實它用了一個簡單的方式,假設創建一個紅色集群,實際上A和C都可以,但C是最優的,因為C上面的Broker數比較少。如果要創建一個藍色集群,那顯然是A是最優的。另外,在實際使用情況下要更復雜,因為得考慮到分片的高可用。按照算法去實現會遇到了一個實際性的問題——用HostPat是有很大局限性,一致性不好,比如需要去管理要調度的節點,因為如果用class的話需要去注冊一個本身選擇的word,或者其實我是不知道被調到哪個節點上。另外主機上要去掛載的目錄其實是沒有人管理的。這是我們遇到的問題,當時我們希望是既要利用到HostPath,只有掛在本地的磁盤這種特性來提高我們的性能管理。
而且我要能夠選出合理節點,并且能夠管理到這個存儲。因此我們在當時對Kubernetes做改造,實現磁盤和調度器的算法,可以實現實時更新磁盤信息。但是實現方式是通過假設創建實例.
本地磁盤管理
如果Broker已經在設備上建立起來,磁盤也被用了,那如何去管理它?事實上磁盤管理只能進入第三方的Agent。
故障處理和提升資源利用時會預留空間,比如為了快速處理故障不做簽署,首先就是成本太高,現在做的是快速恢復,因此我們會預留1到2個盤,即快速處理盤,因此只要把軟件指向這個容器,就可以馬上啟用,并且不會有太大的網絡開銷。另外就是在主機層面,即把分片在主機層面是做分開,做到高可用。
但我們遇到一個問題——需要把客戶端統一,因為技術平臺化。那如何把客戶端做到統一?我們的看這里,客戶端可以去讀Consul信息,檢查topic是不是有用。還有個好處是,如果做遷移的時候,因為事情使了很多方,生產和消費方式是很多的,而且一般流程是先于生產方,消費方就過來,大家可能有業務,可能大家如果按照這種注冊方式的話,其實遷移過程是可以同步的。在這個地方更改信息,整個這個生產所生產的消費,都可以感受到,就是另外就是易用性會提高。且用這種方式有好處是有一個集群比如我整個集群全部斷掉了,雖然事沒發生過,但是作為一個備用的方式的話,我們會有一個災備集群把所有的客戶端都可以直接遷移過去。
Q/A
Q: 你好,麻煩問一下,一個集群里面可能有很多topic,不同的用戶消費topic的時候,用戶之間是怎么隔離的?會不會消費到其他的topic數據?想問一下有沒有什么隔離的好的辦法?你一個集群里有多少套?集群里有多個topic,數據我就不想讓別人看到嗎?當然我如果提供一個客戶端給他,他就能把所有的數據看得到,有沒有什么好的辦法。
A:其實是這樣的,就是在我們的一個情況稱,如果這個進群它有多少Broker,假如在這個會相互影響,我們還是建議把它不是相互影響,因為集群面不可能只給一個用戶只提供一個集群,就是我們一個大的集群,會有很多用戶在使用他的數據,都是不同的topic進來的嗎?他消費的時候如果我沒有隔離的話,我只要給他客戶端,它所有的數據都看得到嗎?只能通過我在前面去做提供什么API服務來這種方式,有沒有?Kafka本身有沒有什么好的辦法去本身應該是有認證。
更多詳細資料,請戳下面的鏈接:
知乎基于Kubernetes的Kafka平臺的設計和實現.pdf
apache kafka vs apache storm如何使用?
相關閱讀
陳新宇:CKafka在人臉識別PASS中的應用
楊原:騰訊云Kafka自動化運營實踐
饒軍:Apache Kafka的過去,現在,和未來
此文已由作者授權騰訊云+社區發布,原文鏈接:https://cloud.tencent.com/dev...
總結
以上是生活随笔為你收集整理的白瑜庆:知乎基于Kubernetes的kafka平台的设计和实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: POJ3070 矩阵快速幂模板
- 下一篇: OKWatchDog 打造一个安全的容