Kafka快速入門秘籍:背景介紹,應(yīng)用場(chǎng)景分析、核心架構(gòu)分析
一、背景介紹
引言:其實(shí)這段背景,我們之前介紹RabbitMQ的時(shí)候,已經(jīng)說(shuō)過(guò)了,我們這里講kakfa的時(shí)候,再把這一段給拿出來(lái),再說(shuō)明下。在講實(shí)戰(zhàn)前,我們還是有必要講解下理論的,理論為輔,實(shí)戰(zhàn)為主,在實(shí)戰(zhàn)的基礎(chǔ)上,再深入理解理論,底層原理,底層源碼。下篇文章或者視頻,我們將帶你看官網(wǎng)學(xué)習(xí)kafka環(huán)境搭建、kafka基本用法、kafka的容錯(cuò)性測(cè)試,在掌握知識(shí)的同時(shí),還能順便學(xué)習(xí)下英文。
1)問(wèn)題引入:
假設(shè)我們現(xiàn)在需要設(shè)計(jì)這樣一個(gè)用戶注冊(cè)系統(tǒng):用戶注冊(cè)完成后,需要給用戶發(fā)送激活郵件,開(kāi)通用戶賬號(hào),記錄用戶IP、用戶設(shè)備、時(shí)間等信息。
起初的設(shè)計(jì):

2)但存在的問(wèn)題是:
由于多個(gè)系統(tǒng)強(qiáng)耦合在一起,用戶注冊(cè)響應(yīng)會(huì)非常慢,嚴(yán)重影響了用戶的體驗(yàn),當(dāng)流量大的時(shí)候,性能會(huì)更差。
3)引入消息中間件:
為了解決上述問(wèn)題,我們引入消息中間件,來(lái)實(shí)現(xiàn)系統(tǒng)的解耦,多個(gè)系統(tǒng)間通過(guò)消息中間件進(jìn)行異步通信,最終的設(shè)計(jì)圖如下:

即實(shí)現(xiàn)了系統(tǒng)解耦,又提升了系統(tǒng)響應(yīng)的速度
4)消息中間件介紹:
消息中間件(Message Queue Middleware,簡(jiǎn)稱MQ)又稱為消息隊(duì)列,是指利用高效可靠的消息傳遞機(jī)制進(jìn)行與平臺(tái)無(wú)關(guān)的數(shù)據(jù)交流,并基于數(shù)據(jù)通信來(lái)進(jìn)行分布式系統(tǒng)的構(gòu)建。

2、應(yīng)用場(chǎng)景分析
1)異步通信
在很多時(shí)候,為了加快應(yīng)用系統(tǒng)整體運(yùn)轉(zhuǎn)速度,并不需要立即響應(yīng)某些請(qǐng)求,消息中間件提供了異步處理機(jī)制,允許將一些請(qǐng)求信息放入消息中間件中,但并不立即處理它,而是慢慢處理。在有限資源下,使用消息中間件能夠使系統(tǒng)性能從容倍增!
如:用戶注冊(cè)成功的郵件通知;用戶購(gòu)物下單的信息通知;大數(shù)據(jù)日志收集處理
2)削峰
以防突發(fā)劇增流量瞬間沖垮系統(tǒng),使用消息中間件可以支撐突發(fā)訪問(wèn)壓力
3)業(yè)務(wù)系統(tǒng)解耦
系統(tǒng)間的耦合關(guān)系太強(qiáng),會(huì)對(duì)系統(tǒng)的設(shè)計(jì)產(chǎn)生束縛,也會(huì)增加系統(tǒng)的復(fù)雜性,通過(guò)消息中間件可以更好的設(shè)計(jì)系統(tǒng),是一個(gè)系統(tǒng)完成指定的功能,而不是將所有的功能融合在同一個(gè)系統(tǒng)中。
二、kafka簡(jiǎn)介
Kafka作為一種消息中間件,是一種分布式的,基于發(fā)布/訂閱的消息系統(tǒng)。主要設(shè)計(jì)目標(biāo)如下:
以時(shí)間復(fù)雜度為O(1)的方式提供消息持久化能力,即使對(duì)TB級(jí)以上數(shù)據(jù)也能保證常數(shù)時(shí)間的訪問(wèn)性能
高吞吐率。即使在非常廉價(jià)的商用機(jī)器上也能做到單機(jī)支持每秒100K條消息的傳輸
支持Kafka Server間的消息分區(qū),及分布式消費(fèi),同時(shí)保證每個(gè)partition內(nèi)的消息順序傳輸
同時(shí)支持離線數(shù)據(jù)處理和實(shí)時(shí)數(shù)據(jù)處理
1、kafka架構(gòu)

名詞解釋:
Broker
一個(gè)Kafka集群由一個(gè)或多個(gè)broker組成。搭建了kafka環(huán)境的服務(wù)器就可以稱為broker。
Topic
Kafka集群上存儲(chǔ)的消息都有一個(gè)類別,這個(gè)類別被稱為topic。(使用者只需指定消息的topic,即可生產(chǎn)或消費(fèi)數(shù)據(jù)而不必關(guān)心數(shù)據(jù)存于何處)Topic在邏輯上可以被認(rèn)為是一個(gè)queue。每條消費(fèi)都必須指定它的topic,可以簡(jiǎn)單理解為必須指明把這條消息放進(jìn)哪個(gè)queue里,這與RabbitMQ就有點(diǎn)類似了。
Partition
為了使得Kafka的吞吐率可以水平擴(kuò)展,物理上又把topic分成一個(gè)或多個(gè)partition,每個(gè)partition在物理上對(duì)應(yīng)一個(gè)文件夾,該文件夾下存儲(chǔ)這個(gè)partition的所有消息和索引文件。創(chuàng)建topic時(shí)可指定parition數(shù)量。我們實(shí)戰(zhàn)演示的時(shí)候,會(huì)再次說(shuō)明。

因?yàn)槊織l消息都被append到該partition中,是順序?qū)懘疟P,因此效率非常高(經(jīng)驗(yàn)證,順序?qū)懘疟P效率比隨機(jī)寫內(nèi)存還要高,這是Kafka高吞吐率的一個(gè)很重要的保證)。
Producer
負(fù)責(zé)發(fā)布消息到Kafka broker
Consumer
消費(fèi)消息。每個(gè)consumer屬于一個(gè)特定的consumer group(可為每個(gè)consumer指定group name,若不指定group name則屬于默認(rèn)的group)。同一topic的一條消息只能被同一個(gè)consumer group內(nèi)的一個(gè)consumer消費(fèi),但多個(gè)consumer group可同時(shí)消費(fèi)這一消息。
三、kafka其它核心概念
1、消息存儲(chǔ)
很多傳統(tǒng)的message queue都會(huì)在消息被消費(fèi)完后將消息刪除,一方面避免重復(fù)消費(fèi),另一方面可以保證queue的長(zhǎng)度比較少,提高效率。而Kafka集群會(huì)保留所有的消息,無(wú)論其被消費(fèi)與否。當(dāng)然,因?yàn)榇疟P限制,不可能永久保留所有數(shù)據(jù)(實(shí)際上也沒(méi)必要),因此Kafka提供兩種策略去刪除舊數(shù)據(jù)。一是基于時(shí)間,二是基于partition文件大小。例如可以通過(guò)配置$KAFKA_HOME/config/server.properties,讓Kafka刪除一周前的數(shù)據(jù),也可通過(guò)配置讓Kafka在partition文件超過(guò)1GB時(shí)刪除舊數(shù)據(jù)。
2、Consumer Group
每一個(gè)consumer實(shí)例都屬于一個(gè)consumer group,每一條消息只會(huì)被同一個(gè)consumer group里的一個(gè)consumer實(shí)例消費(fèi)。(不同consumer group可以同時(shí)消費(fèi)同一條消息)
Kafka保證的是穩(wěn)定狀態(tài)下每一個(gè)consumer實(shí)例只會(huì)消費(fèi)某一個(gè)或多個(gè)特定partition的數(shù)據(jù),而某個(gè)partition的數(shù)據(jù)只會(huì)被某一個(gè)特定的consumer實(shí)例所消費(fèi)。這樣設(shè)計(jì)的劣勢(shì)是無(wú)法讓同一個(gè)consumer group里的consumer均勻消費(fèi)數(shù)據(jù),優(yōu)勢(shì)是每個(gè)consumer不用都跟大量的broker通信,減少通信開(kāi)銷,同時(shí)也降低了分配難度,實(shí)現(xiàn)也更簡(jiǎn)單。另外,因?yàn)橥粋€(gè)partition里的數(shù)據(jù)是有序的,這種設(shè)計(jì)可以保證每個(gè)partition里的數(shù)據(jù)也是有序被消費(fèi)。
3、Consumer Rebalance
Kafka通過(guò)Zookeeper管理集群配置,在consumer group發(fā)生變化時(shí)(如:某個(gè)consumer因故障下線時(shí))進(jìn)行rebalance。具體含義為:
如果某consumer group中consumer數(shù)量少于partition數(shù)量,則至少有一個(gè)consumer會(huì)消費(fèi)多個(gè)partition的數(shù)據(jù),
如果consumer的數(shù)量與partition數(shù)量相同,則正好一個(gè)consumer消費(fèi)一個(gè)partition的數(shù)據(jù),
而如果consumer的數(shù)量多于partition的數(shù)量時(shí),會(huì)有部分consumer無(wú)法消費(fèi)該topic下任何一條消息。