天天看點

Kafka Consumer介紹

Kafka consumer消費消息時,向broker發出"fetch"請求去消費特定分區的消息。consumer指定消息在日志中的偏移量(offset),就可以消費從這個位置開始的消息。 customer擁有了offset的控制權 ,可以向後復原去重新消費之前的消息,這是很有意義的。

推還是拉? Kafka最初考慮的問題是,customer應該從brokes拉取消息還是brokers将消息推送到consumer,也就是pull還push。在這方面,Kafka遵循了一種大部分消息系統共同的傳統的設計:producer将消息推送到broker,consumer從broker拉取消息。

Pull有個缺點是,如果broker沒有可供消費的消息,将導緻consumer不斷在循環中輪詢,直到新消息到t達。為了避免這點,Kafka有個參數可以讓consumer阻塞知道新消息到達(當然也可以阻塞知道消息的數量達到某個特定的量這樣就可以批量發送)。 解讀: 這不就是阻塞隊列麼。。。

消費狀态跟蹤 對消費消息狀态的記錄也是很重要的。 大部分消息系統在broker端的維護消息被消費的記錄:一個消息被分發到consumer後broker就馬上進行标記或者等待customer的通知後進行标記。這樣也可以在消息在消費後立馬就删除以減少空間占用。 但是這樣會不會有什麼問題呢? 如果一條消息發送出去之後就立即被标記為消費過的,一旦consumer處理消息時失敗了(比如程式崩潰)消息就丢失了。為了解決這個問題,很多消息系統提供了另外一個個功能:當消息被發送出去之後僅僅被标記為已發送狀态,當接到consumer已經消費成功的通知後才标記為已被消費的狀态。這雖然解決了消息丢失的問題,但産生了新問題,首先如果consumer處理消息成功了但是向broker發送響應時失敗了,這條消息将被消費兩次。第二個問題時,broker必須維護每條消息的狀态,并且每次都要先鎖住消息然後更改狀态然後釋放鎖。這樣麻煩又來了,且不說要維護大量的狀态資料,比如如果消息發送出去但沒有收到消費成功的通知,這條消息将一直處于被鎖定的狀态, Kafka采用了不同的政策。Topic被分成了若幹分區,每個分區在同一時間隻被一個consumer消費。這意味着每個分區被消費的消息在日志中的位置僅僅是一個簡單的整數: offset 。這樣就很容易标記每個分區消費狀态就很容易了, 僅僅需要一個整數而已。這樣消費狀态的跟蹤就很簡單了。