Kafka入門(1):概述

紅雞菌發表於2020-07-08

摘要

在本文中,我將從為什麼需要訊息佇列開始講起,舉兩個小例子,跟你聊聊目前訊息佇列的一些使用場景。

比如訊息佇列在複雜系統中的解耦,又比如訊息佇列在高併發下的場景如果讓流量變得更平緩。

隨後我會跟你介紹一下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:如果有其他的問題,也可以在公眾號找到我,歡迎來找我玩~

相關文章