這幾天在學習kafka,看了一些書和博文督弓,看到了一篇博文感受頗深(深感大學的課程其實是非常重要的)芦圾,所以這里就把這篇文章精簡一下,順便當給自己鞏固一下知識帝牡。
注:本文如與《寫程序的康德--kafka為什么這么快》有雷同往毡,純屬我抄他的。
眾所周知kafka的吞吐量比一般的消息隊列要高靶溜,號稱the fastest开瞭,那他是如何做到的,讓我們從以下幾個方面分析一下原因罩息。
生產者端
生產者負責寫入數據嗤详,Kafka會將消息持久化到磁盤,保證不會丟失數據瓷炮,Kafka采用了倆個技術提高寫入的速度断楷。
1.順序寫入:在大學的計算機組成(劃重點)里我們學過,硬盤是機械結構崭别,需要指針尋址找到存儲數據的位置冬筒,所以恐锣,如果是隨機IO,磁盤會進行頻繁的尋址舞痰,導致寫入速度下降土榴。Kafka使用了順序IO提高了磁盤的寫入速度,Kafka會將數據順序插入到文件末尾响牛,消費者端通過控制偏移量來讀取消息玷禽,這樣做會導致數據無法刪除,時間一長呀打,磁盤空間會滿矢赁,kafka提供了2種策略來刪除數據:基于時間刪除和基于partition文件的大小刪除。
2.Memory Mapped Files:這個和Java NIO中的內存映射基本相同贬丛,在大學的計算機原理里我們學過(劃重點)撩银,mmf直接利用操作系統(tǒng)的Page來實現文件到物理內存的映射,完成之后對物理內存的操作會直接同步到硬盤豺憔。mmf通過內存映射的方式大大提高了IO速率额获,省去了用戶空間到內核空間的復制。它的缺點顯而易見--不可靠恭应,當發(fā)生宕機而數據未同步到硬盤時抄邀,數據會丟失,Kafka提供了produce.type參數來控制是否主動的進行刷新昼榛,如果kafka寫入到mmp后立即flush再返回給生產者則為同步模式境肾,反之為異步模式。
消費者端
在這之前先來了解一下零拷貝:平時從服務器讀取靜態(tài)文件時胆屿,服務器先將文件從復制到內核空間准夷,再復制到用戶空間,最后再復制到內核空間并通過網卡發(fā)送出去莺掠,而零拷貝則是直接從內核到內核再到網卡,省去了用戶空間的復制读宙。
Kafka把所有的消息存放到一個文件中彻秆,當消費者需要數據的時候直接將文件發(fā)送給消費者,比如10W的消息共10M结闸,全部發(fā)送給消費者唇兑,10M的消息在內網中傳輸是非常快的桦锄,假如需要1s扎附,那么kafka的tps就是10w。Zero copy對應的是Linux中sendfile函數结耀,這個函數會接受一個offsize來確定從哪里開始讀取×粢梗現實中匙铡,不可能將整個文件全部發(fā)給消費者,他通過消費者傳遞過來的偏移量來使用零拷貝讀取指定內容的數據返回給消費者碍粥。
總結
Kafka快的原因是他將一個個消息變成一個文件鳖眼,通過mmp提高IO速度,寫入時在末尾直接添加嚼摩,讀取時通過偏移量直接返回钦讳。
最后說點原作者沒有說的
不能因為快我們的消息隊列就只選擇Kafka,技術的選型還是要結合具體的業(yè)務場景枕面,合適的才是最好的愿卒,不能只以快論英雄,這一點相信男同胞們深有體會潮秘。具體不同MQ的使用場景可以看我之前的文章琼开,《Kafka還是RabbitMQ?》唇跨。