一、kafka概述:

1、消息隊列:

1)、原理及其有點:

客戶端消費Queue種的數據有兩種方式:1、發布/訂閱模式,也就是一對多,數據生產之後,推給所有的訂閱者,打個比方:就像是手機上面的QQ消息,你沒有打開手機看消息,但是如果有消息就會一直有消息推送過來。2、點對點模式,也就是一對一,這個是主動模式,第一種模式更像是被動模式,這個就是消費者主動拉取生產後的數據。

2、消息隊列的優點:

1)、解耦。2)、冗餘。3)、擴展性。4)、靈活性and峰值處理能力。5)、可恢復性。6)、順序保證。(ps:kafka保證一個partition內的數據是有序的)7)、緩衝。8)、非同步通信。

3、kafka基本術語:

1)、無論是kafka集群還是consumer,都依賴zookeeper集群來保存一些meta信息。

2)、Producer:消息生產者,向kafka broker發消息的客戶端。

3)、consumer:消息消費者,向kafka broker取消息的客戶端。

4)、Topic:可以理解是一個隊列,一個topic里有很多個partition。

5)、consumer group:這是kafka用來實現topic廣播的和單播的手段。topic的消息會複製(不是真正的複製)到所有的CG,但是每個partition只會把消息發給該CG中的一個consumer。廣播的實現方法是:只要每個consumer有一個獨立的CG就行了。單播的實現方法是:只要所有的consumer在同一個CG。

6)、Broker:一台kafka伺服器就是一個broker,一個集群由多個broker。一個broker可以容納多個topic。

7)、partition:一個非常大惡的topic可以分布在多個broker上,一個topic可以分成多個partition,每個partition是一個有序隊列。partition中的每條消息都會被分配一個有序的ID,kafka只保證按一個partition中的順序將消息發給consumer,不保證一個topic的整體(多個partition)的順序。

二、kafka工作流程:

1、Kafka生產過程:

1)、producer採用推(push)模式將消息發布到broker,每條消息都被追加(append)到分區(patition)中,屬於順序寫磁碟(順序寫磁碟效率比隨機寫內存要高,保障kafka吞吐率)。

2)、分區:消息發送時都被發送到一個topic,其本質就是一個目錄,而topic是由一些Partition Logs(分區日誌)組成。

我們可以看到,每個Partition中的消息都是有序的,生產的消息被不斷追加到Partition log上,其中的每一個消息都被賦予了一個唯一的offset值。

①分區的原因:1、方便在集群中擴展,每個Partition可以通過調整以適應它所在的機器,而一個topic又可以有多個Partition組成,因此整個集群就可以適應任意大小的數據了;2、可以提高並發,因為可以以Partition為單位讀寫了。

②分區的原則:1、指定了patition,則直接使用;2、未指定patition但指定key,通過對key的value進行hash出一個patition;3、patition和key都未指定,使用輪詢選出一個patition。

3)、副本:

同一個partition可能會有多個replication,沒有replication的情況下,一旦broker 宕機,其上所有 patition 的數據都不可被消費,同時producer也不能再將數據存於其上的patition,沒有replication的情況下,一旦broker 宕機,其上所有 patition 的數據都不可被消費,同時producer也不能再將數據存於其上的patition。

4)、寫入流程:

2、Broker保存消息:

1)、存儲方式:

物理上把topic分成一個或多個patition,每個patition物理上對應一個文件夾(該文件夾存儲該patition的所有消息和索引文件)。

2)、存儲策略:

無論消息是否被消費,kafka都會保留所有消息。有兩種策略可以刪除舊數據:

1)基於時間:log.retention.hours=1682)基於大小:log.retention.bytes=1073741824需要注意的是,因為Kafka讀取特定消息的時間複雜度為O(1),即與文件大小無關,所以這裡刪除過期文件與提高 Kafka 性能無關。

3)、zookeeper的存儲結構:

4)、kafka消費過程分析:

(1)、高級API優點:

1、高級API 寫起來簡單2、不需要自行去管理offset,系統通過zookeeper自行管理。3、不需要管理分區,副本等情況,.系統自動管理。4、消費者斷線會自動根據上一次記錄在zookeeper中的offset去接著獲取數據(默認設置1分鐘更新一下zookeeper中存的offset)。

5、可以使用group來區分對同一個topic 的不同程序訪問分離開來(不同的group記錄不同的offset,這樣不同程序讀取同一個topic才不會因為offset互相影響)

(2)、高級API缺點:

1、不能細化控制如分區、副本、zk等。

2、不能自行控制offset(對於某些特殊需求來說)。

(3)、低級API優點:

1、能夠讓開發者自己控制offset,想從哪裡讀取就從哪裡讀取。2、自行控制連接分區,對分區自定義進行負載均衡3、對zookeeper的依賴性降低(如:offset不一定非要靠zk存儲,自行存儲offset即可,比如存在文件或者內存中)(4)低級API缺點1、太過複雜,需要自行控制offset,連接哪個分區,找到分區leader 等。

(5)、消費者組:

在這種情況下,消費者可以通過水平擴展的方式同時讀取大量的消息。另外,如果一個消費者失敗了,那麼其他的group成員會自動負載均衡讀取之前失敗的消費者讀取的分區。消費者是以consumer group消費者組的方式工作,由一個或者多個消費者組成一個組,共同消費一個topic。每個分區在同一時間只能由group中的一個消費者讀取,但是多個group可以同時消費這個partition。在圖中,有一個由三個消費者組成的group,有一個消費者讀取主題中的兩個分區,另外兩個分別讀取一個分區。某個消費者讀取某個分區,也可以叫做某個消費者是某個分區的擁有者。

(6)、消費方式:

1、consumer採用pull(拉)模式從broker中讀取數據。

2、push(推)模式很難適應消費速率不同的消費者,因為消息發送速率是由broker決定的。它的目標是儘可能以最快速度傳遞消息,但是這樣很容易造成consumer來不及處理消息,典型的表現就是拒絕服務以及網路擁塞。而pull模式則可以根據consumer的消費能力以適當的速率消費消息。3、對於Kafka而言,pull模式更合適,它可簡化broker的設計,consumer可自主控制消費消息的速率,同時consumer可以自己控制消費方式——即可批量消費也可逐條消費,同時還能選擇不同的提交方式從而實現不同的傳輸語義。4、pull模式不足之處是,如果kafka沒有數據,消費者可能會陷入循環中,一直等待數據到達。為了避免這種情況,我們在我們的拉請求中有參數,允許消費者請求在等待數據到達的「長輪詢」中進行阻塞(並且可選地等待到給定的位元組數,以確保大的傳輸大小)。

三、kafka消息保證機制:

1、At most once:消息可能會丟,但是絕對不會重複傳遞。

讀完消息之後先commit然後再處理消息,在這種模式下comsumer在commit後還沒有來得及處理就crash了,下次重新開始工作之後無法讀到剛剛已提交而未處理的消息,這就對應了At most once。

2、At least once:消息絕對不會丟,但是可能重複傳遞。

讀完消息之後先處理消息然後再commit,如果在消息處理之後commite之前crash,下次重新開始工作的時候剛剛處理未提交commit消息,但是實際上該消息已經被處理過,這就對應了At least once。

3、Exactly once:每條消息之傳輸一次僅被傳輸一次。

如果要做到Exactly once,那麼就需要offset來幫助實現,通用的方式是將offset和操作輸出輸出到同一個地方,但是對於high API來說,offset是保存在zk中的,無法輸出到同一個低方,lower API是自己維護offset的,可以將它存在同一個地方,一般存在HDFS。

4、如何保證數據不丟失:

(1)、broker如何保證數據的不丟失:

acks=all : 所有副本都寫入成功並確認。

retries = 一個合理值。min.insync.replicas=2 消息至少要被寫入到這麼多副本才算成功。unclean.leader.election.enable=false 關閉unclean leader選舉,即不允許非ISR中的副本被選舉為leader,以避免數據丟失。

(2)、consumer如果保證數據得不丟失:

enable.auto.commit=false 關閉自動提交offset。

更多文章見:

讓我遇見你。?

www.shiruiblog.cn圖標
推薦閱讀:

相关文章