Kafka入門(1):概述
摘要
在本文中,我將從為什麼需要消息隊列開始講起,舉兩個小例子,跟你聊聊目前消息隊列的一些使用場景。
比如消息隊列在複雜系統中的解耦,又比如消息隊列在高並發下的場景如果讓流量變得更平緩。
隨後我會跟你介紹一下Kafka中的一些重要的名詞,比如主題、Broker、分區等。
注意,Kafka不僅僅是消息中間件,他還是優秀的分散式流處理平台,不過在本文中重點還是研究Kafka在消息隊列中的應用,以及原理。
1. 使用場景
在我們學習Kafka之前,先想一想什麼地方需要用到消息中間件。
然後,我將舉兩個小例子,簡單的說一說消息中間件的使用場景。
1.1 解耦
比如我們在一個系統中,需要調用其他的很多個系統,我們當然可以在這個系統中挨個調用其他的系統。但是問題就來了,如果我們需要調用的其他系統有變動,比如增加了新的系統,或者有一些系統不再提供服務了,那麼應該怎麼辦呢?修改系統調用的程式碼,然後再次上線?
這樣顯得特別的麻煩,而且也使得這個系統與其他的系統完完全全的耦合在了一起。
所以我們可以把我們的」服務調用「,封裝成一個消息,發送到消息中間件上。
對於其他的系統,只需要去這個消息中間件上面拉取自己需要的消息,然後進行處理。
此外,對於用戶來說,也不需要等待這麼長的時間,只要這個系統將消息丟進了消息中間件就可以返回了,這就保證了更快的響應速度。
這就是我們所說的解耦,一個系統只管把數據發送到中間件中,另外的系統只管從中間件中拿到數據,然後處理。
1.2 削峰填谷
一開口就知道老高並發了。
這個名詞我們其實並不陌生,但凡你搜過」高並發「、」秒殺」這一類的關鍵詞,就一定會查到這樣的結果。
那麼削峰填谷的關鍵就在於讓流量變得更加的平緩。
咱們就拿「秒殺」舉例。
那麼對於這個商城來講,這個「秒殺」活動的上游服務就是下單。而這個上游服務需要調用很多的下游服務,比如庫存服務生成庫存,訂單服務生成訂單,支付服務,而支付服務又可能需要調用第三方的支付介面等等。簡單來講,就是上游服務的處理速度遠遠大於下游服務的處理速度。
那麼這個時候如果我們不對上游服務做任何的限制,所有的請求直接打到下游服務,那麼整個系統都可能掛掉。
所以,我們可以用消息中間件來做「削峰填谷」這件事情。
上游服務只需要將「某某用戶在某某時間購買了某某商品」等這些必要的資訊,丟進消息中間件中,然後下游服務按照自己的速度,從消息中間件中拉取資訊,然後消費。這樣,整個系統的處理就能有條不紊了。
在這裡,我只是舉了一些小例子,省略了很多細節,真正的業務並沒有這麼簡單,還有很多東西是需要考慮的,比如我們把消息放進了消息中間件中,什麼時候才能被消費呢,會不會一直飢餓,這個時候需不需要再次發送資訊呢?
再比如,如果我再次發送了資訊,有沒有可能重複消費呢?
又或者,我們發送的資訊有沒有可能丟了?
諸如此類的問題其實還有很多,我們帶著這些問題往下看。
2. 概念
說完了消息隊列的用途,我準備跟你介紹一下在Kafka中的幾個常見的名詞。
但是有一點是需要注意的,雖然在本篇,甚至本系列的文章中,我可能都在講消息隊列這個概念,但是Kafka不僅僅只是個消息引擎系統,他還是一個很優秀的分散式流處理平台。
只不過作者能力學識都有限,所以目前只能先研究消息隊列這個方面的內容。
2.1 生產者與消費者
這個很容易理解,生產者就是發送消息的對象。
生產者負責把需要處理的消息或者記錄,發送到消息隊列中,剩下的事情就與他無關了。
消費者是處理消息的對象。
消費者負責從消息隊列中拉取待處理的消息,然後進行處理。
2.2 主題
在上面的內容中,我只說到了「把消息丟到消息隊列」以及「從消息隊列中拉取消息」這麼兩種說法,那麼現在我們要解決的問題是:
-
怎麼確定我該把消息發送到哪/我該從哪裡拿消息?
-
如果有不同種類的消費者,會不會把消息搞混?
其實如果只有一種消息,那麼是不會有這個問題的。但是如果有不同種類的消息呢,比如我有下單的消息,也有日誌的消息,那麼會不會存在訂單服務拿到了日誌消息這種情況呢?難道我應該配置多個Kafka嗎?
所以在Kafka中有了主題這種說法。
在解釋原理之前,你可以這麼理解,一個主題,對應一個隊列。我們在發送消息的時候,選擇合適的主題,將消息發送到這個主題中。
生產者將消息發送到設定好的主題中,消費者負責從特定的主題拉取消息,然後進行處理。
如此一來,我們的消息隊列就可以處理更多種類的消息了。
2.3 Broker
上面我們提到了生產者與消費者,他們被稱為Kafka的客戶端。
既然有客戶端,那麼就一定有服務端,就是我們這一小節提到的Broker。
Broker相當於Kafka的服務端,你可以理解為是隊列存在的地方,生產者把消息發送到Broker中,消費者從Broker中獲取消息。
2.4 分區
在上面我們提到了,在Broker中有好幾個主題,生產者向Broker中的某一個主題發送資訊,消費者從Broker中的某一個主題拉取資訊。
那麼我們很容易的可以發現,這個消息隊列是存在性能瓶頸的。
在這裡,Broker所在的機器的IO速度,可能會使得這個消息隊列存在性能上的瓶頸。
假設我們的Broker上面有特別多的主題,那麼這個時候如果由於IO速度不夠,可能會導致生產者無法及時的將消息發送到Broker中,消費者無法及時的從Broker中拉取消息。
所以就有了分區這個概念,相當於我們可以把一個主題分成很多份。但是,當生產者往某一個主題中發送消息的時候,並不會把這個消息發送給這個主題的所有分區,而是會發送到這個主題的某一個分區下。
也就是說,這裡的分區,是擴展的概念,而不是複製的概念。
此外,這些分區可以部署在不同的機器上,性能也就提升了好幾倍。
2.5 Replica
「高可用」這個概念,在互聯網中也特別的重要。
而通常來講,可用性通常都是通過冗餘來實現的。
上面我們提到了分區這個概念,利用分區,把一個主題分成多個部分進行擴展。
但是如果某一個分區掛了,是不是就這個主題的很多資訊就丟失了呢?
因此有了Replica這個概念。簡單的來說,就是把每一個分區,都複製幾份。
通常來講,我們理解的複製,都是有一個leader,若干個follower,且一般leader負責寫,follower負責讀。不過在Kafka中跟MySQL這些不太一樣,在Kafka中follower就僅僅只是作備份使用,所有的讀寫還是發生在了leader身上。
寫在最後
首先,謝謝你能看到這裡。
在《Kafka入門》系列的文章中,我的打算是跟MySQL系列的文章一樣,儘可能的把複雜的概念講得更加簡單易懂一些。另外,也會稍微的深入一點點原理,儘可能的在會用的情況下,知道他是怎麼實現的,以及為什麼要這麼設計。
在這期間我如果有哪些理解的不夠到位,或者解釋的不對,歡迎留言指正!
再次感謝你能看到這裡!
PS:如果有其他的問題,也可以在公眾號找到我,歡迎來找我玩~