Kafka 伺服器組態對於叢集的效能、穩定性和可擴充套件性至關重要。正確的設定能最佳化資源使用,避免效能瓶頸及資料遺失。本文將探討執行緒池管理、主題自動建立、長官者平衡、主題刪除、預設值管理、分割槽數量等關鍵引數的調整,並提供硬體選擇和雲端佈署的最佳實務。透過這些設定,可以有效提升 Kafka 叢集的整體效能和穩定性,並滿足不同應用場景的需求。同時,文章也分析了日誌段大小、保留策略等設定對效能的影響,並提供如何在 Azure 和 AWS 上進行佈署的建議,以協助讀者在不同環境中建構和管理高效能的 Kafka 叢集。
Kafka 伺服器組態調整與主題預設值管理
Kafka 伺服器的組態設定對於叢集的效能、穩定性和可擴充套件性至關重要。正確的設定不僅能夠最佳化系統資源的使用,還能防止潛在的效能瓶頸和資料遺失風險。
執行緒池管理與效能最佳化
Kafka 使用可設定的執行緒池來處理日誌段(log segments),這些執行緒主要在以下情況中使用:
- 正常啟動時開啟每個分割槽的日誌段
- 當發生故障後啟動時檢查並截斷每個分割槽的日誌段
- 關閉時清理日誌段
預設情況下,每個日誌目錄只使用一個執行緒。由於這些執行緒僅在啟動和關閉時使用,因此可以合理地設定較多的執行緒數來平行化操作,特別是在從非正常關閉中還原時,可以顯著縮短重新啟動具有大量分割槽的代理伺服器(broker)的時間。
設定 num.recovery.threads.per.data.dir
此引數指定每個日誌目錄使用的還原執行緒數量。例如,若設定 num.recovery.threads.per.data.dir 為 8,並且 log.dirs 中指定了 3 個路徑,則總共將使用 24 個執行緒。
num.recovery.threads.per.data.dir=8
內容解密:
此設定的主要目的是最佳化 Kafka 在啟動和關閉時的效能。增加執行緒數量可以加快日誌段的開啟和關閉速度,特別是在處理大量分割槽時,能夠顯著減少還原時間。
自動建立主題與長官者平衡
Kafka 的預設組態允許在特定情況下自動建立主題,例如當生產者開始寫入訊息或消費者開始讀取訊息時。然而,這種行為可能導致意外的主題建立,因此可以透過設定 auto.create.topics.enable 為 false 來停用自動建立主題的功能。
auto.create.topics.enable=false
內容解密:
停用自動建立主題可以避免因錯誤操作或惡意行為導致的主題泛濫,從而提高叢集的安全性和管理效率。
此外,auto.leader.rebalance.enable 設定可以用來確保叢集中的長官者(leader)分佈盡可能平衡,避免單一代理伺服器承擔過多的長官者角色。
auto.leader.rebalance.enable=true
內容解密:
此設定的目的是維持叢集的負載平衡,透過定期檢查分割槽的分佈並在必要時進行長官者的重新平衡,確保系統的整體效能和穩定性。
主題刪除與預設值管理
Kafka 允許透過設定 delete.topic.enable 為 false 來禁止刪除主題,這對於需要嚴格控制資料保留和刪除的環境尤為重要。
delete.topic.enable=false
內容解密:
此設定的主要目的是防止意外或未經授權的主題刪除操作,從而保護重要資料的安全。
主題預設值與分割槽數量管理
Kafka 的伺服器組態中包含了許多主題的預設設定,例如分割槽數量和訊息保留時間。這些預設值可以透過管理工具進行調整,以滿足不同主題的需求。
設定 num.partitions
num.partitions 引數決定了新建立主題的分割槽數量,預設為 1。需要注意的是,分割槽數量只能增加不能減少,因此在設定此引數時需要謹慎考慮未來的擴充套件需求。
num.partitions=10
內容解密:
選擇合適的分割槽數量對於主題的擴充套件性和效能至關重要。過少或過多的分割槽都可能導致資源浪費或效能問題,因此需要根據實際的訊息吞吐量和叢集規模進行合理的規劃。
如何選擇合適的分割槽數量
選擇分割槽數量時需要考慮多個因素,包括預期的訊息吞吐量、單個分割槽的最大消費吞吐量、以及未來的擴充套件需求等。
考慮因素:
- 預期的訊息吞吐量:根據預期的寫入和讀取速度來確定合適的分割槽數量。
- 單個分割槽的最大消費吞吐量:由於一個分割槽只能被一個消費者完全消費,因此需要根據消費者的處理能力來限制單個分割槽的吞吐量。
- 根據鍵的分割槽策略:如果訊息是根據鍵進行分割槽的,則在後期增加分割槽可能會很困難,因此需要提前規劃。
- 每個代理伺服器的分割槽數量和資源限制:需要考慮每個代理伺服器的磁碟空間和網路頻寬限制。
最佳實踐:
- 將分割槽數量設定為叢集中代理伺服器數量的倍數,以實作負載平衡。
- 根據實際的訊息流量和消費能力進行調整,以達到最佳的效能和資源利用率。
Kafka 叢集組態關鍵引數解析
在建立與管理 Kafka 叢集的過程中,正確的組態引數對於確保系統的效能、可靠性和可擴充套件性至關重要。本文將探討幾個關鍵的 Kafka 組態引數,包括 num.partitions、default.replication.factor、log.retention.ms、log.retention.bytes 和 log.segment.bytes,並分析它們對 Kafka 叢集運作的影響。
分割區數量(num.partitions)
分割區數量是 Kafka 中一個非常重要的組態引數,它直接影響到叢集的平行處理能力和資料分佈的均勻程度。過少的分割區可能導致無法充分利用叢集資源,而過多的分割區則會增加中繼資料更新和長官者轉移的時間,同時也會消耗更多的記憶體和其他資源。
如何確定合適的分割區數量?
根據目標吞吐量計算:如果已知主題的目標吞吐量和消費者的預期吞吐量,可以透過將目標吞吐量除以消費者的預期吞吐量來計算所需的分割區數量。例如,如果目標是每秒寫入和讀取 1 GB 的資料,且每個消費者只能處理 50 MB/s,那麼至少需要 20 個分割區,以支援 20 個消費者同時讀取資料,達到每秒 1 GB 的總吞吐量。
根據分割區大小調整:經驗表明,將每個分割區在磁碟上的大小限制在每天 6 GB 以內,通常可以獲得令人滿意的效能。因此,可以根據預期的每日資料量來調整分割區數量。
預設複製因子(default.replication.factor)
當啟用自動主題建立功能時,default.replication.factor 組態引數決定了新建立主題的複製因子。複製因子對於確保資料的永續性和可用性至關重要。建議將複製因子設定為至少比 min.insync.replicas 多 1,以確保在發生故障時仍能保持資料的可用性。對於需要更高容錯能力的大型叢集,可以考慮將複製因子設定為比 min.insync.replicas 多 2(RF++),以便在進行維護或升級時仍能保持資料的安全性。
日誌保留策略(log.retention.ms 和 log.retention.bytes)
Kafka 提供了兩種日誌保留策略:根據時間和根據大小。log.retention.ms 引數控制了根據時間保留日誌的策略,而 log.retention.bytes 則控制了根據大小保留日誌的策略。
根據時間的保留:預設情況下,Kafka 會保留最近 168 小時(即一週)的資料。可以透過
log.retention.ms、log.retention.minutes或log.retention.hours引數來設定保留時間,其中log.retention.ms的優先順序最高。根據大小的保留:可以透過
log.retention.bytes引數來設定每個分割區的最大保留大小。如果主題有多個分割區,則總保留大小將是log.retention.bytes與分割區數量的乘積。
同時使用兩種保留策略
可以同時使用根據時間和根據大小的保留策略。當同時設定了 log.retention.ms 和 log.retention.bytes 時,只要任一條件滿足,日誌就會被刪除。例如,如果設定 log.retention.ms 為一天,log.retention.bytes 為 1 GB,那麼如果一天內產生的資料量超過了 1 GB,日誌仍可能被刪除,即使它們不超過一天。
日誌段大小(log.segment.bytes)
Kafka 將產生的訊息追加到目前的日誌段中,當日誌段的大小達到 log.segment.bytes 所設定的值(預設為 1 GB)時,該日誌段就會被關閉,並開啟一個新的日誌段。調整日誌段的大小對於低產出率的主題尤為重要,因為它直接影響到訊息被過期刪除的時間。
調整日誌段大小的重要性
對於產出率較低的主題,如果日誌段大小設定得過大,可能會導致訊息被保留的時間遠遠超過預期的保留時間。例如,如果一個主題每天只接收 100 MB 的訊息,而 log.segment.bytes 設定為 1 GB,那麼需要 10 天才能填滿一個日誌段。如果 log.retention.ms 設定為一週,那麼實際上可能會保留長達 17 天的訊息。
Kafka 效能調校與硬體選擇的關鍵要素
在佈署與管理 Kafka 叢集的過程中,效能調校與硬體選擇是確保系統穩定運作和高效能的關鍵因素。正確組態 Kafka 的各種引數以及選擇適當的硬體,可以顯著提升叢集的處理能力和可靠性。本文將探討 Kafka 的時間策略、日誌段管理、硬體選擇等重要議題,並提供具體的調校建議。
時間策略與日誌段管理
Kafka 的日誌段管理機制是其高效能的關鍵之一。日誌段的大小和保留策略直接影響到系統的效能和資料儲存。
日誌段大小與保留時間
日誌段的大小由 log.segment.bytes 引數控制,當日誌段達到該大小時,Kafka 將關閉該日誌段並開啟新的日誌段進行寫入。預設情況下,該引數的值為 1 GB。此外,日誌段的保留時間由 log.retention.ms 引數決定,預設為 7 天。當日誌段中的最後一條訊息過期時,該日誌段才會被刪除。
log.segment.bytes=1073741824
log.retention.ms=604800000
#### 內容解密:
log.segment.bytes:控制每個日誌段的大小,適當的大小可以平衡效能和磁碟使用。log.retention.ms:決定日誌段保留的時間,確保資料不會過早被刪除。
時間策略對效能的影響
使用時間策略的日誌段管理可能會導致多個日誌段同時關閉,進而影響磁碟效能。這種情況通常發生在低流量的分割區,因為它們很少達到大小限制。因此,在使用時間策略時,需要考慮其對磁碟效能的潛在影響。
取得偏移量與時間戳
Kafka 透過時間戳來檢索偏移量。當請求特定時間戳的偏移量時,Kafka 會查詢在該時間戳正在寫入的日誌段檔案。它透過檔案的建立和最後修改時間來確定目標檔案,並傳回該日誌段的起始偏移量。
min.insync.replicas 與資料永續性
為了確保資料的永續性,建議將 min.insync.replicas 設定為 2,並將生產者的 acks 設定為 “all”。這樣可以確保至少兩個副本確認寫入操作,從而避免因長官者故障導致的資料丟失。
min.insync.replicas=2
#### 內容解密:
min.insync.replicas=2:確保至少兩個副本同步,避免單點故障導致的資料丟失。acks=all:要求所有同步副本確認寫入操作,提升資料可靠性。
訊息大小限制與組態協調
Kafka 的 message.max.bytes 引數限制了單個訊息的最大大小,預設為 1 MB。生產者如果嘗試傳送大於此限制的訊息,將收到錯誤回應。此外,消費者端的 fetch.message.max.bytes 組態需要與 message.max.bytes 相協調,以避免消費者無法取得大訊息的情況。
message.max.bytes=1000000
fetch.message.max.bytes=1000000
replica.fetch.max.bytes=1000000
#### 內容解密:
message.max.bytes:限制單個訊息的最大大小,防止過大的訊息影響系統效能。fetch.message.max.bytes和replica.fetch.max.bytes:需與message.max.bytes一致,確保消費者和副本能夠正確處理訊息。
硬體選擇對 Kafka 效能的影響
Kafka 的硬體選擇對於其效能至關重要。主要的效能瓶頸包括磁碟吞吐量、記憶體、網路和 CPU。
磁碟吞吐量
生產者的效能直接受磁碟吞吐量的影響。固態硬碟硬碟(SSD)由於其低延遲和高 IOPS,顯著優於傳統硬碟(HDD)。然而,HDD 在大容量儲存需求下仍具優勢,可以透過多磁碟組態或 RAID 來提升效能。
#### 內容解密:
- SSD 提供更好的效能,但成本較高;HDD 適合大容量儲存需求。
- 多磁碟組態或 RAID 可以提升 HDD 的整體效能。
Kafka硬體與雲端佈署最佳實踐
在規劃Kafka叢集時,硬體選擇是一個至關重要的環節。合適的硬體組態能夠確保Kafka叢集的高效能運作和穩定性。以下將探討Kafka的硬體需求以及在雲端環境中的佈署策略。
磁碟效能:SSD vs. HDD
Kafka的效能高度依賴磁碟的讀寫能力。傳統的硬碟(HDD)由於其機械結構,在處理大量隨機讀寫操作時表現不佳。固態硬碟硬碟(SSD)則提供了更快的讀寫速度和更低的延遲,因此是Kafka佈署的理想選擇。特別是在面對大量客戶端連線時,SSD能夠提供更好的效能。
磁碟容量:根據訊息保留策略進行規劃
磁碟容量的規劃取決於需要保留的訊息數量。如果預期每天會有1 TB的流量,並且需要保留7天的訊息,那麼至少需要7 TB的有效儲存空間來儲存日誌段。此外,還需要考慮其他檔案的儲存空間,通常建議增加至少10%的額外空間,以應對流量的波動和未來的擴充套件需求。
記憶體:最佳化頁面快取
Kafka的消費者通常會從分割槽的末尾讀取訊息,這些訊息很可能已經被儲存在系統的頁面快取中。因此,增加系統可用於頁面快取的記憶體能夠提高消費者的效能。Kafka本身不需要太大的堆積記憶體組態,5 GB的堆積記憶體就足以應付每秒處理15萬條訊息和200兆位元每秒的資料速率。系統的其他記憶體會被用於頁面快取,從而提高日誌段的快取效率。
網路:避免網路介面飽和
網路吞吐量決定了Kafka能夠處理的最大流量。Kafka的多消費者特性會導致輸入和輸出網路使用率的不平衡。生產者可能會以1 MB每秒的速度寫入某個主題,但多個消費者可能會成倍增加輸出網路的使用率。因此,建議至少使用10 Gb網路介面卡(NIC),以避免網路成為效能瓶頸。
CPU:壓縮和解壓縮訊息批次
處理能力在Kafka規模擴大之前並不是最重要的考慮因素,但它仍然會影響代理器的整體效能。客戶端通常會壓縮訊息批次以最佳化網路和磁碟使用。Kafka代理器需要解壓縮這些訊息批次以驗證校驗和並分配偏移量,然後重新壓縮以儲存到磁碟。這是Kafka對處理能力的主要需求。
雲端中的Kafka佈署
隨著雲端運算的發展,越來越多的Kafka叢集被佈署在雲端環境中,如Microsoft Azure、Amazon AWS和Google Cloud Platform。在雲端環境中,需要根據不同的效能特性和需求選擇合適的計算例項組態。
Microsoft Azure中的佈署建議
在Azure中,可以獨立於虛擬機器(VM)管理磁碟,因此儲存需求的決定不需要與VM型別繫結。首先根據資料保留需求和生產者的效能需求進行決策。如果需要極低的延遲,可能需要使用I/O最佳化的例項並搭配高階別SSD儲存。對於較小的叢集,Standard D16s v3例項型別是一個不錯的選擇,而D64s v4例項則能夠提供更好的效能和擴充套件性。
在選擇VM後,建議使用Azure Managed Disks而不是暫時性磁碟,以避免在VM遷移時丟失資料。高階別SSD或Ultra SSD組態提供了更高的效能和99.99%的SLA保證,但成本也更高。
Azure Managed Disks組態解密:
Azure提供了多種Managed Disks選項,包括HDD、SSD和Ultra SSD。它們各自具有不同的效能特性和成本。選擇適合的Managed Disks型別對於確保Kafka叢集的效能和可靠性至關重要。
@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle
title Kafka伺服器組態調整與主題預設值管理
package "AWS 雲端架構" {
package "網路層" {
component [VPC] as vpc
component [Subnet] as subnet
component [Security Group] as sg
component [Route Table] as rt
}
package "運算層" {
component [EC2] as ec2
component [Lambda] as lambda
component [ECS/EKS] as container
}
package "儲存層" {
database [RDS] as rds
database [DynamoDB] as dynamo
storage [S3] as s3
}
package "服務層" {
component [API Gateway] as apigw
component [ALB/NLB] as lb
queue [SQS] as sqs
}
}
apigw --> lambda
apigw --> lb
lb --> ec2
lb --> container
lambda --> dynamo
lambda --> s3
ec2 --> rds
container --> rds
vpc --> subnet
subnet --> sg
sg --> rt
@enduml
此圖示展示了Azure Managed Disks的不同型別及其特點。
在AWS上組態Kafka叢集以實作最佳效能
在AWS上執行Kafka時,若需要極低的延遲,則可能需要使用具有本地SSD儲存的I/O最佳化例項。否則,使用暫時性儲存(如Amazon Elastic Block Store)可能就足夠了。在AWS中,常見的選擇是m4或r3例項型別。m4例項允許更長的保留期,但由於磁碟位於彈性區塊儲存上,因此磁碟的吞吐量會較低。r3例項具有更好的吞吐量,因為它使用本地SSD磁碟,但這些磁碟會限制可以保留的資料量。若要兼顧兩者,可能需要升級到i2或d2例項型別,但它們的價格明顯更高。
組態Kafka叢集
單個Kafka代理程式適用於本地開發工作或概念驗證系統,但將多個代理程式組態為叢集具有顯著的好處,如圖2-2所示。最大的好處是能夠將負載分散到多台伺服器上。其次是使用複製來防止由於單一系統故障而導致的資料遺失。複製還允許在Kafka或基礎系統上執行維護工作,同時仍保持客戶端的可用性。本文重點介紹組態Kafka基本叢集的步驟。第7章將提供更多有關資料複製和永續性的資訊。
Kafka叢集大小的決定因素
Kafka叢集的適當大小由幾個因素決定。通常,叢集的大小將受到以下幾個關鍵領域的限制:
- 磁碟容量
- 每個代理程式的複本容量
- CPU容量
- 網路容量
第一個需要考慮的因素是保留訊息所需的磁碟容量以及單個代理程式可用的儲存空間。如果叢集需要保留10 TB的資料,而單個代理程式可以儲存2 TB,那麼最小叢集大小就是5個代理程式。此外,增加複製因子將至少增加100%的儲存需求,具體取決於所選擇的複製因子設定(參見第7章)。此處的複本是指單個分割槽被複製到的不同代理程式的數量。這意味著,同樣的叢集,如果組態了複製因子為2,那麼現在至少需要包含10個代理程式。
另一個需要考慮的因素是叢集處理請求的能力。這可以透過前面提到的其他三個瓶頸來體現。如果您有一個10個代理程式的Kafka叢集,但有超過100萬個複本(即50萬個分割槽,複製因子為2),那麼在均衡的情況下,每個代理程式大約有10萬個複本。這可能會導致生產、消費和控制器佇列出現瓶頸。過去,官方建議每個代理程式不超過4,000個分割槽複本,每個叢集不超過20萬個分割槽複本。然而,叢集效率的改進使得Kafka能夠擴充套件到更大的規模。目前,在組態良好的環境中,建議每個代理程式不超過14,000個分割槽複本,每個叢集不超過100萬個複本。
代理程式組態
要讓多個Kafka代理程式加入單個叢集,代理程式組態中有兩個要求。第一,所有代理程式必須對zookeeper.connect引數具有相同的組態。這指定了叢集儲存元資料的ZooKeeper叢集和路徑。第二,叢集中的所有代理程式必須對broker.id引數具有唯一的值。如果兩個代理程式嘗試使用相同的broker.id加入相同的叢集,第二個代理程式將記錄錯誤並無法啟動。還有其他在執行叢集時使用的組態引數,特別是控制複製的引數,這些將在後面的章節中介紹。
作業系統調校
雖然大多數Linux發行版都具有開箱即用的核心調校引陣列態,可以很好地適用於大多數應用程式,但對於Kafka代理程式,可以進行一些更改以提高效能。這些更改主要圍繞虛擬記憶體和網路子系統,以及用於儲存日誌段的磁碟掛載點的特定問題。這些引數通常在/etc/sysctl.conf檔案中組態,但您應該參考Linux發行版的檔案以取得有關如何調整核心組態的具體細節。
虛擬記憶體
一般來說,Linux虛擬記憶體系統會自動根據系統工作負載進行調整。我們可以對交換空間的使用方式以及髒記憶體頁面進行一些調整,以針對Kafka的工作負載進行調校。
與大多數應用程式一樣,特別是那些吞吐量很重要的應用程式,最佳做法是(幾乎)完全避免交換。將記憶體頁面交換到磁碟所帶來的成本將對Kafka的所有效能方面產生明顯影響。此外,Kafka大量使用系統頁面快取,如果VM系統正在交換到磁碟,則沒有足夠的記憶體分配給頁面快取。
避免交換的一種方法是根本不組態任何交換空間。不組態交換空間並不是一個硬性要求,但它確實提供了一個安全網,以防系統上發生災難性事件。有了交換空間,可以防止OS由於記憶體不足而突然終止某個行程。因此,建議將vm.swappiness引數設定為非常低的值,例如1。