kafka是一個分布式的,高吞吐量的、信息分片存儲,消息同步復(fù)制的開源消息服務(wù),它提供了消息系統(tǒng)的功能,但是采用了獨(dú)特的設(shè)計(jì)。
kafka最初由LinkedIn設(shè)計(jì)開發(fā),使用Scala語言編寫,用作LinkedIn網(wǎng)站的活動流數(shù)據(jù)和運(yùn)營數(shù)據(jù)處理工具,這其中活動流數(shù)據(jù)是指頁面訪問量、被查看內(nèi)容方面的信息以及搜索情況等內(nèi)容,運(yùn)營數(shù)據(jù)是指服務(wù)器的性能數(shù)據(jù)(CPU、IO使用率、請求時間、服務(wù)日志等數(shù)據(jù))。
現(xiàn)在kafka已被多家不同類型的公司采用,作為其內(nèi)部各種數(shù)據(jù)的處理工具或消息隊(duì)列服務(wù)。如今kafka捐獻(xiàn)給了apache軟件基金組織,成為apache下的一個開源項(xiàng)目。
下面我們來溫習(xí)一下消息系統(tǒng)的基本要素:
1、topic:kafka維護(hù)的一個叫topic的消息主題;
2、producer:我們將消息發(fā)布到kafka的topic上,發(fā)布消息的進(jìn)程也叫生產(chǎn)者producer;
3、consumer:我們從kafka的topic上訂閱消息,訂閱消息的進(jìn)程叫消費(fèi)者consumer;
4、broker:kafka運(yùn)行在由一個或多個服務(wù)器構(gòu)成的集群上,集群中的每一臺服務(wù)器被稱為broker。(broker的意思為:經(jīng)紀(jì)人、居間人、代理人)
所以從宏觀上來看,生產(chǎn)者(producer)通過網(wǎng)絡(luò)發(fā)布消息到kafka集群(cluster),kafka集群再為消費(fèi)者(consumer)提供消息服務(wù),他們的處理流程如下圖所示:
生產(chǎn)者、消費(fèi)者與kafka的broker服務(wù)器之間通過TCP協(xié)議通信。kafka提供了多種語言客戶端Java、C/C++、Python、php、ruby、.net、scala、erlang等,用于與kafka交互。
我們將消息的發(fā)布(publish)叫做生產(chǎn)者producer,將消息的訂閱(subscribe)叫做消費(fèi)者consumer,將中間的存儲服務(wù)叫做broker,這個broker就是我們的kafka服務(wù)器,生產(chǎn)者通過推模式將數(shù)據(jù)推到kafka服務(wù)器broker,消費(fèi)者通過拉模式從kafka服務(wù)器broker拉取數(shù)據(jù),它們?nèi)缦聢D所示:
需要注意的是,消費(fèi)者是自己主動從broker拉取數(shù)據(jù),而broker不會主動把數(shù)據(jù)發(fā)送到消費(fèi)者。
對于在實(shí)際應(yīng)用中,生產(chǎn)者、消費(fèi)者和kafka的broker一般集群部署,多個producer、consumer和broker之間協(xié)同合作,通過zookeeper協(xié)調(diào)管理,構(gòu)成了一個高性能的分布式消息發(fā)布與訂閱系統(tǒng),在一個集群中,它們的結(jié)構(gòu)如下圖所示:
構(gòu)成的整個分布式消息系統(tǒng)將按照如下的流程運(yùn)行:
1、啟動zookeeper
2、啟動kafka的broker
3、編寫客戶端Producer生產(chǎn)數(shù)據(jù),通過zookeeper找到broker,然后將數(shù)據(jù)存入broker
4、編寫客戶端Consumer消費(fèi)數(shù)據(jù),通過zookeeper找對應(yīng)的broker,然后從broker消費(fèi)消息。
以上我們對kafka有了一個概括性的描述,讓我們從宏觀上認(rèn)識了kafka是什么以及其基本工作原理,接下來我們再詳細(xì)看看kafka涉及到的幾個主要要素都有些什么特點(diǎn):
Topic,高級別抽象的kafka提供者,一個topic是一個目錄或消息名,消息將被發(fā)送到topic,對于每個topic,kafka維持一個分片日志(partitioned log),如下圖所示為一個topic的解剖圖:
每一個分片日志都是有序的、不可變的消息系列,新的消息不斷地添加到分片日志的末尾,在這個分片日志中,每個消息被分配一個連續(xù)的id號叫offset,它唯一地定義了一個消息。
在一個配置的時間內(nèi),kafka集群一直保留著所有發(fā)布的消息,不管這些消息有沒有被消費(fèi)。比如被設(shè)置保留兩天,那么一個消息被發(fā)布后的兩天時間內(nèi),消息都是可以被消費(fèi)的,兩天之后消息將被丟棄以釋放空間。
kafka中進(jìn)行partitions設(shè)計(jì)有多個原因,首先,通過partition可以使log文件的大小不會超過單臺機(jī)器的文件容量限制,一個topic可以有多個partitions,因此可以存儲任意數(shù)量的數(shù)據(jù)。其次,可以提升并發(fā)消費(fèi)的能力,一個topic的partitions可以被分布在kafka集群中的多臺機(jī)器上,每臺機(jī)器上的kafka實(shí)例負(fù)責(zé)該機(jī)器上分片數(shù)據(jù)的請求和操作,每個分片可以配置被復(fù)制的份數(shù),從而復(fù)制到集群中的其他機(jī)器上,以提升高可用性。
每個partition有一個server作為leader,0個或者多個server作為followers,leader處理所有的讀寫請求,followers復(fù)制leader進(jìn)行消息同步,如果一個leader發(fā)生故障,followers中會自動有一個follower變成新的leader。
生產(chǎn)者把消息發(fā)送到他們選擇的topics中,producers還能指定發(fā)送到topic的哪個partition中,你可以通過round-robin或者其他算法來決定把消息發(fā)送到哪個partition中。
傳統(tǒng)的消息系統(tǒng)有兩種模式:
一種是基于隊(duì)列Queue的點(diǎn)對點(diǎn)消息。
一種是基于主題Topic的發(fā)布與訂閱消息。
基于隊(duì)列的點(diǎn)對點(diǎn)消息只能被一個消費(fèi)者消費(fèi),而基于主題的發(fā)布與訂閱消息能被多個消費(fèi)者消費(fèi)。kafka抽象了這兩種模式,它采用consumer group名稱來處理這兩種模式,可以將消費(fèi)者分成多個group,每個consumer屬于一個單獨(dú)的consumer group,也可以多個consumer屬于同一個group。
如果采用基于隊(duì)列的點(diǎn)對點(diǎn)消息,則每個消費(fèi)者都需要位于同一個group中,如果采用基于主題的發(fā)布訂閱消息,則每個消費(fèi)者都要位于不同的group中。
在更多的情況下,我們的主題topic中會包含幾個consumer group,每個consumer group都是一個logical subscribe,每個group包含了多個consumer實(shí)例,這樣更具擴(kuò)展性和容錯性。kafka有比傳統(tǒng)消息系統(tǒng)更強(qiáng)健的訂閱機(jī)制。
kafka在較高的層次上提供了如下保證:
1、生產(chǎn)者producer發(fā)送到topic partition中的消息會被順序的追加到日志中;
2、消費(fèi)者consumer消費(fèi)消息的順序和消息在日志中的順序一致;
3、如果一個topic有N份復(fù)制,則我們可以允許N-1臺服務(wù)故障而不會丟失任何消息。
kafka的一些常用應(yīng)用場景:
1、消息系統(tǒng):替換傳統(tǒng)的消息系統(tǒng),解耦系統(tǒng)或緩存待處理的數(shù)據(jù),kafka有更好的吞吐量,內(nèi)置了分片、復(fù)制、容錯機(jī)制,是大規(guī)模數(shù)據(jù)消息處理的更好的解決方案。
2、網(wǎng)站活動跟蹤:網(wǎng)站的訪問量,搜索量,或者其他用戶的活動行為如注冊,充值,支付,購買等行為可以發(fā)布到中心的topic,每種類型可以作為一個topic,這些信息流可以被消費(fèi)者訂閱實(shí)時處理、實(shí)時監(jiān)控或者將數(shù)據(jù)流加載到Hadoop中進(jìn)行離線處理等。
3、度量統(tǒng)計(jì):可以用于度量統(tǒng)計(jì)一些運(yùn)維監(jiān)控?cái)?shù)據(jù),將分布式的一些監(jiān)控?cái)?shù)據(jù)聚集到一起。
4、日志聚合:可以作為一個日志聚合的替換方案,如Scribe、Flume。
5、數(shù)據(jù)流處理:可以對數(shù)據(jù)進(jìn)行分級處理,將從kafka獲取的原始數(shù)據(jù)進(jìn)行加工潤色后再發(fā)布至kafka。
6、事件溯源:可以以時間為順序記錄應(yīng)用事件的狀態(tài)變化,從而為事件溯源。
7、提交日志:可以作為分布式系統(tǒng)的外部日志存儲介質(zhì)。
當(dāng)然也許還可以以其他方式更加巧妙地使用kafka。
一個Java技術(shù)交流群,一起交流,共同進(jìn)步,扣扣群號:513086638
微信公眾平臺: