天天看點

Zookeeper(九)依賴于ZooKeeper的分布式消息系統Kafka

Kafka

Kafka是知名社交網絡公司LinkedIn于2010年12月份開源的分布式消息系統,主要由Scala語言開發,于2012年成為Apache頂級項目,目前被廣泛應用在包括Twitter,Netffix和Tumblr等在内的大型網際網路站點上。

Kafka主要用于實作低延遲的發送和收集大量的事件和日志資料——這些資料通常都是活躍的資料通常都是活躍的資料。所謂活躍資料,在網際網路大型的Web網站應用中非常常見,通常是指網站的PV數和使用者通路記錄等。這些資料通常以日志的形式記錄下來,然後有一個專門的系統來進行日志的收集與統計。

Kafka是一個吞吐量極高的分布式消息系統,其整體設計是典型的釋出與訂閱模式系統。在Kafka叢集中,沒有“中心主節點”的概念,叢集中所有的伺服器都是對等的,是以。可以在不做任何配置更改與删除,同樣,消息的生産者和消費者也能夠做到随意重新開機和機器的上下線。Kafka伺服器及消息生産者和消費者之間的部署關系如下圖所示:

Zookeeper(九)依賴于ZooKeeper的分布式消息系統Kafka

Broker注冊

Broker:幾Kafka的伺服器,用于存儲消息,在消息中間件中通常被稱為Broker。

Offset:消息存儲在Kafka的Broker上,消費者拉取消息資料的過程中需要知道消息在檔案中的偏移量,這個便宜量就是所謂的Offset。

Kafka是一個分布式消息系統,這也展現在起Broker,Producer和Consumer的分布式部署上。雖然Broker是分布式部署并且互相之間是獨立運作的,但還是需要有一個注冊系統能夠将整個叢集中的Broker伺服器都管理起來。在Kafka的設計中,選擇了ZooKeeper來進行所有Broker的管理。

在ZooKeeper上會有一個專門用來進行Broker伺服器清單記錄的節點,下文中我們稱為ieee“Broker”節點,起節點路徑為/brokers/ids。

每個Broker伺服器在啟動時,都會到ZooKeeper上進行注冊,即到Broker節點下建立屬于自己的節點,其節點路徑為/broker/ids[0...N]

從上面的節點路徑中,我們可以看到,在Kafka中,我們使用一個全局唯一的數字來指代每一個Broker伺服器,可以稱其為“BrokerID”,不同的Broker必須使用不同的BrokerID進行注冊,例如/broker/ids/1和/broker/ids/2分别代表了兩個Broker伺服器。建立完Broker節點後,每個Broker就會将自己的IP位址和端口等資訊寫入到該節點中。

請注意,Broker建立的節點是一個臨時節點,也就是說,一旦這個Broker伺服器當機或是下線後,那麼對應的Broker節點也就被删除了。是以我們可以通過ZooKeeper上Broker界定啊的變化情況來動态表征Broker伺服器的可用性。

Topic注冊

在Kafka中,會将同一個Topic的消息分成多個分區并将其分分布到多個Broker上,而這些分區資訊以及馭Broker的對應關系也都是由ZooKeeper維護的,由專門的節點來記錄,其節點路徑為/brokers/topics。下文中我們将這個節點稱為“Topic”u節點。Kafka中的每一個Topic,都會以/brokers/topecs/[topic]的形式記錄在這個節點下,例如/brokers/topics/login和/brokers/topics/search等。

Broker伺服器在啟動後,會到對應的Topic節點下注冊自己的BrokerID,并寫入針對Topic的分區總數。例如,/brokers/topics/login/->2這個節點表明BrokerID為3的一個Broker伺服器,對于“login”這個Topic的消息,提供了2個分區進行消息存儲。同樣,這個分區數節點也是一個臨時節點。

消費分區與消費者關系

對于每個消費者分組,Kafka都會為其配置設定一個全局唯一的GroupID,同一個消費者分組内部的所有消費者都共享該ID。同時Kafka也會為每個消費者配置設定一個ConsumerID,通常采用“Hostname:UUID”的形式來表示。在Kafka的設計中,規定了每個消息分區有且隻能同時有一個消費者進行消息的消費,是以,需要在ZooKeeper上記錄下消費分區馭消費者之間的對應的關系。每個消費者一旦确定了對一個消息分區的消費權利,那麼需要将其ConsumerID寫入到對應消息分區的臨時節點上,例如/consumers/[group_id]/owners/[topic]/[broker_id-partition_id],其中“[broker_id-partition_id]”就是一個消息分區的辨別,節點内容局勢消費分區上消息的消費者的ConsumerID。

消費消息進度Offset記錄

在消費者對指定消息分區進行消息消費的過程中,需要定時地将分區消息的消費進度,即Offset記錄到ZooKeeper節點上,以便在該消費者進行重新開機或者其他消費者重新接管該消息分區的消息消費後,能夠從之前的進度開始繼續進行消息的消費。Offset在ZooKeeper上的記錄由一個專門的節點負責,起節點路徑為/consumer/[group_id]/offsets/[topic]/[broker_id-partition_id],起節點内容就是Offset值。

消費者注冊

下面我們來看看消費者伺服器在初始化啟動時加入消費者分組的過程。

1.注冊到消費者分組。

每個消費者伺服器在啟動的時候,都會到ZooKeeper的指定節點下建立一個屬于自己的消費者節點,例如/consumers/[group_id]/ids/[consumer_id].

完成節點建立後,消費者會将自己訂閱的Topic資訊寫入該節點。注意,該節點也是一個臨時節點,也就是說,一旦消費者伺服器出現故障或是下線後,其對應的消費者節點就會被删除。

2.對消費者分組中消費者的變化注冊監聽。

每個消費者都需要關注所屬消費者分組中消費者伺服器的變化情況,即對/consumers/[group_id]/ids節點注冊子節點變化的Watcher監聽。一旦發現消費者新增或減少,就會觸發消費者的負載均衡。

3.對Broker伺服器的變化注冊監聽。

消費者需要對/brokers/ids/[0...N]中的節點進行監聽的注冊,如果發現Broker伺服器清單發生變化,那麼就根據具體情況來決定是否需要進行消費者的負載均衡。

4.進行消費者負載均衡。

所謂消費者負載均衡,是指為了能夠讓同一個Topic下不同分區的消息盡量均衡地被多個消費者消費者消費而進行的一個消費者于消費分區配置設定的過程。通常,對于一個消費者分組,如果組内的消費者伺服器發上變更或Broker伺服器發生變更,會觸發消費者負載均衡。

小結

Kafka從設計之初就是一個大規模的分布式i消息中間件,其服務端存在多個Broker,同時為了達到負載均衡,将每個Topic消息分成了多個分區,并分布在不同的Broker上,對各生産者和消費者能夠同時發送和接收消息。Kafka使用ZooKeeper作為分布式協調架構,很好滴将消息生産,消息存儲和消息消費的過程有機地結合起來。同時借助ZooKeeper,Kafka能夠在保持包括生産者,消費者和Broker在内的所有元件無狀态的情況下,建立起生産者和和消費者之間的訂閱關系,并實作了生産者和消費者的負載均衡。

繼續閱讀