在我們旅行于數據海洋的途中,如果把 Kafka 比作是一艘承載無數信息航行的快船,前文《Kafka實戰漫談:大數據領域的不敗王者》已經講述了如何搭建起這艘快船,讓它在起風的早晨開始了第一次航行。
但隨著大浪的拍打,我們必須讓它做好準備,以應對那些未知的暴風雨。
今天,我們來談談如何讓這艘快船變得更強壯——讓它有能力在風急浪高時穩穩地前行,不至于讓寶貴的數據貨物沉入海底。
在 Kafka 這艘數據游輪載著數據航行時,我們這些開發者——也就是船上的水手來說,Kafka 集群的高可用性、消息消費的一致性和延時隊列等都是確保數據航行安全的關鍵特性。
所以,拿起你的望遠鏡,讓我們來一探 Kafka 高級知識的奧秘吧!
說到 Kafka,許多人第一反應可能是:噢,一個消息中間件?
是的,但它遠不止如此。Kafka 的力量在于它的可伸縮性、可靠性以及高吞吐。
很多在業務中使用過 Kafka 的小伙伴肯定知道,搭建起一個高效的 Kafka 集群,就像在你的航船上裝備強大的引擎。
而恰當地處理消息的重復消費與延時,則猶如在粗獷的海浪中找到了平穩的航道。
(1) 堅不可摧的集群艦隊:Kafka 高可用
在高海拔時,Kafka 能夠展現它的“高”——高可用。
集群化部署后,即便是有節點失聯,系統也能自我修復。如同海中的艦隊,一艘艦船的失事并不意味著整個航線的中斷。
(2) 精確把握所有貨物:消費去重
重復消費在消息隊列中猶如誤投遞包裹。
在 Kafka 的運送數據時,要確保每條消息只被消費一次,我們得有高超的“航海術”——冪等性與事務。
(3) 總有延時的風浪:延時隊列處理
和海底的珍珠一樣,每個船上的數據包都有其“價值”,然而在時間的尺度上,它們的價值是變化的。
所有才有詩人說:人生遇到的每個人,出場順序真的很重要!這在消息中間件里也同樣適用。
人生沒有時光機,但 Kafka 的延時隊列有:它不僅可以發送實時消息,還能處理那些需要“重復呈現”的信息。
接下來,讓我們更深入地探索這艘快船的強大之處,以及如何利用它。首先,我們搭建一個 Kafka 集群。
我們啟動了三個容器,配置都略微不同——記住,每艘船都有其獨特的身份(broker.id)和自己的泊位(listeners)。
通過進入 Zookeeper 的客戶端檢查 Kafka 的狀態,就如同站在燈塔上檢查艦隊——確保每艘船都已就緒并在正確的位置。
啟動三個容器,server.properties 文件分別為:
# 1,2,3broker.id = 3# 49092,49093,49094listeners=PLAINTEXT://172.16.30.34:49094
校驗是否啟動成功,進入 zookeeper,查看:
# 進入客戶端./bin/zkCli.sh# 查看brokerls /brokers/ids
可以看到各自的 ID 都不同,說明 3 個節點啟動成功了:
我們在上篇文章中已經介紹了分區和副本的概念,現在,結合集群中的節點,我們進一步來理解它們。
有備無患,副本就好比是同型船的兄弟,一旦領軍的船只(leader)遇難,它們(follower)中的一員就會站出來,扛起大旗。
Kafka 的讀寫操作都發生在 leader 上,leader 還負責把數據同步給 foller。
當 leader 掛了,經過主從選舉,從 follower 中選出一個新的 leader。
在這里,Kafka 的調度能力展露無遺。
就像團隊合作的捕魚作業,一個 message 可能會被多個消費者(在不同的船上)處理,但恰到好處的通信保證了魚群的精確分配。
在集群中,我們可以借助以下命令來發送、消費消息:
# 向集群發送消息./kafka-console-producer.sh --broker-list 172.16.30.34:49092,172.16.30.34:49093,172.16.30.34:49094 --topic my-replicated-topic# 消費集群消息./kafka-console-consumer.sh --bootstrap-server 172.16.30.34:49092,172.16.30.34:49093,172.16.30.34:49094 --topic my-replicated-topic# 指定消費組消費集群消息./kafka-console-consumer.sh --bootstrap-server 172.16.30.34:49092,172.16.30.34:49093,172.16.30.34:49094 --from-beginning --consumer-property group.id=testGroup1 --topic my-replicated-topic
可以看到,消息發送成功了:
消息消費成功:
控制器如船隊的指揮官,遇見有需要改變的情況時能及時做出應答,無論是船只的增減,抑或是航線的變更。
每個 broker 在啟動時會向 zk 創建一個臨時序號節點【比如上面創建的broker節點 1,2,3】,獲得的最小序號 broker 會作為集群中的 controller,負責以下幾件事:
每一個水手都有其特定的崗位,如同 Kafka 在消費者與分區間實現的再平衡——這是一種資源優化的藝術,和分配負載均衡的請求類似。
在 Kafka 中,再平衡需要一個前提就是:消費組中的消費者沒有指定分區來消費。如果對消息指定了分區,rebalance 就不會生效。
并且,當消費組中的消費組和分區關系發生變化時,rebalance 才會觸發。這時,消息的分區會遵循以下幾個策略中的一種(可配置):
HW(high-weight,高水位)和 LEO(log-end-offset)是衡量副本最后消息位置的兩個重要指標,它們就像是船上的測深儀,確保了數據不被過早或不當地處理。
HW 是已完成 lead-follower 同步的位置,消費者無法消費到 HW 線之前的消息。并且,在完成同步以后,HW 線才更新,以防止消息丟失。
LEO 是指某個副本最后消費消息的位置,根據木桶效應,HW 一定不高于 LEO。
在 Kafka 的海域里,防止消息的丟失恰至關鍵。這就需要水手精準的操作——生產者要如同技術精湛的引導者,消費者像觀望遠方的瞭望者,及時地做出反饋。
對于生產者來說,可以采用以下方式來防止:
對于消費者來說,需要將自動提交改為手動提交,并且當消費完成后再進行 ack 應答。
這相當于網絡中的握手過程,消息包收到以后,給出反饋;如果沒有收到消息,就讓發送端或者 Kafka 重新發一次,以防止消息還沒消費就丟失了。
再精確的海圖也免不了失誤時出現。為避免消息被重復消費,生產者可能需要更謹慎,而消費者需要有追蹤每條消息唯一性的能力。
為了防止消息丟失,當生產者發送完消息后,會根據有無收到 ack 應答去決定是否重新發送消息。
當網絡抖動或者其它原因,導致生產者沒有收到 ack 時,消費者可能會收到兩條或多條相同的消息,造成重復消費。
解決方案有以下兩種:
由于生產者關閉重試后,可能會造成消息丟失,所以我們更推薦讓消費者用冪等性或者事務來防止重復消費,這在其它的消息隊列中也同樣適用。
就像在粗獷的風浪中維持航道一樣困難,Kafka 的有序消費要求很高。有時需要犧牲性能,專注于單一的分區和消費者。
Kafka 的順序消費會嚴重地犧牲性能,所以使用時需要做出權衡。
消息積壓如同海上的風暴,短時間內的消費者可能支撐不過生產者的速度,這時候可能需要更多的船只和船員加入作業。
當消費者的消費速度,遠遠趕不上生產消息的速度一段時間后,kafka 會堆積大量未消費的消息。
這會導致消費者尋址的速度越來越慢,kafka 對外提供服務的性能也越來越差,從而可能會造成整個服務鏈變慢,導致服務雪崩。
一般,我們通過多線程或橫向擴展的方式來解決:
有時,信息需要在特定的時刻獲取,就比如火車票待支付訂單 30min 后會自動過期。
Kafka 也可設定的延時隊列,就像是烹飪師傅精準控制火候,讓美食在最佳時間完美呈現。
方案如下:
過去,信號火一點即傳,如今,Kafka 使數據能在毫秒之間抵達世界的任何角落。
高可用性的秘密不在于單艦的堅固,而在于整個艦隊的協同。
去重、延時、消費順序的保證,使得 Kafka 成為一個強大且靈活的通信工具。
Kafka 也不僅僅是一個消息隊列,它是大數據時代的一艘高速航船,隨時準備穿梭于信息的海洋,破浪前行。而我們,作為水手和指揮官,應當熟悉船上每一個細節,以確保我們的貨物——數據,能安全、準確地到達預定的港口。
好了,現在,各位船長,讓我們起航吧!
本文鏈接:http://www.www897cc.com/showinfo-26-48759-0.html深入淺出Kafka:高可用、順序消費及冪等性
聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com