既然是集群,必然有多個Kafka節點,只有單節點構成的Kafka偽集群只能用於日常測試,不可能滿足線上生產需求。 真正的線上環境需要考量各種因素,結合自身的業務需求而制定。看一些考慮因素(以下順序,可是分了順序的哦)
1 操作系統 - OS
可能你會問Kafka不是JVM上的大數據框架嗎?Java又是跨平臺的語言,把Kafka安裝到不同的操作系統上會有什麼區別嗎? 區別相當大!
確實,Kafka由Scala/Java編寫,編譯後源碼就是“.class”文件。 本來部署到哪個OS應該一樣,但是不同OS的差異還是給Kafka集群帶來了相當大的影響。 毋庸置疑,部署在Linux上的生產環境是最多的。
考慮操作系統與Kafka的適配性,Linux系統顯然要比其他兩個特別是Windows系統更加適合部署Kafka。可具體原因你能談笑風生嗎?
1.1 I/O模型
I/O模型可以近似認為I/O模型就是OS執行I/O指令的方法。 主流的I/O模型通常有5種類型:
- 阻塞式I/O e.g. Java中Socket的阻塞模式
- 非阻塞式I/O e.g. Java中Socket的非阻塞模式
- I/O多路複用 e.g. Linux中的系統調用select函數
- 信號驅動I/O e.g. epoll系統調用則介於第三種和第四種模型之間
- 異步I/O e.g. 很少有Linux支持,反而Windows系統提供了一個叫IOCP線程模型屬於該類
我在這裡不詳細展開每一種模型的實現細節,因為那不是本文重點。
言歸正傳,I/O模型與Kafka的關係幾何? Kafka Client 底層使用了Java的selector,而selector
- 在Linux上的實現機制是epoll
- 在Windows平臺上的實現機制是select
因此在這一點上將Kafka部署在Linux上是有優勢的,能夠獲得更高效的I/O性能。
1.2 數據網絡傳輸效率
Kafka生產和消費的消息都是通過網絡傳輸的,而消息保存在哪裡呢? 肯定是磁盤! 故Kafka需要在磁盤和網絡間進行大量數據傳輸。 Linux有個零拷貝(Zero Copy)技術,就是當數據在磁盤和網絡進行傳輸時避免昂貴內核態數據拷貝從而實現快速數據傳輸。Linux平臺實現了這樣的零拷貝機制,但有些令人遺憾的是在Windows平臺上必須要等到Java 8的60更新版本才能“享受”到。
一句話,在Linux部署Kafka能夠享受到零拷貝技術所帶來的快速數據傳輸特性帶來的極致快感。
1.3 社區生態
社區目前對Windows平臺上發現的Kafka Bug不做任何承諾。因此,Windows平臺上部署Kafka只適合於個人測試或用於功能驗證,千萬不要應用於生產環境。
2 磁盤
2.1 靈魂拷問:機械硬盤 or 固態硬盤
- 前者便宜且容量大,但易壞!
- 後者性能優勢大,但是貴!
建議是使用普通機械硬盤即可。
- Kafka雖然大量使用磁盤,可多是順序讀寫操作,一定程度上規避了機械磁盤最大的劣勢,即隨機讀寫慢。從這一點上來說,使用SSD並沒有太大性能優勢,機械磁盤物美價廉
- 而它因易損壞而造成的可靠性差等缺陷,又由Kafka在軟件層面提供機制來保證
2.2 是否應該使用磁盤陣列(RAID)
使用RAID的兩個主要優勢在於:
- 提供冗餘的磁盤存儲空間
- 提供負載均衡
不過就Kafka而言
- Kafka自己實現了冗餘機制提供高可靠性
- 通過分區的設計,也能在軟件層面自行實現負載均衡
如此說來RAID的優勢也就沒有那麼明顯了。雖然實際上依然有很多大廠確實是把Kafka底層的存儲交由RAID的,只是目前Kafka在存儲這方面提供了越來越便捷的高可靠性方案,因此在線上環境使用RAID似乎變得不是那麼重要了。 綜上,追求性價比的公司可以不搭建RAID,使用普通磁盤組成存儲空間即可。使用機械磁盤完全能夠勝任Kafka線上環境。
2.3 磁盤容量
集群到底需要多大? Kafka需要將消息保存在磁盤上,這些消息默認會被保存一段時間然後自動被刪除。 雖然這段時間是可以配置的,但你應該如何結合自身業務場景和存儲需求來規劃Kafka集群的存儲容量呢?
假設有個業務
- 每天需要向Kafka集群發送1億條消息
- 每條消息保存兩份以防止數據丟失
- 消息默認保存兩週時間
現在假設消息的平均大小是1KB,那麼你能說出你的Kafka集群需要為這個業務預留多少磁盤空間嗎?
計算:
- 每天1億條1KB的消息,存兩份 1億 * 1KB * 2 / 1000 / 1000 = 200GB
- 一般Kafka集群除消息數據還存其他類型數據,比如索引數據 再為其預留10%磁盤空間,因此總的存儲容量就是220GB
- 要存兩週,那麼整體容量即為 220GB * 14,大約3TB
- Kafka支持數據的壓縮,假設壓縮比是0.75 那麼最後規劃的存儲空間就是0.75 * 3 = 2.25TB
總之在規劃磁盤容量時你需要考慮下面這幾個元素:
- 新增消息數
- 消息留存時間
- 平均消息大小
- 備份數
- 是否啟用壓縮
3 帶寬
對於Kafka這種通過網絡進行大數據傳輸的框架,帶寬容易成為瓶頸。 普通的以太網絡,帶寬主要有兩種:1Gbps的千兆網絡和10Gbps的萬兆網絡,特別是千兆網絡應該是一般公司網絡的標準配置了 以千兆網絡為例,說明帶寬資源規劃。
真正要規劃的是所需的Kafka服務器的數量。 假設機房環境是千兆網絡,即1Gbps,現在有業務,其目標或SLA是在1小時內處理1TB的業務數據。 那麼問題來了,你到底需要多少臺Kafka服務器來完成這個業務呢?
計算
帶寬1Gbps,即每秒處理1Gb數據 假設每臺Kafka服務器都是安裝在專屬機器,即每臺Kafka機器上沒有混入其他服務 通常情況下你只能假設Kafka會用到70%的帶寬資源,因為總要為其他應用或進程留一些資源。超過70%的閾值就有網絡丟包可能性,故70%的設定是一個比較合理的值,也就是說單臺Kafka服務器最多也就能使用大約700Mb帶寬。
這只是它能使用的最大帶寬資源,你不能讓Kafka服務器常規性使用這麼多資源,故通常要再額外預留出2/3的資源,即 單臺服務器使用帶寬700Mb / 3 ≈ 240Mbps 這裡的2/3其實是相當保守的,可以結合機器使用情況酌情減少該值
有了240Mbps,可以計算1小時內處理1TB數據所需的服務器數量了。 根據這個目標,每秒需要處理2336Mb的數據,除以240,約等於10臺服務器。 如果消息還需要額外複製兩份,那麼總的服務器臺數還要乘以3,即30臺。
總結
與其盲目上馬一套Kafka環境然後事後費力調整,不如在一開始就思考好實際場景下業務所需的集群環境。在考量部署方案時需要通盤考慮,不能僅從單個維度上進行評估。
參考
- Linux內核模型架構
- Kafka核心技術與實戰
閱讀更多 Java愛好者哦 的文章