最近工做中呢,頻頻用到消息中心,包括異步轉同步的功能,分佈式收集日誌信息等功能,在面試中也常會問到候選人關於消息中心的知識點,但大多數程序員,尤爲是工做兩三年的,雖然平時工做中都有用到消息中心,但都老是不可以說明白其中的原理,因而以爲有必要把消息中心做爲一個篇章,專門進行總結梳理一番~看的時候,建議你們不妨先看看問題,本身先嚐試回答一下,再看答案。看看本身掌握得如何了那準備好了的話,咱們就要開始啦啊~前端
01.爲何要使用消息中心?
消息中心,有如下幾大做用:程序員
- 消息通信:能夠做爲基本的消息通信,好比聊天室等工具的使用
- 異步處理 : 將一些實時性要求不是很強的業務異步處理,起到緩衝的做用,必定程度上也會避免由於有些消費者處理的太慢或者網絡問題致使的通信等待過久,於是致使的單個服務崩潰,甚至產生多個服務間的雪崩效應;
- 應用解耦 : 消息隊列將消息生產者和消費者分離開來,能夠實現應用解耦
- 流量削峯: 能夠經過在應用前端採用消息隊列來接收請求,能夠達到削峯的目的:請求超過隊列長度直接不處理,重定向至錯誤頁面。相似於網關限流的做用冗餘存儲:消息隊列把數據進行持久化,直到它們已經被徹底處理,經過這一方式規避了數據丟失風險
02.聊聊Kafka的特色
- 可靠性:Kafka是分佈式的、可分區的、數據可備份的、高度容錯的
- 可擴展性:在無需停機的狀況下實現輕鬆擴展
- 消息持久性:Kafka支持將消息持久化到本地磁盤
- 高性能:Kafka的消息發佈訂閱具備很高的吞吐量,即使存儲了TB級的消息,它依然能保持穩定的性能
03.你會在哪些場景選擇使用Kafka?
1)日誌信息收集記錄我我的接觸的項目中,Kafka使用最多的場景,就是用它與FileBeats和ELK組成典型的日誌收集、分析處理以及展現的框架web
該圖爲FileBeats+Kafka+ELK集羣架構。Kafka在框架中,做爲消息緩衝隊列面試
FileBeats先將數據傳遞給消息隊列,Logstash server(二級Logstash)拉取消息隊列中的數據,進行過濾和分析,而後將數據傳遞給Elasticsearch進行存儲,最後,再由Kibana將日誌和數據呈現給用戶數據庫
因爲引入了Kafka緩衝機制,即便遠端Logstash server因故障中止運行,數據也不會丟失,可靠性獲得了大大的提高服務器
2)用戶軌跡跟蹤:kafka常常被用來記錄web用戶或者app用戶的各類活動,如瀏覽網頁、搜索、點擊等操做,這些活動信息被各個服務器發佈到kafka的topic中,而後消費者經過訂閱這些topic來作實時的監控分析,固然也能夠保存到數據庫網絡
3)運營指標:kafka也常常用來記錄運營監控數據。包括收集各類分佈式應用的數據,生產各類操做的集中反饋,好比報警和報告架構
4)流式處理:好比spark streaming和storm併發
04.Kafka使用哪一種方式消費消息,pull仍是push?
Kafka的消費者使用pull(拉)的方式將消息從broker中拉下來app
1 這樣作的好處是:
1)Kafka能夠根據consumer的消費能力以適當的速率消費消息
2)消費者能夠控制本身的消費方式:可使用批量消費,也能夠選擇逐條消費
3)消費者還能夠選擇不一樣的提交方式來實現不一樣的傳輸語義,要是使用了push的方式,就沒有這些優勢了
2 缺點是:
會出現一種狀況:若是Kafka沒有數據,消費者會專門有個線程去等待數據,可能會陷入循環等待中
3 Kafka如何避免這一缺點:
咱們能夠經過在拉請求中設置參數,容許消費者請求在等待數據到達的「長輪詢」中進行阻塞(而且可選地等待到給定的字節數,以確保大的傳輸大小)來避免這一問題
4 關於push的方式的話,它的優勢是:
1)相對於pull的方式來講,它不須要專門有一個消息去等待,而可能形成線程循環等待的問題
2)它的缺點是: push(推)模式通常是會以一樣的速率將消息推給消費者,很難適應消費速率不一樣的消費者,這樣很容易形成有些消費能力比較低的consumer來不及處理消息,致使出現拒絕服務以及網絡擁塞的狀況
05.Kafka與Zookeeper是什麼關係?
Kafka的數據會存儲在zookeeper上。包括broker和消費者consumer的信息 其中,
broker信息:包含各個broker的服務器信息、Topic信息
消費者信息:主要存儲每一個消費者消費的topic的offset的值
06.聊聊Kafka的架構
總的來講,Kafka是分爲三個角色:Producer、Kafka集羣以及Consumer生產者將消息發送到Kafka集羣,而後消費者再去Kafka集羣進行消息的消費
稍微具體一點,就是下面這幅圖
1)圖中,除了包含前面說到的生產者Producer、Kafka集羣以及消費者Consumer三個角色以外,還包含了用於存儲信息的註冊中心-Zookeeper
2)生產者:很明顯,它是消息的生產者,用於發送消息的客戶端
3)消費者:消息的消費者,用於消費消息的客戶端。
4)消費者組:kafka的消費者角色,還有消費者組的概念,也就是說每一個消費者組中能夠包含多個consumer。其中,Kafka規定,消費者組中的消費者不能同時消費topic中的同一分區
好比說,圖中,消費者組中包含Consumer A 和Consumer B兩個,對於有兩個分區的topic A,Consumer A消費了partition0,這時Consumer B就不能消費partition0的消息了,它只能消費partition1中的消息
延伸出消息如何保證順序?
由於隊列的先進先出的特色,保證了消息在發送的時候是有序的,而在同一個分區中,它是被一個消費者所消費的,那麼它就也能夠在一個分區中,保證消費消息時的順序性。而在一個有兩個及兩個以上的topic內的話,就不能保證消息的順序性了
所以,想要保證消息的順序性,只在新建topic時,指定一個分區便可
5)Kafka集羣:消息存儲轉發的地方,通常是集羣的方式存在,而每一個集羣節點稱爲一個broker
6)Zookeeper:用於存儲broker信息和消費者信息
7)broker:即Kafka集羣的一臺機器,可包含多個Topic
8)Topic : 主題,能夠理解爲一個隊列
9)Partation: 隊列Topic的分區,一個Topic能夠分爲多個分區,用於高併發場景的負載功能;實際上Topic只是一個邏輯概念,真正存在的是分區
10)Offset:即隊列中當前讀取消息的位置。順便說一下,kafka的存儲文件都是按照offset.kafka來命名,使用offset作名字,就方便查找。例如你想找位於2035的位置,只要找到2035.kafka的文件便可
07.Kafka的緩衝池滿了怎麼辦?
不管消息是否被消費,kafka都會保留全部消息。而當消息的大小,大於設置的最大值log.retention.bytes(默認爲1073741824)的值,也就是說這個緩衝池滿了的時候,Kafka便會清除掉舊消息
那麼它每次刪除多少消息呢?
topic的分區partitions,被分爲一個個小segment,按照segment爲單位進行刪除(segment的大小也能夠進行配置,默認log.segment.bytes = 1024 1024 1024),由時間從遠到近的順序進行刪除
此外,Kafka還支持基於時間策略進行刪除數據,過時時間默認爲:log.retention.hours=168
注意:由於Kafka讀取特定消息的時間複雜度爲O(1),即與文件大小無關,因此這裏刪除過時文件與提升 Kafka 性能無關
08.數據傳輸的事務有幾種?
有如下三種:
- 最多一次(<=1): 消息不會被重複發送,最多被傳輸一次,但也有可能一次不傳輸
- 最少一次(>=1):消息不會被漏發送,最少被傳輸一次,但也有可能被重複傳輸
- 精確的一次(Exactly once)(=1): 不會漏傳輸也不會重複傳輸,每一個消息都傳輸被一次並且僅僅被傳輸一次,這是你們所指望的那麼,每種傳輸,分別是怎樣實現的呢?
- 最多一次:consumer先讀消息,記錄offset,最後再處理消息
這樣,不可避免地存在一種可能:在記錄offset以後,還沒處理消息就出現故障了,新的consumer會繼續從這個offset處理,那麼就會出現有些消息永遠不會被處理。那麼這種機制,就是消息最多被處理一次
最少一次:consumer能夠先讀取消息,處理消息,最後記錄offset
固然若是在記錄offset以前就crash了,新的consumer會重複的消費一些消息。那麼這種機制,就是消息最多被處理一次
精確一次:能夠經過將提交分爲兩個階段來解決:保存了offset後提交一次,消息處理成功以後再提交一次。固然也能夠直接將消息的offset和消息被處理後的結果保存在一塊兒,這樣就可以保證消息可以被精確地消費一次
09.Kafka在什麼狀況下會出現消息丟失?
如下幾個階段,都有可能會出現消息丟失的狀況
1)消息發送的時候,若是發送出去之後,消息可能由於網絡問題並無發送成功
2)消息消費的時候,消費者在消費消息的時候,若還未作處理的時候,服務掛了,那這個消息不就丟失了
3)分區中的leader所在的broker掛了以後
咱們知道,Kafka的Topic中的分區Partition是leader與follower的主從機制,發送消息與消費消息都直接面向leader分區,並不與follower交互,follower則會去leader中拉取消息,進行消息的備份,這樣保證了必定的可靠性
可是,當leader副本所在的broker忽然掛掉,那麼就要從follower中選舉一個leader,但leader的數據在掛掉以前並無同步到follower的這部分消息確定就會丟失掉
10.Kafka的性能好在什麼地方?
Kafka的性能好在兩個方面:順序寫和零拷貝
1)順序寫
咱們知道,操做系統每次從磁盤讀寫數據的時候,都須要找到數據在磁盤上的地址,再進行讀寫。而若是是機械硬盤,尋址須要的時間每每會比較長
而通常來講,若是把數據存儲在內存上面,少了尋址的過程,性能會好不少;但Kafka 的數據存儲在磁盤上面,依然性能很好,這是爲何呢?
這是由於,Kafka採用的是順序寫,直接追加數據到末尾。實際上,磁盤順序寫的性能極高,在磁盤個數必定,轉數必定的狀況下,基本和內存速度一致
所以,磁盤的順序寫這一機制,極大地保證了Kafka自己的性能
2)零拷貝
好比:讀取文件,再用socket發送出去這一過程
buffer = File.read Socket.send(buffer)
傳統方式實現:
先讀取、再發送,實際會通過如下四次複製
- 將磁盤文件,讀取到操做系統內核緩衝區Read Buffer
- 將內核緩衝區的數據,複製到應用程序緩衝區Application Buffer
- 將應用程序緩衝區Application Buffer中的數據,複製到socket網絡發送緩衝區
- 將Socket buffer的數據,複製到網卡,由網卡進行網絡傳輸
傳統方式,讀取磁盤文件並進行網絡發送,通過的四次數據copy是很是繁瑣的
從新思考傳統IO方式,會注意到在讀取磁盤文件後,不須要作其餘處理,直接用網絡發送出去的這種場景下,第二次和第三次數據的複製過程,不只沒有任何幫助,反而帶來了巨大的開銷。那麼這裏使用了零拷貝,也就是說,直接由內核緩衝區Read Buffer將數據複製到網卡,省去第二步和第三步的複製。
這樣一定會大大減小讀取的開銷,使得Kafka讀取消息的性能有一個質的提高
總結
總而言之
本次文章經過10個常見的Kafka經典面試題,帶你們再次從新學習了一次Kafka,相信你們可以掌握得更深刻一些了。
想一想本身當年在畢業第一年,實際上就已經開始使用Kafka了,可是當時就只知道它是個消息中心,對於它的特色啊,原理啊一無所知;第二年,由於要作新項目,有機會了解了一下,大概知道了它的框架,一些基本概念,但當時的學習,也還只是照本宣科,網上說多少是能夠獲得多少,但不少東西根本無法消化,記了不少筆記也老是無法給別人講得特別清楚;直到如今,有了必定的學習和實戰經驗,再去看它,你會發現彷佛一切都變得簡單,你的腦子裏很容易就出現了它的架構全局,它的一些特色,對於它的一些設計思路表示親切與讚揚。並且不少東西,在看的時候,你會以爲更輕鬆,也會有一些本身的理解,而且基本不用作太多的筆記,即可以很快理解它的原理,由於此次是真正地學會了
因此,每一個階段都有每一個階段該作的事,可能正由於以前的填鴨式地學習基礎,纔會有今天的快速理解的效果。不斷學習纔是真理,它會讓你不斷髮現驚喜,包括對外界的,也包括對你本身的