Apache Kafka: 优化部署的10个最佳实践
原文作者:Ben Bromhead????? 譯者:江瑋
原文地址:https://www.infoq.com/articles/apache-kafka-best-practices-to-optimize-your-deployment
關鍵點:
- Kafka的低開銷和易于水平伸縮的設計使得它能基于廉價硬件高效地運行。
- 使用最好的磁盤為ZooKeeper提供強大的網絡帶寬,分別存儲日志,隔離ZooKeeper進程,禁用交換以減少延遲。
- 將Kafka的默認復制因子從2增加到3,這在大多數生產環境中都是合適的。
- 更多的分區意味著更大的并行化和吞吐量,但分區也意味著更多的復制延遲、重新負載均衡和文件句柄資源。
- 監視系統指標,如網絡吞吐量、文件句柄、內存、負載、磁盤使用情況,以及JVM統計數據,如GC和堆使用情況。
Apacha Kafka以著名奧匈帝國小說家卡夫卡命名(注1),并且沒有辜負這個名字。它對后端技術人員充滿吸引力;產品具備深度和挑戰性;當足夠全面理解后,同樣能帶來的豐厚回報。遵循Kafka的一系列最佳實踐,可以使這個強大的數據流平臺的使用和管理變得非常容易且有效。
?
注1:弗蘭茲·卡夫卡,生活于奧匈帝國的捷克德語小說家,本職為保險業職員。主要作品有小說《審判》、《城堡》、《變形記》等。深受尼采、柏格森哲學影響,作品大都用變形荒誕的形象和象征直覺手法,表現被充滿敵意的社會環境所包圍的孤立、絕望的個人。
?
以下是10個技巧可以優化Kafka部署并更使之容易管理:
接下來讓我們逐一詳細看看這些最佳實踐。
?
Kafka為用戶提供了大量的日志配置選項,雖然默認設置是合理的,但是更好的方式是根據實際的業務情況,自定義日志行為以匹配特定需求。包括設置日志保留策略、清理、壓縮。
?
可以使用log.segment.bytes,log.segment.ms和log.cleanup.policy來控制日志行為。如果在業務中不需要保留大量歷史日志,可以通過設置cleanup.policy來清理特定大小的日志文件,或者設定在某個時間點清理。此外還可以將其設置為“compact”,以便在需要時保留日志。日志文件清理會消耗CPU和RAM資源,清理、壓縮的頻率和性能需要小心權衡。
?
壓縮是Kafka確保每個消息鍵至少保留最后一個已知值的過程(在單個Topic分區的數據日志中)。壓縮操作會對Topic中每個鍵進行處理,只保留其最后一個值,并清除所有其他重復項。在刪除時,鍵值會被設為“null”(它被稱為“tombstone”,形象地表示刪除)。
?
圖1- Kafka日志壓縮過程
Kafka日志相關參考文檔:
Log
Compaction Basics
雖然許多不熟悉Kafka的團隊會高估它的硬件需求,但實際上Kafka開銷很低而且在設計上對水平擴展很友好。這使得使用廉價的硬件就可以高效地運行Kafka:
- CPU:除非需要SSL和日志壓縮,否則Kafka不需要強大的CPU。同時,使用的核越多,并行性越好。在大多數情況下,可以使用LZ4來提升性能。
- RAM:在大多數情況下,Kafka可以使用6GB的RAM來優化堆空間。對于特別重的生產負載,使用32GB或更多。額外的RAM將用于支持OS頁面緩存和提高客戶機吞吐量。雖然Kafka可以用更少的RAM運行,但是當可用內存更少時,它處理負載的能力就會受到限制。
- Disk:Kafak在RAID設置中使用多個驅動器時非常有用。RAID在底層實現了物理磁盤的負載均衡和冗余,雖然會犧牲一些磁盤空間和寫入性能。在配置中使用多目錄,每個目錄掛在在不同的磁盤(或者RAID)上。由于Kafka的順序磁盤I/O范式,SSD沒有提供多少優勢,此外不應該使用NAS(注2)。
- Network & File:建議使用XFS(注3),如果環境允許,建議將集群部署在單個數據中心。與此同時傳輸的網絡帶寬應盡可能充足。
注2:NAS(Network Attached Storage:網絡附屬存儲):連接在網絡上具備資料存儲功能的裝置,也稱為“網絡存儲器”。它是專用數據存儲服務器,將存儲設備與服務器徹底分離,集中管理數據。
注3:XFS是一個64位文件系統,最大支持 8exbibytes 減1字節的單個文件系統,實際部署時取決于宿主操作系統的最大塊限制。對于一個32位Linux系統,文件和文件系統的大小會被限制在 16tebibytes。
?
Apache Kafka官網還包含專門的硬件和OS配置內容,其中提供了寶貴的建議。關于Kafka負載/性能測試的其他有用鏈接如下:
Benchmarking Apache Kafka: 2 Million Writes Per Second (On Three Cheap Machines)
Load Testing Apache Kafka on AWS
Performance testing
運行的Apache ZooKeeper集群是運行Kafka的關鍵依賴項。但是當使用ZooKeeper和Kafka一起使用時,有一些重要的最佳實踐需要注意。
?
ZooKeeper節點的數量一般最多5個。一個節點適合于開發環境,對于大多數生產環境三個節點的Kafka集群足夠了。雖然大型Kafka部署可能需要5個ZooKeeper節點來減少延遲,但是必須考慮節點上的負載。如果7個或更多的節點同步和處理請求,整個系統的負載將變得非常大,性能可能會有明顯的影響。(雖然最新版本的Kafka在Zookeeper上的負載要比以前版本低得多,以前的版本使用Zookeeper來存儲消費偏移量。)
?
最后正如Kafka的硬件需求一樣,為ZooKeeper提供盡可能充足的網絡帶寬。使用最好的磁盤、單獨存儲日志、隔離ZooKeeper進程和禁用交換也會減少延遲。下表突出顯示了不同Kafka版本中依賴Zookeeper的一些控制臺操作。早期版本0.8.0在控制臺沒有很多可用的功能。從0.10.0.0開始,我們可以看到一些主要的功能移出了Zookeeper,從而降低了Zookeeper的利用率。
?
?
適當的管理意味著Kafka部署的彈性,一個重要實踐是將Kafka默認復制因子從2增加到3,這在大多數生產環境中都是合適的。這樣做可以確保即使其中一個broker失效也不用擔心,甚至損失兩個broker也不會影響系統的可用性。另一個需要考慮的是數據中心機架區域。例如,如果使用AWS, Kafka服務器應該位于相同的區域,但同時也要考慮多個可用性區域來實現冗余和彈性。
?
機架部署需要考慮的Kafka配置參數為:
broker.rack=rack-id
正如Apache Kafka文檔中所述:
When a topic is created, modified or replicas are redistributed, the rack constraint will be honoured, ensuring replicas span as many racks as they can (a partition will span min(#racks, replication-factor) different racks).
一個例子:
考慮三個機架上分布的9個Kafka代理(B1-B9),如下圖所示:
?
圖2- Kafka集群具有機架感知
?
圖中具有三個分區(P1、P2、P3)和復制因子為3 (R1、R2、R3)的單個Topic將為每個機架中的一個節點分配一個分區。這個場景提供了高可用性,每個分區都有兩個副本,即使整個機架故障(如圖上所示)。
?
Topic配置對Kafka集群的性能有很大的影響。由于上生產之后再對復制因子或分區計數等設置的進行更改,有可能影響線上,因此盡可能在初始時就以正確的方式估算并設置好配置。如果需要更改或創建新Topic,確保在Stage環境中測試該新Topic。
?
把復制因子改為3時,在處理大型消息時要深思。如果可能的話,將大消息分成有序的多個片段,或者使用指向數據的指針(例如主鍵)。如果這些方式都無法采用,建議在生產端啟用壓縮。默認的日志段大小是1 GB,如果消息更大,必須仔細分析業務場景。分區(Partition)計數也是一個非常重要的設置,將在下一節詳細討論。
?
Topic配置有默認值,可以在創建時覆蓋,也可以在稍后進行特定配置時覆蓋。如上所述,最重要的配置之一是復制因子(replication factor)。以下示例演示了從控制臺創建Topic,復制因子為3,以及使用其他“Topic級別”配置的3個分區:
bin/kafka-topics.sh --zookeeper ip_addr_of_zookeeper:2181 --create --topic my-topic --partitions 3 --replication-factor 3 --config max.message.bytes=64000 --config flush.messages=1
獲取Topic級別配置的完整列表可以參考官方文檔。
?
Kafka是為并行處理而設計的,就像并行化本身一樣,充分發揮它需要掌握平衡的藝術。分區計數是一個Topic級設置,分區越多,并行化和吞吐量越大。然而分區還意味著更多的復制延遲、重新負載均衡和大量文件句柄。
?
找到最佳分區設置并不復雜,可以計算基于當前硬件期望達到的吞吐量,然后計算所需的分區數量。根據保守的估計,單個Topic上一個分區可以交付10MB /s,以此進行推斷,可以獲得所需的總吞吐量。另一種方法是為每個broker每個Topic使用一個分區,然后進行性能測試并檢查結果,如果需要更大的吞吐量,則將分區加倍。
?
Overall, a useful rule here is to aim to keep total partitions for a topic below 10, and to keep total partitions for the cluster below 10,000. If you don’t, your monitoring must be highly capable and ready to take on what can be very challenging rebalances and outages!
The number of partitions is set while creating a Kafka topic as shown below.
一般來說,Topic的總分區建議保持在10以下,并將集群的總分區保持在10,000以下。如果分區數遠多于此,那么必須做好完善的監控并且服務中斷做好預案。
?
以下是在創建Kafka主題時設置分區的數量:
bin/kafka-topics.sh --zookeeper ip_addr_of_zookeeper:2181 --create --topic my-topic --partitions 3 --replication-factor 3 --config max.message.bytes=64000 --config flush.messages=1
?
此外,也可以在創建之后增加分區計數。但是它會影響消費端,因此建議在考慮清楚所有后果之后再執行此操作。
bin/kafka-topics.sh --zookeeper zk_host:port/chroot --alter --topic topic_name --partitions new_number_of_partitions
?
Kafka安全部署主要兩點:1) Kafka的內部配置,2) Kafka運行的基礎設施。
Kafka .9版本包含了許多有價值的安全特性,例如Kafka/client和Kafka/ZooKeeper身份驗證支持,以及TLS支持。雖然TLS會對吞吐量和性能帶來成本,但它有效地地隔離和保護Kafka broker的流量。
?
隔離卡Kafka和ZK對安全至關重要。除了特殊情況,ZK不應該連接到公網,應該只和Kafka溝通(如有共用情況則另說)。防火墻和安全組應該隔離Kafka和ZooKeeper,將broker駐留在私有網絡中并拒絕外部連接。中間件或負載平衡層應該將Kafka與公網客戶端隔離。
Kafka的安全選項和協議如下:
- SSL/SASL:客戶端到代理、內部代理、代理到工具的身份驗證。
- SSL:客戶端到代理之間、代理之間以及工具到代理之間的數據加密
- SASL類型:SASL/GSSAPI (Kerberos)、SASL/PLAIN、SASL/沖壓- sha -512/沖壓- sha -256、sasl_auth載體
- Zookeeper安全性:客戶端的身份驗證(代理、工具、生產者、消費者),ACL授權。
使用SASL_SSL進行安全設置的示例配置:
#Broker configuration listeners=SSL://host.name:port,SASL_SSL://host.name:port advertised.listeners=SSL://host.name:port,SASL_SSL://host.name:port
security.protocol=SASL_SSL security.inter.broker.protocol=SSL listener.security.protocol.map=INTERBROKER\:SSL,PUBLIC_CLIENT\: SASL_PLAINTEXT,PRIVATE_CLIENT\:SASL_PLAINTEXT ssl.keystore.location=/var/private/ssl/server.keystore.jks
ssl.keystore.password=test1234?ssl.key.password=test1234
ssl.truststore.location=/var/private/ssl/server.truststore.jks
ssl.truststore.password=test1234 sasl.mechanism.inter.broker.protocol=PLAIN sasl.enabled.mechanisms=PLAIN
#Client Configuration (jaas file) sasl.mechanism=PLAIN
sasl.jaas.config=org.apache.kafka.common.security.plain.PlainLoginModule required \
username="[USER NAME]" \
password="[USER PASSWORD]";
?
常見的問題場景:broker由于負載太高而下線,本質上是由于占用了大量文件句柄導致的錯誤。通過編輯/etc/sysctl.conf并將Ulimit配置為允許128,000個或更多的打開文件,可以避免這種錯誤。
增加CentOS的ulimit的一個例子:
1)創建新文件/etc/security/limits.d/nofile.conf
2)輸入以下內容:
* soft nofile 128000
* hard nofile 128000
3)重啟系統或服務。
4)通過以下命令進行驗證。
*ulimit -a
*以外還有很多方法可以增加ulimit。可以針對實際的Linux發行版,使用任何合適的方法。
?
為了降低Kafka部署的延遲,確保broker在地理上位于離客戶最近的區域,并確保在選擇云服務商提供的實例時考慮網絡性能。如果硬件、帶寬等因素影響服務質量,可以考慮在基礎設施及硬件上進行有價值的投資。
?
在創建Kafka集群時,遵循上面的實踐可以避免許多問題,但仍要保持警惕,在問題出現之前識別并正確處理。
?
監視系統指標(如網絡吞吐量、打開的文件句柄、內存、負載、磁盤使用情況及其他因素),監視JVM統計數據(包括GC和堆使用情況)等都是必要的。儀表板和歷史記錄工具可以大大提高問題發現的時效。與此同時,可以通過Nagios或PagerDuty等系統配置延遲峰值或磁盤空間不足等預警,以便在問題如滾雪球一樣越滾越大之前得到妥善解決。
?
通過Instaclustr控制臺顯示的Kafka監控圖示例:
?
?
?
?
原文作者:Ben Bromhead? 譯者:江瑋
原文鏈接:https://www.infoq.com/articles/apache-kafka-best-practices-to-optimize-your-deployment
版權聲明:本文版權歸作者(譯者)及公眾號所有,歡迎轉載,但未經作者(譯者)同意必須保留此段聲明,且在文章頁面明顯位置給出,本文鏈接如有問題,可留言咨詢。
轉載于:https://www.cnblogs.com/davidwang456/p/10307481.html
總結
以上是生活随笔為你收集整理的Apache Kafka: 优化部署的10个最佳实践的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 经济学人使用Golang构建微服务历程回
- 下一篇: Go语言程序结构分析初探