Kafka是靠什麼機制保持高可靠,高可用的?

2021-09-24 13:45:33 字數 3819 閱讀 8265

面試大廠時,一旦簡歷上寫了 kafka,幾乎必然會被問到乙個問題:說說 acks 引數對訊息持久化的影響?

這個 acks 引數在 kafka 的使用中,是非常核心以及關鍵的乙個引數,決定了很多東西。

如何保證宕機的時候資料不丟失?

如果想理解這個 acks 引數的含義,首先就得搞明白 kafka 的高可用架構原理。

比如下面的圖里就是表明了對於每乙個 topic,我們都可以設定它包含幾個 partition,每個 partition 負責儲存這個 topic 一部分的資料。

然後 kafka 的 broker 集群中,每台機器上都儲存了一些 partition,也就存放了 topic 的一部分資料,這樣就實現了 topic 的資料分布式儲存在乙個 broker 集群上。

但是有乙個問題,萬一乙個 kafka broker 宕機了,此時上面儲存的資料不就丟失了嗎?

沒錯,這就是乙個比較大的問題了,分布式系統的資料丟失問題,是它首先必須要解決的,一旦說任何一台機器宕機,此時就會導致資料的丟失。

多副本冗餘的高可用機制

所以如果大家去分析任何乙個分布式系統的原理,比如說 zookeeper、kafka、redis cluster、elasticsearch、hdfs,等等。

其實它們都有自己內部的一套多副本冗餘的機制,多副本冗餘幾乎是現在任何乙個優秀的分布式系統都一般要具備的功能。

在 kafka 集群中,每個 partition 都有多個副本,其中乙個副本叫做 leader,其他的副本叫做 follower,如下圖:

如上圖所示,假設乙個 topic 拆分為了 3 個 partition,分別是 partition0,partiton1,partition2,此時每個 partition 都有 2 個副本。

比如 partition0 有乙個副本是 leader,另外乙個副本是 follower,leader 和 follower 兩個副本是分布在不同機器上的。

這樣的多副本冗餘機制,可以保證任何一台機器掛掉,都不會導致資料徹底丟失,因為起碼還是有副本在別的機器上的。

多副本之間資料如何同步?

接著我們就來看看多個副本之間資料是如何同步的?其實任何乙個 partition,只有 leader 是對外提供讀寫服務的。

也就是說,如果有乙個客戶端往乙個 partition 寫入資料,此時一般就是寫入這個 partition 的 leader 副本。

然後 leader 副本接收到資料之後,follower 副本會不停的給它傳送請求嘗試去拉取最新的資料,拉取到自己本地後,寫入磁碟中。

如下圖所示:

isr 到底指的是什麼東西?

既然大家已經知道了 partiton 的多副本同步資料的機制了,那麼就可以來看看 isr 是什麼了。

isr 全稱是「in-sync replicas」,也就是保持同步的副本,它的含義就是,跟 leader 始終保持同步的 follower 有哪些。

大家可以想一下 ,如果說某個 follower 所在的 broker 因為 jvm fullgc 之類的問題,導致自己卡頓了,無法及時從 leader 拉取同步資料,那麼是不是會導致 follower 的資料比 leader 要落後很多?

所以這個時候,就意味著 follower 已經跟 leader 不再處於同步的關係了。

但是只要 follower 一直及時從 leader 同步資料,就可以保證它們是處於同步的關係的。

所以每個 partition 都有乙個 isr,這個 isr 裡一定會有 leader 自己,因為 leader 肯定資料是最新的,然後就是那些跟 leader 保持同步的 follower,也會在 isr 裡。

acks 引數的含義

鋪墊了那麼多的東西,最後終於可以進入主題來聊一下 acks 引數的含義了。

如果大家沒看明白前面的那些副本機制、同步機制、isr 機制,那麼就無法充分的理解 acks 引數的含義,這個引數實際上決定了很多重要的東西。

首先這個 acks 引數,是在 kafka producer,也就是生產者客戶端裡設定的。

也就是說,你往 kafka 寫資料的時候,就可以來設定這個 acks 引數。然後這個引數實際上有三種常見的值可以設定,分別是:0、1 和 all。

第一種選擇是把 acks 引數設定為 0,意思就是我的 kafka producer 在客戶端,只要把訊息傳送出去,不管那條資料有沒有在哪怕 partition leader 上落到磁碟,我就不管它了,直接就認為這個訊息傳送成功了。

如果你採用這種設定的話,那麼你必須注意的一點是,可能你傳送出去的訊息還在半路。

結果呢,partition leader 所在 broker 就直接掛了,然後結果你的客戶端還認為訊息傳送成功了,此時就會導致這條訊息就丟失了。

第二種選擇是設定 acks = 1,意思就是說只要 partition leader 接收到訊息而且寫入本地磁碟了,就認為成功了,不管它其他的 follower 有沒有同步過去這條訊息了。

這種設定其實是 kafka 預設的設定,大家請注意,劃重點!這是預設的設定。

也就是說,預設情況下,你要是不管 acks 這個引數,只要 partition leader 寫成功就算成功。

但是這裡有乙個問題,萬一 partition leader 剛剛接收到訊息,follower 還沒來得及同步過去,結果 leader 所在的 broker 宕機了,此時也會導致這條訊息丟失,因為人家客戶端已經認為傳送成功了。

最後一種情況,就是設定 acks=all,這個意思就是說,partition leader 接收到訊息之後,還必須要求 isr 列表裡跟 leader 保持同步的那些 follower 都要把訊息同步過去,才能認為這條訊息是寫入成功了。

如果說 partition leader 剛接收到了訊息,但是結果 follower 沒有收到訊息,此時 leader 宕機了,那麼客戶端會感知到這個訊息沒傳送成功,他會重試再次傳送訊息過去。

此時可能 partition2 的 follower 變成 leader 了,此時 isr 列表裡只有最新的這個 follower 轉變成的 leader 了,那麼只要這個新的 leader 接收訊息就算成功了。

最後的思考

acks=all 就可以代表資料一定不會丟失了嗎?當然不是,如果你的 partition 只有乙個副本,也就是乙個 leader,任何 follower 都沒有,你認為 acks=all 有用嗎?

當然沒用了,因為 isr 裡就乙個 leader,它接收完訊息後宕機,也會導致資料丟失。

所以說,這個 acks=all,必須跟 isr 列表裡至少有 2 個以上的副本配合使用,起碼是有乙個 leader 和乙個 follower 才可以。

這樣才能保證說寫一條資料過去,一定是 2 個以上的副本都收到了才算是成功,此時任何乙個副本宕機,不會導致資料丟失。

什麼是高併發 ,詳細講解什麼是高併發 ,詳細講解

高併發 high concurrency 是網際網路分布式系統架構設計中必須考慮的因素之一,它通常是指,通過設計保證系統能夠同時並行處理很多請求。高併發相關常用的一些指標有響應時間 response time 吞吐量 throughput 每秒查詢率qps query per second 併發使用...

什麼是高防CDN?

高防cdn是為了更好的服務網路而出現的,是通過高防dns來實現的。高防cdn是通過智慧型化的系統判斷來路,再反饋給使用者,可以減輕使用者使用過程的複雜程度。通過智慧型dns解析,能讓 訪問者連線到響應的伺服器上,以避免某個伺服器因訪問者過多而癱瘓。它的優勢在於 自動化,引導式自助,內嵌資訊完善,錯誤...

kafka是如何實現高可用的

kafka面試中,經常會被問到kafka是如何實現高可用的。ha,也就是高可用,kafka 0.8版本之前是沒有ha的,如果乙個broker掛了,那麼這個分割槽也就是掛了,分區內的訊息都沒辦法繼續被消費。kafka 0.8版本之後引入了副本機制 replicas 副本機制也是分布式系統中的常用的機制...