kafka概念掃盲

1、kafka概述

1.一、定義

Kakfa是一個分佈式的基於發佈/訂閱模式的消息隊列(message queue),主要應用於大數據的實時處理領域python

1.二、消息隊列

1.2.一、傳統的消息隊列&新式的消息隊列的模式

 

 

 

上面是傳統的消息隊列,好比一個用戶要註冊信息,當用戶信息寫入數據庫後,後面還有一些其餘流程,好比發送短信,則須要等這些流程處理完成後,在返回給用戶數據庫

而新式的隊列是,好比一個用戶註冊信息,數據直接丟進數據庫,就直接返回給用戶成功微信

1.2.二、使用消息隊列的好處

A、        解耦網絡

B、        可恢復性架構

C、        緩衝併發

D、        靈活性&峯值處理能力異步

E、         異步通訊分佈式

 

1.2.三、消息隊列的模式

A、點對點模式性能

消息生產者發送消息到消息隊列中,而後消息消費者從隊列中取出而且消費消息,消息被消費後,隊列中不在存儲。因此消息消費者不可能消費到已經被消費的消息;隊列支持存在多個消費者,可是對於一個消息而言,只會 有一個消費者能夠消費;若是想發給多個消費者,則須要屢次發送該條消息測試

B】發佈/訂閱模式(一對多,消費者消費數據以後不會清除消息)

消息生產者將消息發佈到topic中,同時有多個消息消費者(訂閱)消費該消息,和點對點的方式不一樣,發佈到topic的消息會被全部的訂閱者消費;可是數據保留是期限的,默認是7天,由於他不是存儲系統;kafka就是這種模式的;有兩種方式,一種是是消費者去主動去消費(拉取)消息,而不是生產者推送消息給消費者;另一種就是生產者主動推送消息給消費者,相似公衆號

 

1.三、kafka的基礎架構

 

 

 

kafka的基礎架構主要有broker、生產者、消費者組構成,當前還包括zookeeper

生產者負責發送消息

broker負責緩衝消息,broker中能夠建立topic,每一個topic又有partition和replication的概念

消費者組負責處理消息,同一個消費者組的中消費者不能消費同一個partition中的數據,消費者組主要是提升消費能力,好比以前是一個消費者消費100條數據,如今是2個消費者消費100條數據,能夠提升消費能力;因此消費者組的消費者的個數要小於partition的個數,否則就會有消費者沒有partition能夠消費,形成資源的浪費

注:可是不一樣的消費者組的消費者是能夠消費相同的partition數據

Kakfa若是要組件集羣,則只須要註冊到一個zk中就能夠了,zk中還保留消息消費的進度或者說偏移量或者消費位置

0.9版本以前偏移量存儲在zk

0.9版本以後偏移量存儲在kafka中,kafka定義了一個系統的topic,專用用來存儲偏移量的數據;

爲何要改?主要是考慮到頻繁更改偏移量,對zk的壓力較大,並且kafka自己本身的處理也較複雜

 

1.四、kafka安裝

A、Kafka的安裝只須要解壓安裝包就能夠完成安裝

tar -zxvf kafka_2.11-2.1.1.tgz -C /usr/local/

  

B、查看配置文件

[root@es1 config]# pwd
/usr/local/kafka/config
[root@es1 config]# ll
total 84
-rw-r--r--. 1 root root  906 Feb  8  2019 connect-console-sink.properties
-rw-r--r--. 1 root root  909 Feb  8  2019 connect-console-source.properties
-rw-r--r--. 1 root root 5321 Feb  8  2019 connect-distributed.properties
-rw-r--r--. 1 root root  883 Feb  8  2019 connect-file-sink.properties
-rw-r--r--. 1 root root  881 Feb  8  2019 connect-file-source.properties
-rw-r--r--. 1 root root 1111 Feb  8  2019 connect-log4j.properties
-rw-r--r--. 1 root root 2262 Feb  8  2019 connect-standalone.properties
-rw-r--r--. 1 root root 1221 Feb  8  2019 consumer.properties
-rw-r--r--. 1 root root 4727 Feb  8  2019 log4j.properties
-rw-r--r--. 1 root root 1925 Feb  8  2019 producer.properties
-rw-r--r--. 1 root root 6865 Jan 16 22:00 server-1.properties
-rw-r--r--. 1 root root 6865 Jan 16 22:00 server-2.properties
-rw-r--r--. 1 root root 6873 Jan 16 03:57 server.properties
-rw-r--r--. 1 root root 1032 Feb  8  2019 tools-log4j.properties
-rw-r--r--. 1 root root 1169 Feb  8  2019 trogdor.conf
-rw-r--r--. 1 root root 1023 Feb  8  2019 zookeeper.properties

  

C、修改配置文件server.properties

設置broker.id 這個是kafka集羣區分每一個節點的惟一標誌符

 

 

 

D、設置kafka的數據存儲路徑

 

 

 

注:這個目錄下不能有其餘非kafka的目錄,否則會致使kafka集羣沒法啓動

E、設置是否能夠刪除topic,默認狀況先kafka的topic是不容許刪除的

 

 

 

 

F、Kafka的數據保留的時間,默認是7天

 

 

 

G、Log文件最大的大小,若是log文件超過1g會建立一個新的文件

 

 

 

 

 

 

H、Kafka鏈接的zk的地址和鏈接kafka的超時時間

 

 

 

J、默認的partition的個數

 

 

 

1.五、啓動kafka

A、啓動方式1,kafka只能單節點啓動,因此每一個kakfa節點都須要手動啓動,下面的方式阻塞的方式啓動

 

 

 

B、啓動方式2,守護的方式啓動,推薦

 

 

 

1.六、kafka操做

A、查看當前kafka集羣已有的topic

 

 

 

注意:這裏鏈接的zookeeper,而不是鏈接的kafka

B、建立topic,指定分片和副本個數

 

 

 

注:

replication-factor:副本數

replication-factor:分區數

Topic:主題名

若是當前kafka集羣只有3個broker節點,則replication-factor最大就是3了,下面的例子建立副本爲4,則會報錯

 

 

 

C、刪除topic

 

 

 

D、查看topic信息

 

 

 

 

 

 

 

1.七、啓動生產者生產消息,kafka自帶一個生產者和消費者的客戶端

A、啓動一個生產者,注意此時連的9092端口,鏈接的kafka集羣

 

 

 

B、啓動一個消費者,注意此時鏈接的仍是9092端口,在0.9版本以前鏈接的仍是2181端口

 

 

 

這裏咱們啓動2個消費者來測試一下

 

 

 

注:若是不指定的消費者組的配置文件的話,默認每一個消費者都屬於不一樣的消費者組

C、發送消息,能夠看到每一個消費者都能收到消息

 

 

 

 

 

 

 

 

 

D、Kakfa中的實際的數據

 

 

 

 

 

 

2、kafka架構深刻

 

 

 

 

Kafka不能保證消息的全局有序,只能保證消息在partition內有序,由於消費者消費消息是在不一樣的partition中隨機的

2.一、kafka的工做流程

Kafka中的消息是以topic進行分類的,生產者生成消息,消費者消費消息,都是面向topic的

 

 

 

 

Topic是一個邏輯上的概念,而partition是物理上的概念

每一個partition又有副本的概念

每一個partition對應於一個log文件,該log文件中存儲的就是生產者生成的數據,生產者生成的數據會不斷的追加到該log的文件末端,且每條數據都有本身的offset,消費者都會實時記錄本身消費到了那個offset,以便出錯的時候從上次的位置繼續消費,這個offset就保存在index文件中

kafka的offset是分區內有序的,可是在不一樣分區中是無順序的,kafka不保證數據的全局有序

2.二、kafka原理

因爲生產者生產的消息會不斷追加到log文件的末尾,爲防止log文件過大致使數據定位效率低下,Kafka採用分片和索引的機制,將每一個partition分爲多個segment,每一個segment對應2個文件----index文件和log文件,這2個文件位於一個相同的文件夾下,文件夾的命名規則爲topic名稱+分區序號

 

 

Indx和log的文件的文件名是當前這個索引是最小的數據的offset

Kafka如何快速的消費數據呢?

 

 

Index文件中存儲的數據的索引信息,第一列是offset,第二列這這個數據所對應的log文件中的偏移量,就像咱們去讀文件,使用seek()設置當前鼠標的位置同樣,能夠更快的找到數據

若是要去消費offset爲3的數據,首先經過二分法找到數據在哪一個index文件中,而後在經過index中offset找到數據在log文件中的offset;這樣就能夠快速的定位到數據,並消費

因此kakfa雖然把數據存儲在磁盤中,可是他的讀取速度仍是很是快的

 

3、kafka的生產者和消費者

3.一、kafka的生產者

Kafka的partition的分區的做用

Kafka的分區的緣由主要就是提供併發提升性能,由於讀寫是partition爲單位讀寫的;

那生產者發送消息是發送到哪一個partition中呢?

A、在客戶端中指定partition

B、輪詢(推薦)消息1去p1,消息2去p2,消息3去p3,消息4去p1,消息5去p2,消息6去p3 。。。。。。。

 

3.2 kafka如何保證數據可靠性呢?經過ack來保證

爲保證生產者發送的數據,能可靠的發送到指定的topic,topic的每一個partition收到生產者發送的數據後,都須要向生產者發送ack(確認收到),若是生產者收到ack,就會進行下一輪的發送,不然從新發送數據

 

 

 

 

那麼kafka何時向生產者發送ack

確保follower和leader同步完成,leader在發送ack給生產者,這樣才能確保leader掛掉以後,能再follower中選舉出新的leader後,數據不會丟失

那多少個follower同步完成後發送ack

方案1:半數已經完成同步,就發送ack

方案2:所有完成同步,才發送ack(kafka採用這種方式)

採用第二種方案後,設想如下場景,leader收到數據,全部的follower都開始同步數據,可是有一個follower由於某種故障,一直沒法完成同步,那leader就要一直等下,直到他同步完成,才能發送ack,這樣就很是影響效率,這個問題怎麼解決?

 

 

Leader維護了一個動態的ISR列表(同步副本的做用),只須要這個列表的中的follower和leader同步;當ISR中的follower完成數據的同步以後,leader就會給生產者發送ack,若是follower長時間未向leader同步數據,則該follower將被剔除ISR,這個時間閾值也是自定義的;一樣leader故障後,就會從ISR中選舉新的leader

怎麼選擇ISR的節點呢?

首先通訊的時間要快,要和leader要能夠很快的完成通訊,這個時間默認是10s

而後就看leader數據差距,消息條數默認是10000條(後面版本被移除)

爲何移除:由於kafka發送消息是批量發送的,因此會一瞬間leader接受完成,可是follower尚未拉取,因此會頻繁的踢出加入ISR,這個數據會保存到zk和內存中,因此會頻繁的更新zk和內存。

 

可是對於某些不過重要的數據,對數據的可靠性要求不是很高,可以容忍數據的少許丟失,因此不必等ISR中的follower所有接受成功

因此kafka爲用戶提供了三種可靠性級別,用戶能夠根據可靠性和延遲進行權衡,這個設置在kafka的生成中設置:acks參數設置

A、acks爲0

生產者不等ack,只管往topic丟數據就能夠了,這個丟數據的機率很是高

B、ack爲1

Leader落盤後就會返回ack,會有數據丟失的現象,若是leader在同步完成後出現故障,則會出現數據丟失

C、ack爲-1(all)

Leader和follower(ISR)落盤纔會返回ack,會有數據重複現象,若是在leader已經寫完成,且follower同步完成,可是在返回ack的出現故障,則會出現數據重複現象;極限狀況下,這個也會有數據丟失的狀況,好比follower和leader通訊都很慢,因此ISR中只有一個leader節點,這個時候,leader完成落盤,就會返回ack,若是此時leader故障後,就會致使丟失數據

 

3.3 Kafka如何保證消費數據的一致性?經過HW來保證

 

 

 

LEO:指每一個follower的最大的offset

HW(高水位):指消費者能見到的最大的offset,LSR隊列中最小的LEO,也就是說消費者只能看到1~6的數據,後面的數據看不到,也消費不了

避免leader掛掉後,好比當前消費者消費8這條數據後,leader掛   了,此時好比f2成爲leader,f2根本就沒有9這條數據,那麼消費者就會報錯,因此設計了HW這個參數,只暴露最少的數據給消費者,避免上面的問題

 

3.3.一、HW保證數據存儲的一致性

A、Follower故障

Follower發生故障後會被臨時提出LSR,待該follower恢復後,follower會讀取本地的磁盤記錄的上次的HW,並將該log文件高於HW的部分截取掉,從HW開始想leader進行同步,等該follower的LEO大於等於該Partition的hw,即follower追上leader後,就能夠從新加入LSR

B、Leader故障

Leader發生故障後,會從ISR中選出一個新的leader,以後,爲了保證多個副本之間的數據一致性,其他的follower會先將各自的log文件高於hw的部分截掉(新leader本身不會截掉),而後重新的leader同步數據

注意:這個是爲了保證多個副本間的數據存儲的一致性,並不能保證數據不丟失或者不重複

 

3.3.2精準一次(冪等性),保證數據不重複

 

Ack設置爲-1,則能夠保證數據不丟失,可是會出現數據重複(at least once)

Ack設置爲0,則能夠保證數據不重複,可是不能保證數據不丟失(at most once)

可是若是魚和熊掌兼得,該怎麼辦?這個時候就就引入了Exactl once(精準一次)

 

在0.11版本後,引入冪等性解決kakfa集羣內部的數據重複,在0.11版本以前,在消費者處本身作處理

若是啓用了冪等性,則ack默認就是-1,kafka就會爲每一個生產者分配一個pid,並未每條消息分配seqnumber,若是pid、partition、seqnumber三者同樣,則kafka認爲是重複數據,就不會落盤保存;可是若是生產者掛掉後,也會出現有數據重複的現象;因此冪等性解決在單次會話的單個分區的數據重複,可是在分區間或者跨會話的是數據重複的是沒法解決的

3.4 kafka的消費者

3.4.1 消費方式

消息隊列有兩種消費消息的方式,push(微信公衆號)、pull(kafka),push模式很難適應消費速率不一樣的消費者,由於消費發送速率是由broker決定的,他的目標是儘量以最快的的速度傳遞消息,可是這樣很容易形成消費者來不及處理消息,典型的表現就是拒絕服務以及網絡擁塞。而pull的方式能夠消費者的消費能力以適當的速率消費消息

Pull的模式不足之處是若是kafka沒有數據,消費者可能會陷入死循環,一直返回空數據,針對這一點,kafka的消費者在消費數據時候回傳遞一個timeout參數,若是當時沒有數據可供消費,消費者會等待一段時間在返回

3.4.2 分區分配策略

一個消費者組有多個消費者,一個topic有多個partition。因此必然會涉及到partition的分配問題,即肯定哪一個partition由哪一個消費者來消費

Kafka提供兩種方式,一種是輪詢(RountRobin)對於topic組生效,一種是(Range)對於單個topic生效

 

輪訓:前置條件是須要一個消費者裏的消費者訂閱的是相同的topic。否則就會出現問題;非默認的的方式

 

同一個消費者組裏的消費者不能同時消費同一個分區

好比三個消費者消費一個topic的9個分區

 

 

 

 

若是一個消費者組裏有2個消費者,這個消費者組裏同時消費2個topic,每一個topic又有三個partition

首先會把2個topic當作一個主題,而後根據topic和partition作hash,而後在按照hash排序。而後輪訓分配給一個消費者組中的2個消費者

 

若是是下面這樣的方式訂閱的呢?

好比有3個topic,每一個topic有3個partition,一個消費者組中有2個消費者。消費者1訂閱topic1和topic2,消費者2訂閱topic2和topic3,那麼這樣的場景,使用輪訓的方式訂閱topic就會有問題

 

若是是下面這種方式訂閱呢

好比有2個topic,每一個topic有3個partition,一個消費者組 有2個消費者,消費者1訂閱topic1,消費者2訂閱topic2,這樣使用輪訓的方式訂閱topic也會有問題

 

因此咱們一直強調,使用輪訓的方式訂閱topic的前提是一個消費者組中的全部消費者訂閱的主題是同樣的;

因此輪訓的方式不是kafka默認的方式

Range:是按照單個topic來劃分的,默認的分配方式

 

 

 

 

 

Range的問題會出現消費者數據不均衡的問題

好比下面的例子,一個消費者組訂閱了2個topic,就會出現消費者1消費4個partition,而另一個消費者只消費2個partition

 

 

分區策略何時會觸發呢?當消費者組裏的消費者個數變化的時候,會觸發分區策略調整,好比消費者裏增長消費者,或者減小消費者

3.4.3 offset的維護

因爲消費者在消費過程當中可能會出現斷電宕機等故障,消費者恢復後,須要從故障前的位置繼續消費,因此消費者須要實施記錄本身消費哪一個offset,以便故障恢復後繼續消費

Offset保存的位置有2個,一個zk,一個是kafka

首先看下offset保存到zk

由消費者組、topic、partition三個元素肯定惟一的offset

 

因此消費者組中的某個消費者掛掉以後,或者的消費者仍是能夠拿到這個offset的

 

 

Controller這個節點和zk通訊,同步數據,這個節點就是誰先起來,誰就先註冊controller,誰就是controller。其餘節點和controller信息保持同步

 

3.4.五、消費者組的案例

修改消費者組id

 

 

啓動一個消費者發送3條數據

 

 

指定消費者組啓動消費者,啓動三個消費者,能夠看到每一個消費者消費了一條數據

 

 

 

 

 

 

 

在演示下不一樣組能夠消費同一個topic的,咱們看到2個消費者的消費者都消費到同一條數據

再次啓動一個消費者,這個消費者屬於另一個消費者組

 

 

 

 

4、Kafka的高效讀寫機制

4.一、分佈式部署

多節點並行操做

 

4.二、順序寫磁盤

Kafka的producer生產數據,要寫入到log文件中,寫的過程當中一直追加到文件末尾,爲順序寫,官網有數據代表。一樣的磁盤,順序寫能到600M/S,而隨機寫只有100K/S。這與磁盤的機械結構有關,順序寫之因此快,是由於其省去了大量磁頭尋址的時間

4.三、零複製技術

正常狀況下,先把數據讀到內核空間,在從內核空間把數據讀到用戶空間,而後在調操做系統的io接口寫到內核空間,最終在寫到硬盤中

 

 

Kafka是這樣作的,直接在內核空間流轉io流,因此kafka的性能很是高

 

 

 

 

5、 zookeeper在kafka中的做用

Kafka集羣中有一個broker會被選舉爲controller,負責管理集羣broker的上下線,全部的topic的分區副本分配和leader選舉等工做

相關文章
相關標籤/搜索