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)的順序。
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都會保留所有消息。有兩種策略可以刪除舊數據:
3)、zookeeper的存儲結構:
4)、kafka消費過程分析:
(1)、高級API優點:
5、可以使用group來區分對同一個topic 的不同程序訪問分離開來(不同的group記錄不同的offset,這樣不同程序讀取同一個topic才不會因為offset互相影響)
(2)、高級API缺點:
2、不能自行控制offset(對於某些特殊需求來說)。
(3)、低級API優點:
(5)、消費者組:
在這種情況下,消費者可以通過水平擴展的方式同時讀取大量的消息。另外,如果一個消費者失敗了,那麼其他的group成員會自動負載均衡讀取之前失敗的消費者讀取的分區。消費者是以consumer group消費者組的方式工作,由一個或者多個消費者組成一個組,共同消費一個topic。每個分區在同一時間只能由group中的一個消費者讀取,但是多個group可以同時消費這個partition。在圖中,有一個由三個消費者組成的group,有一個消費者讀取主題中的兩個分區,另外兩個分別讀取一個分區。某個消費者讀取某個分區,也可以叫做某個消費者是某個分區的擁有者。
(6)、消費方式:
1、consumer採用pull(拉)模式從broker中讀取數據。
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 : 所有副本都寫入成功並確認。
(2)、consumer如果保證數據得不丟失:
enable.auto.commit=false 關閉自動提交offset。
更多文章見:
讓我遇見你。?www.shiruiblog.cn 推薦閱讀: