通常情況下,企業中會采取輪詢或者隨機的方式,通過Kafka的producer向Kafka集群生產數據,來盡可能保證Kafka分區之間的數據是均勻分布的。
在分區數據均勻分布的前提下,如果我們針對要處理的topic數據量等因素,設計出合理的Kafka分區數量。對於一些實時任務,比如Spark Streaming/Structured-Streaming、Flink和Kafka集成的應用,消費端不存在長時間"掛掉"的情況即數據一直在持續被消費,那么一般不會產生Kafka數據積壓的情況。
但是這些都是有前提的,當一些意外或者不合理的分區數設置情況的發生,積壓問題就不可避免。
Kafka消息積壓的典型場景:
1. 實時/消費任務掛掉
比如,我們寫的實時應用因為某種原因掛掉了,並且這個任務沒有被監控程序監控發現通知相關負責人,負責人又沒有寫自動拉起任務的腳本進行重啟。
那么在我們重新啟動這個實時應用進行消費之前,這段時間的消息就會被滯后處理,如果數據量很大,可就不是簡單重啟應用直接消費就能解決的。
2. Kafka分區數設置的不合理(太少)和消費者"消費能力"不足
Kafka單分區生產消息的速度qps通常很高,如果消費者因為某些原因(比如受業務邏輯復雜度影響,消費時間會有所不同),就會出現消費滯后的情況。
此外,Kafka分區數是Kafka並行度調優的最小單元,如果Kafka分區數設置的太少,會影響Kafka consumer消費的吞吐量。
3. Kafka消息的key不均勻,導致分區間數據不均衡
在使用Kafka producer消息時,可以為消息指定key,但是要求key要均勻,否則會出現Kafka分區間數據不均衡。
那么,針對上述的情況,有什么好的辦法處理數據積壓呢?
一般情況下,針對性的解決辦法有以下幾種:
1. 實時/消費任務掛掉導致的消費滯后
a. 任務重新啟動后直接消費最新的消息,對於"滯后"的歷史數據采用離線程序進行"補漏"。
此外,建議將任務納入監控體系,當任務出現問題時,及時通知相關負責人處理。當然任務重啟腳本也是要有的,還要求實時框架異常處理能力要強,避免數據不規范導致的不能重新拉起任務。
b. 任務啟動從上次提交offset處開始消費處理
如果積壓的數據量很大,需要增加任務的處理能力,比如增加資源,讓任務能盡可能的快速消費處理,並趕上消費最新的消息
2. Kafka分區少了
如果數據量很大,合理的增加Kafka分區數是關鍵。如果利用的是Spark流和Kafka direct approach方式,也可以對KafkaRDD進行repartition重分區,增加並行度處理。
3. 由於Kafka消息key設置的不合理,導致分區數據不均衡
可以在Kafka producer處,給key加隨機后綴,使其均衡。
推薦文章:
Kafka分區分配策略(Partition Assignment Strategy)
SparkStreaming和Kafka基於Direct Approach如何管理offset
如何為Kafka集群確定合適的分區數以及分區數過多帶來的弊端
關注微信公眾號:大數據學習與分享,獲取更對技術干貨