Kakfa在大數據消息引擎領域,絕對是沒有爭議的國民老公。mysql
這是kafka系列的第一篇文章。預計共出20篇系列文章,所有原創,從0到1,跟你一塊兒死磕kafka。sql
本文盤點了 Kafka 的各類術語而且進行解讀,術語可能比較枯燥,但真的是精髓中的精髓!數據庫
瞭解Kafka以前咱們必須先掌握它的相關概念和術語,這對於後面深刻學習 Kafka 各類功能將大有裨益。因此,枯燥你也得給我看完!編程
大概是有這麼些東西要掌握,很少很少,預計20分鐘能夠吃透:數組
主題層有三個兒子,分別叫作:Topic、Partition、Replica。既然我說是三個兒子,那你懂了,是不可分割的總體。緩存
Kafka 是分佈式的消息引擎系統,它的主要功能是提供一套完備的消息(Message)發佈與訂閱解決方案。服務器
在 Kafka 中,發佈訂閱的對象是主題(Topic),你能夠爲每一個業務、每一個應用甚至是每類數據都建立專屬的主題。網絡
一個Topic是對一組消息的概括。也能夠理解成傳統數據庫裏的表,或者文件系統裏的一個目錄。架構
一個Topic一般都是由多個partition組成的,建立topic時候能夠指定partition數量。負載均衡
📷 分區優點
爲何須要將Topic分區呢?若是你瞭解其餘分佈式系統,你可能據說過度片、分區域等說法,好比 MongoDB 和 Elasticsearch 中的 Sharding、HBase 中的 Region,其實它們都是相同的原理。
試想,若是一個Topic積累了太多的數據以致於單臺 Broker 機器都沒法容納了,此時應該怎麼辦呢?
一個很天然的想法就是,可否把數據分割成多份保存在不一樣的機器上?這不就是分區的做用嗎?其實就是解決伸縮性的問題,每一個partition均可以放在獨立的服務器上。
固然優點不只於此,也能夠提升吞吐量。kafka只容許單個partition的數據被一個consumer線程消費。所以,在consumer端,consumer並行度徹底依賴於被消費的分區數量。綜上所述,一般狀況下,在一個Kafka集羣中,partition的數量越多,意味着能夠到達的吞吐量越大。
📷 partition結構
每一個partition對應於一個文件夾,該文件夾下存儲該partition的數據和索引文件。
如圖所示,能夠看到兩個文件夾,都對應着一個叫作asd的topic,在該臺服務器上有兩個分區,0和2,那麼1呢?在其餘服務器上啦!畢竟是分佈式分佈的!
咱們進去asd-0目錄中看看是什麼?有後綴爲.index和.log的文件,他們就是該partition的數據和索引文件:
如今先無論它們是何方神聖,由於我會在【分區機制原理】這篇文章中詳細描述。
📷 partition順序性
如今,我須要你睜大眼睛看看關於分區很是重要的一點:
【每一個partition內部保證消息的順序。可是分區之間是不保證順序的】
這一點很重要,例如kafka中的消息是某個業務庫的數據,mysql binlog是有前後順序的,10:01分我沒有付款,因此pay_date爲null,而10:02分我付款了,pay_date被更新了。
但到了kafka那,因爲是分佈式的,多分區的,可就不必定能保證順序了,也許10:02分那條先來,這樣可就會引起嚴重生產問題了。所以,通常咱們須要按表+主鍵來分區。保證同一主鍵的數據發送到同一個分區中。
若是你想要 kafka 中的全部數據都按照時間的前後順序進行存儲,那麼能夠設置分區數爲 1。
每一個partition能夠配置若干個副本。Kafka 定義了兩類副本:領導者副本(Leader Replica)和追隨者副本(Follower Replica)。只能有 1 個領導者副本和 N-1 個追隨者副本。
爲啥要用副本?也很好理解,反問下本身爲何重要的文件須要備份多份呢?備份機制(Replication)是實現高可用的一個手段。
須要注意的是:僅Leader Replica對外提供服務,與客戶端程序進行交互,生產者老是向領導者副本寫消息,而消費者老是從領導者副本讀消息。而Follower Replica不能與外界進行交互,它只作一件事:向領導者副本發送請求,請求領導者把最新生產的消息發給它,保持與領導者的同步。
若是對於剛剛所說的主題、分區、副本還有疑惑,那麼結合下面這張圖再思考一下,我相信你就能夠玩轉它了:
下圖所示,TopicA,具備三個partition,每一個partion都有1 個leader副本和 1 個follower者副本。爲了保證高可用性,一臺機器宕機不會有影響,所以leader副本和follower副本必然分佈在不一樣的機器上。
Kafka的官方定義是message system,由此咱們能夠知道Kafka 中最基本的數據單元無疑是消息message,它可理解成數據庫裏的一條行或者一條記錄。消息是由字符數組組成。關於消息你必須知道這幾件事:
📷 消息key
發送消息的時候指定 key,這個 key 也是個字符數組。key 用來肯定消息寫入分區時,進入哪個分區。你能夠用有明確業務含義的字段做爲key,好比用戶號,這樣就能夠保證同一個用戶號進入同一個分區。
📷 批量寫入
爲了提升效率, Kafka 以批量batch的方式寫入。
一個 batch 就是一組消息的集合, 這一組的數據都會進入同一個 topic 和 partition(這個是根據 producer 的配置來定的) 。
每個消息都進行一次網絡傳輸會很消耗性能,所以把消息收集到一塊兒再同時處理就高效的多。
固然,這樣會引入更高的延遲以及吞吐量:batch 越大,同一時間處理的消息就越多。batch 一般都會進行壓縮,這樣在傳輸以及存儲的時候效率都更高一些。
📷 位移
生產者向分區寫入消息,每條消息在分區中的位置信息由一個叫位移(Offset)的數據來表徵。分區位移老是從 0 開始,假設一個生產者向一個空分區寫入了 10 條消息,那麼這 10 條消息的位移依次是 0、一、二、…、9。
Kafka 的服務器端由被稱爲 Broker 的服務進程構成,即一個 Kafka 集羣由多個 Broker 組成,Kafka支持水平擴展,broker數量越多,集羣吞吐量越高。在集羣中每一個broker都有一個惟一brokerid,不得重複。Broker 負責接收和處理客戶端發送過來的請求,以及對消息進行持久化。
通常會將不一樣的 Broker 分散運行在不一樣的機器上,這樣若是集羣中某一臺機器宕機,kafka能夠自動選舉出其餘機器上的 Broker 繼續對外提供服務。這其實就是 Kafka 提供高可用的手段之一。
📷 controller
Kafka集羣中會有一個或者多個broker,其中有且僅有一個broker會被選舉爲控制器(Kafka Controller),它負責管理整個集羣中全部分區和副本的狀態。
當某個分區的leader副本出現故障時,由控制器負責爲該分區選舉新的leader副本。當檢測到某個分區的ISR集合發生變化時,由控制器負責通知全部broker更新其元數據信息。當爲某個topic增長分區數量時,一樣仍是由控制器負責分區的從新分配。
這幾句話可能會讓你以爲困惑~不要方~ 只是突出下控制器的職能不少,而這些功能的具體細節會在後面的文章中作具體的介紹。
Kafka中的控制器選舉的工做依賴於Zookeeper,成功競選爲控制器的broker會在Zookeeper中建立/controller這個臨時(EPHEMERAL)節點,此臨時節點的內容參考以下:
其中version在目前版本中固定爲1,brokerid表示稱爲控制器的broker的id編號,timestamp表示競選稱爲控制器時的時間戳。
Kafka有兩種客戶端。生產者和消費者。咱們把生產者和消費者統稱爲客戶端(Clients)。
向主題Topic發佈消息Message的客戶端應用程序稱爲生產者(Producer),生產者程序一般持續不斷地向一個或多個主題發送消息。
而訂閱這些主題消息的客戶端應用程序就被稱爲消費者(Consumer)。和生產者相似,消費者也可以同時訂閱多個主題的消息。
Producer 用來建立Message。在發佈訂閱系統中,他們也被叫作 Publisher 發佈者或 writer 寫做者。
一般狀況下,會發布到特定的Topic,並負責決定發佈到哪一個分區(一般簡單的由負載均衡機制隨機選擇,或者經過key,或者經過特定的分區函數選擇分區。)
Producer分爲Sync Producer 和 Aync Producer。
Sync Producer同步的生產者,即必定要某條消息成功纔會發送下一條。因此它是低吞吐率、通常不會出現數據丟失。
Aync Producer異步的生產者,有個隊列的概念,是直接發送到隊列裏面,批量發送。高吞吐率、可能有數據丟失的。
📷 消費者
Consumer 讀取消息。在發佈訂閱系統中,也叫作 subscriber 訂閱者或者 reader 閱讀者。消費者訂閱一個或者多個主題,而後按照順序讀取主題中的數據。
📷 消費位移
消費者須要記錄消費進度,即消費到了哪一個分區的哪一個位置上,這是消費者位移(Consumer Offset)。注意,這和上面所說的消息在分區上的位移徹底不是一個概念。上面的「位移」表徵的是分區內的消息位置,它是不變的,即一旦消息被成功寫入到一個分區上,它的位移值就是固定的了。
而消費者位移則不一樣,它多是隨時變化的,畢竟它是消費者消費進度的指示器嘛。經過存儲最後消費的 Offset,消費者應用在重啓或者中止以後,還能夠繼續從以前的位置讀取。保存的機制能夠是 zookeeper,或者 kafka 本身。
📷 消費者組
ConsumerGroup:消費者組,指的是多個消費者實例組成一個組來消費一組主題,分區只能被消費者組中的其中一個消費者去消費,組員之間不能重複消費。
爲何要引入消費者組呢?主要是爲了提高消費者端的吞吐量。多個消費者實例同時消費,加速整個消費端的吞吐量(TPS)。
固然它的做用不只僅是瓜分訂閱主題的數據,加速消費。它們還能彼此協助。假設組內某個實例掛掉了,Kafka 可以自動檢測到,而後把這個 Failed 實例以前負責的分區轉移給其餘活着的消費者,這個過程稱之爲重平衡(Rebalance)。
你務必先把這個詞記住,它是kafka大名鼎鼎的重平衡機制,生產出現的異常問題不少都是因爲它致使的。後續我會在【kafka大名鼎鼎又臭名昭著的重平衡】文章中詳細分析。
zookeeper目前在kafka中扮演着舉重輕重的角色和做用~是kafka不可缺乏的一個組件。
目前,Apache Kafka 使用 Apache ZooKeeper 來存儲它的元數據,好比brokers信息、分區的位置和主題的配置等數據就是存儲在 ZooKeeper 集羣中。
注意個人用詞,我只說是目前。why?在 2019 年社區提出了一個計劃,以打破這種依賴關係,並將元數據管理引入 Kafka 自己。由於擁有兩個系統會致使大量的重複。
在以前的設計中,咱們至少須要運行三個額外的 Java 進程,有時甚至更多。事實上,咱們常常看到具備與 Kafka 節點同樣多的 ZooKeeper 節點的 Kafka 集羣!此外,ZooKeeper 中的數據還須要緩存在 Kafka 控制器上,這致使了雙重緩存。
更糟糕的是,在外部存儲元數據限制了 Kafka 的可伸縮性。當 Kafka 集羣啓動時,或者一個新的控制器被選中時,控制器必須從 ZooKeeper 加載集羣的完整狀態。隨着元數據數量的增長,加載過程須要的時間也會增長,這限制了 Kafka 能夠存儲的分區數量。
最後,將元數據存儲在外部會增長控制器的內存狀態與外部狀態不一樣步的可能性。
所以,將來,Kafka 的元數據將存儲在 Kafka 自己中,而不是存儲在 ZooKeeper 之類的外部系統中。能夠持續關注kafka社區動態哦!
一個典型的kafka集羣包含若干個producer(向主題發佈新消息),若干consumer(從主題訂閱新消息,用Consumer Offset表徵消費者消費進度),cousumergroup(多個消費者實例共同組成的一個組,共同消費多個分區),若干broker(服務器端進程)。還有zookeeper。
kafka發佈訂閱的對象叫主題,每一個Topic下能夠有多個Partition,Partition中每條消息的位置信息又叫作消息位移(Offset),Partition有副本機制,使得同一條消息可以被拷貝到多個地方以提供數據冗餘,副本分爲領導者副本和追隨者副本。
能夠用下面這張圖來形象表達kafka的組成:
另外,再po一張思惟導圖助你回顧本文所述的術語。
重要!!關注【胖滾豬學編程】公衆號發送"kafka"。獲取本文全部架構圖以及Kafka全系列思惟導圖!
本文來源於公衆號【胖滾豬學編程】一個集顏值與才華於一身的女程序媛。以漫畫形式讓編程so easy and interesting。