分布式之全面了解Kafka的使用與特性
不啰嗦,我們直接開(kāi)始!
引言
2020年,Kafka 依舊炙手可熱,一線大公司即使不用Kafka,但是自研產(chǎn)品也都是基于Kafka,或者完全借鑒Kafka設(shè)計(jì)思想,理論上來(lái)說(shuō),如果你還沒(méi)熟練掌握一個(gè)MQ框架,Kafka絕對(duì)是不錯(cuò)的選擇。
關(guān)于歷史,如果你感興趣了解一下,至少知道是哪個(gè)公司開(kāi)源的,Kafka最初于2011年在 LinkedIn 開(kāi)發(fā),自那時(shí)起經(jīng)歷了很多改進(jìn),后來(lái)捐獻(xiàn)給Apache基金,如今發(fā)展成為一個(gè)完整的平臺(tái),采用Scala和Java開(kāi)發(fā)的開(kāi)源流處理軟件。
Kafka 是我工作多年使用最多的消息中間件 ,特點(diǎn)是擁有巨大吞吐量(數(shù)百萬(wàn)/秒),作為當(dāng)下最流行的分布式,可水平擴(kuò)展,可容錯(cuò)的“消息系統(tǒng)”。
1、面試官:可以簡(jiǎn)述下Kafka架構(gòu)中比較重要的關(guān)鍵字嗎?
比如Partition,Broker,你都是怎么理解的?
問(wèn)題分析:Kafka基礎(chǔ)知識(shí)考察,因?yàn)镵afka出色的性能,在集群結(jié)構(gòu)上也有所不同,一些新的概念設(shè)計(jì)名字初學(xué)者可能搞不懂,構(gòu)建一個(gè) Kafka cluster 首先需要理解 topics, producers, consumers, and brokers 的概念。
答:關(guān)于Kafka我做了一些深入了解,它的設(shè)計(jì)思路還是很值得借鑒的,這其中有6個(gè)比較關(guān)鍵的名字概念,弄懂這幾個(gè)概念才能更好地了解Kafka的工作機(jī)制。
Producer
消息的生產(chǎn)方,如支付系統(tǒng)確認(rèn)用戶(hù)已經(jīng)支付,支付系統(tǒng)要通知訂單系統(tǒng)和物流系統(tǒng),支付系統(tǒng)就是生產(chǎn)者。
Consumer
消費(fèi)的接收方,Producer 的案例中,物流系統(tǒng)就是消費(fèi)方,前兩個(gè)都比較簡(jiǎn)單,我就不多說(shuō)了。
Topic
每條發(fā)布到MQ集群的消息都有一個(gè)類(lèi)別,這個(gè)類(lèi)別被稱(chēng)為topic,可以理解成一類(lèi)消息的名字。所有的消息都已topic作為單位進(jìn)行歸類(lèi)。
Partition
Kafka 物理上分區(qū)的概念,每個(gè) Topic 會(huì)分散在一個(gè)或多個(gè) Partition。一個(gè) Topic 的數(shù)據(jù)太大了,就分成小片,Kafka 為分區(qū)引入多副本模型,副本之間采用“一個(gè)leader多follower”的設(shè)計(jì),通過(guò)多副本實(shí)現(xiàn)故障自動(dòng)轉(zhuǎn)移,保證可用性。
Broker:
可以理解成一個(gè)服務(wù)器的節(jié)點(diǎn),集群包含一個(gè)或多個(gè)服務(wù)器,這種服務(wù)器被稱(chēng)為 broker。對(duì)應(yīng)用來(lái)說(shuō),生產(chǎn)者把消費(fèi)發(fā)出去了,就不管了。消費(fèi)者慢條斯理地按照自己的速率來(lái)消費(fèi)。這段時(shí)間可能有大量消息產(chǎn)生,消費(fèi)者壓力還是在一定范圍內(nèi)。做生產(chǎn)者和消費(fèi)者之間解耦的就是一個(gè)緩存服務(wù)broker。
Kafka Cluster
集群就是 Broker 的集合,多個(gè) Broker 組成一個(gè)高可用集群。
Producer 與 Consumer的關(guān)系
?topic 和 Partition 的關(guān)系
一個(gè)?topic?可以分別存儲(chǔ)到多個(gè)?Partition,每個(gè)?Partition?有序的。
到這里面試官并沒(méi)有打斷我… 我就繼續(xù)了。
那我們?yōu)槭裁匆x擇 Kafka 呢??
1.這里不再列舉同類(lèi)產(chǎn)品都具有的功能,直接總結(jié)干貨,Kafka 特有的功能:
2.相比同類(lèi)中間件 RabbitMQ or ActiveMQ,Kafka?支持批量拉取消息,大大增加了Kafka的消息吞吐量。
支持多種發(fā)送場(chǎng)景:
1.發(fā)送并忘記。
2.同步發(fā)送 。
3.異步發(fā)送+回調(diào)函數(shù)。
3種方式雖然在時(shí)間上有所差別,但并不是說(shuō)時(shí)間越快的越好,具體使用哪種方式要看具體的業(yè)務(wù)場(chǎng)景,比如業(yè)務(wù)要求消息必須是按順序發(fā)送,可以使用第2種同步發(fā)送,并且只能在一個(gè)partation上。如果業(yè)務(wù)只關(guān)心消息的吞吐量,容許少量消息發(fā)送失敗,也不關(guān)注消息的發(fā)送順序,那么可以使用發(fā)送并忘記的方式。如果業(yè)務(wù)需要知道消息發(fā)送是否成功,并且對(duì)消息的順序不關(guān)心,那么可以用異步+回調(diào)的方式來(lái)發(fā)送消息
3.分布式可高可擴(kuò)展。Kafka 集群可以透明的擴(kuò)展,增加新的服務(wù)器進(jìn)集群。
?只說(shuō)了 Kafka 的優(yōu)勢(shì),那別的同類(lèi)產(chǎn)品就不好了嗎?當(dāng)然不是,存在即真理,每個(gè)產(chǎn)品能生存下來(lái),一定有它自己的優(yōu)勢(shì),比如 RabbitMQ,在吞吐量方面稍遜于 Kafka ,但是他們的出發(fā)點(diǎn)不一樣,RabbitMQ 支持對(duì)消息的可靠的傳遞,支持事務(wù),不支持批量的操作,技術(shù)選型中,選擇最適合你的,你最了解熟悉的。
分布式 | 高性能 | 持久性和擴(kuò)展性 |
---|---|---|
支持多分區(qū) | 高吞吐量 | 數(shù)據(jù)可持久化 |
支持多副本 | 低延遲 | 容錯(cuò)性高 |
支持多訂閱者 | 高并發(fā) | 支持水平在線擴(kuò)展 |
基于ZooKeeper調(diào)度 | 時(shí)間復(fù)雜度為O(1) | 消息分發(fā)自動(dòng)平衡 |
言多必失,說(shuō)了一堆 Kafka 相比其他產(chǎn)品有多好多快,終于成功給自己挖了一個(gè)坑。(?),順著我的思路展開(kāi)了問(wèn)
2、面試官:那為什么Kafka的吞吐量遠(yuǎn)高于其他同類(lèi)中間件?
問(wèn)題分析:多年經(jīng)驗(yàn)總結(jié),面試中最吃虧的就是你把你不熟悉的東西寫(xiě)在簡(jiǎn)歷上,還有就是你知道結(jié)果,不知其原理,源碼沒(méi)看過(guò),好歹也要知道用了巧妙的設(shè)計(jì)。
答:Kafka 是一個(gè)高吞吐量分布式消息系統(tǒng),并且提供了持久化。其高性能的有兩個(gè)重要特點(diǎn):
1.利用了磁盤(pán)連續(xù)讀寫(xiě)性能遠(yuǎn)遠(yuǎn)高于隨機(jī)讀寫(xiě)的特點(diǎn),內(nèi)部采用消息的批量處理,zero-copy機(jī)制,數(shù)據(jù)的存儲(chǔ)和獲取是本地磁盤(pán)順序批量操作,具有O(1)的復(fù)雜度,消息處理的效率很高。
2.并發(fā),將一個(gè)topic拆分多個(gè)partition, kafka讀寫(xiě)的單位是partition,因此,將一個(gè)topic拆分為多個(gè)partition可以提高吞吐量。但是,這里有個(gè)前提,就是不同partition需要位于不同的磁盤(pán)(可以在同一個(gè)機(jī)器)。如果多個(gè)partition位于同一個(gè)磁盤(pán),那么意味著有多個(gè)進(jìn)程同時(shí)對(duì)一個(gè)磁盤(pán)的多個(gè)文件進(jìn)行讀寫(xiě),使得操作系統(tǒng)會(huì)對(duì)磁盤(pán)讀寫(xiě)進(jìn)行頻繁調(diào)度,也就是破壞了磁盤(pán)讀寫(xiě)的連續(xù)性。
在linkedlin的測(cè)試中,每臺(tái)機(jī)器就加載了6個(gè)磁盤(pán),并且不做ra,就是為了充分利用多磁盤(pán)并發(fā)讀寫(xiě),又保證每個(gè)磁盤(pán)連續(xù)讀寫(xiě)的特性。
同一個(gè)topic會(huì)被分散到多個(gè)分片上,并行處理。?
深入分析
Kafka 消息的生產(chǎn)與消費(fèi)模型Demo
偽代碼:使用KafKa客戶(hù)端發(fā)送一條消息
public class MqProducer { private final Logger LOG = LoggerFactory.getLogger(MqProducer.class); @Resource private Producer payProducer; public void sendPayMsg(String msg) { try { LOG.debug("send msg:{}", msg); payProducer.send(msg);//發(fā)送出去一條消息。 } catch (MQException e) { LOG.error("mq消息異常 message:{}", msg, e); } } }
長(zhǎng)什么樣子?
即payProducer.send(msg)里的msg的值:
{"businessType":1,"cityId":10,"ctime":1567426767077,"dataKey":20190902,"logType":1,"phone":"13212341234","uid":12345678,"userType":1,"uuid":"32EA02C86D78863"}
無(wú)論消息長(zhǎng)短,都可以看作一個(gè)json串,用 key-value的形式傳遞信息。
偽代碼:接收一條消息
public class DemoConsumer { /** * 注意:服務(wù)端對(duì)單ip創(chuàng)建相同主題相同隊(duì)列的消費(fèi)者實(shí)例數(shù)有限制,超過(guò)100個(gè)拒絕創(chuàng)建. * */ private static IConsumerProcessor consumer; public static void main(String[] args) throws Exception { Properties properties = new Properties(); properties.setProperty(ConsumerConstants.SubscribeGroup, "dache.risk.log.queue.v2"); // 創(chuàng)建topic對(duì)應(yīng)的consumer對(duì)象(注意每次build調(diào)用會(huì)產(chǎn)生一個(gè)新的實(shí)例) consumer = KafkaClient.buildConsumerFactory(properties, "topic.xxx.xxx"); // 調(diào)用recvMessageWithParallel設(shè)置listener consumer.recvMessageWithParallel(String.class, new IMessageListener() { @Override public ConsumeStatus recvMessage(Message message, MessagetContext context) { //TODO:業(yè)務(wù)側(cè)的消費(fèi)邏輯代碼 try { System.out.println("message=[" + message.getBody() + "] partition=" + message.getParttion()); } catch (Exception e) { e.printStackTrace(); } return ConsumeStatus.CONSUME_SUCCESS; } }); } }
附錄:消息管理工具
如果你們剛剛搭建起Kafka集群,還沒(méi)有完備的頁(yè)面管理系統(tǒng),你不妨了解一下這幾款開(kāi)源工具,給領(lǐng)導(dǎo)展示一下解決問(wèn)題的能力。
為了簡(jiǎn)化開(kāi)發(fā)者和服務(wù)工程師維護(hù) Kafka 集群的工作,基于頁(yè)面的管理工具必不可少。
常用 Kafka 開(kāi)源管理工具:
Kafka Manager?:由 yahoo 團(tuán)隊(duì)開(kāi)發(fā)。使用可參考:https://github.com/yahoo/kafka-manager
Kafka Lens:開(kāi)源項(xiàng)目,允許開(kāi)發(fā)人員在通過(guò)代理傳遞消息時(shí)查看消息,也可以按分區(qū)過(guò)濾消息。
參考:https://github.com/kafka-lens/kafka-lens
圖片來(lái)源:Kafka Lens
Kafka Monitor?:測(cè)試和監(jiān)視Kafka集群,而不需要對(duì)應(yīng)用程序進(jìn)行任何更改。
使用參考:https://github.com/linkedin/kafka-monitor
總結(jié)
Kafka架構(gòu)關(guān)鍵字:
- Producer
- Consumer
- Topic
- Partition
- Broker
- Kafka Cluster
每一個(gè)關(guān)鍵詞都值得你深入研究,讓面試官看到你的亮點(diǎn)吧。
Kafka的性能為何如此優(yōu)秀:一句話總結(jié):得益于架構(gòu)采用分布式并行處理,利用磁盤(pán)順序IO批處理。
參考資料
Thorough Introduction to Apache Kafka
如果你想系統(tǒng)了解下Kafka,可以推薦一本書(shū)《深入理解Kafka:核心設(shè)計(jì)與實(shí)踐原理》,微信讀書(shū)就可以免費(fèi)閱讀。
到此這篇關(guān)于分布式之全面了解Kafka的使用與特性的文章就介紹到這了,更多相關(guān)Kafka的使用內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Spring通過(guò)ApplicationContext主動(dòng)獲取bean的方法講解
今天小編就為大家分享一篇關(guān)于Spring通過(guò)ApplicationContext主動(dòng)獲取bean的方法講解,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2019-03-03一篇文章教帶你了解Java Spring之自動(dòng)裝配
今天小編就為大家分享一篇關(guān)于Spring中的自動(dòng)裝配,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2021-09-09Spring?Boot整合Zookeeper實(shí)現(xiàn)分布式鎖的場(chǎng)景分析
這篇文章主要介紹了Spring?Boot整合Zookeeper實(shí)現(xiàn)分布式鎖,zk實(shí)現(xiàn)分布式鎖完全是依靠zk節(jié)點(diǎn)類(lèi)型當(dāng)中的臨時(shí)序號(hào)節(jié)點(diǎn)來(lái)實(shí)現(xiàn)的,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2022-06-06Springboot Apollo配置yml的問(wèn)題及解決方案
這篇文章主要介紹了Springboot Apollo配置yml的問(wèn)題及解決方案,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-06-06Spring實(shí)現(xiàn)聲明式事務(wù)的方法詳解
這篇文章主要介紹了Spring實(shí)現(xiàn)聲明式事務(wù)的方法詳解,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-01-01springboot整合shardingsphere和seata實(shí)現(xiàn)分布式事務(wù)的實(shí)踐
本文主要介紹了springboot整合shardingsphere和seata實(shí)現(xiàn)分布式事務(wù)的實(shí)踐,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-07-07