Kafka實現細節(三)


如果你第一次看kafka的文章,請先看《分布式消息系統kafka初步》

之前有人問kafka和一般的MQ之間的區別,這個問題挺難回答,我覺得不如從kafka的實現原理來分析更為透徹,這篇將依據官網上給出的design來詳細的分析,kafka是如何實現其高性能、高吞吐的。這一段應該會挺長的我想分兩篇來寫。今天這一篇主要從宏觀上說kafka實現的細節,下一篇,在從具體的技術上去分析。

我們先看kafka的設計元素:

1. 通常來說,kafka的使用是為了消息的持久化(persistent messages)

2. 吞吐量是kafka設計的主要目標

3. 關於消費的狀態被記錄為consumer的一部分,而不是server。這點稍微解釋下,這里的server還是只broker,誰消費了多少數據都記錄在消費者自己手中,不存在broker中。按理說,消費記錄也是一個日志,可以放在broker中,至於為什么要這么設計,我們寫下去了再說。

4. Kafka的分布式可以表現在producer、broker、consumer都可以分布在多台機器上。

在講實現原理之前,我們還得了解幾個術語:

l  Topic:其實官網上沒有單獨提這個詞,但topic其實才是理解的關鍵,在kafka中,不同的數據可以按照不同的topic存儲。

l  Message:消息是kafka處理的對象,在kafka中,消息是被發布到broker的topic中。而consumer也是從相應的topic中拿數據。也就是說,message是按topic存儲的。

l  Consumer Group:雖然上面的設計元素第四條,我們說三者都可以部署到多台機器上,三者分別並作為一個邏輯的group,但對於consumer來說這樣的部署需要特殊的支持。Consumer Group就是讓多個(相關的)進程(機器)在邏輯上扮演一個consumer。這個group的定義其實是為了去支持topic這樣的語義。在JMS中,大家最熟悉的是隊列,我們將所有的consumer放到一個group中,這樣就是隊列。而topic則是將consumer放置到與它相關的topic中去。所以無論一個topic存在於多少個consumer中, a message is stored only a single time。你可能會有疑問,備份怎么辦,接着看下去。

接下來,我們來看kafka的實現究竟依賴了哪些東西。

 

1.  硬件上,kafka選用了硬盤直接讀寫,當然這里也有策略。一個67200rpm STAT RAID5的陣列,線性讀寫速度是300MB/sec,如果是隨機讀寫,速度則是50K/sec。差距很明顯,所以kafka選的策略就是利用線性存儲,至於怎么存,我們在存儲中會說到。

2.  關於緩存,kafka沒有使用內存作為緩存。操作系統用個特性,如果不用direct I/O,那些閑置的memory會去做disk caching,如果 a process maintains an in-process cache of the data,這樣的情況下可能會產生雙份的pagecache,會存儲兩遍。另外Kafka跑在JVM上,本身JVM垃 圾回收、創建對象都非常的耗內存,所以不再依賴於內存做緩存。All data is immediately written to a persistent log on the filesystem without any call to flush the data. 當然內核自己的flush不算了。溫泉做一次32G的內存緩存,需要大概10多分鍾。

3.    Liner writer/reader:這樣做的雖然沒有B樹那樣多樣的變化,但卻有O(1)的操作,而且讀寫不會相互影響。同時,線性的讀寫也解耦了數據規模的問題。用廉價的存儲就可以達到很高的性價比。

4.    Zero-copy:將數據從硬盤寫到socket一般需要經過…你可以自己算一下,這是操作系統里的知識,答案在文章末尾,具體也可以看這里:http://my.oschina.net/ielts0909/blog/85147。一句話,Zero-copy減少了IO的操作步驟。

5.   GZIP and Snappy compression:考慮到傳輸最大的瓶頸就在於網絡上,kafka提供了對數據壓縮的各種協議。

6.   事務機制:雖然kafka對事務的處理比較薄弱,但是在message的分發上還是做了一定的策略來保證數據遞送的准確性:

At most once—this handles the first case described. Messages are immediately marked as consumed, so they can't be given out twice, but many failure scenarios may lead to losing messages.

At least once—this is the second case where we guarantee each message will be delivered at least once, but in failure cases may be delivered twice.

Exactly once—this is what people actually want, each message is delivered once and only once.

上述就是關於kafka的實現細節,主要寫了關於kafka采用到的技術和使用技術的原因,在后面一篇中,我將主要講述producer、broker、consumer之間的配合以及kafka的存儲問題。

 --------------------------------------------------------------------------------

 

To understand the impact of sendfile, it is important to understand the common data path for transfer of data from file to socket:

  1. The operating system reads data from the disk into pagecache in kernel space
  2. The application reads the data from kernel space into a user-space buffer
  3. The application writes the data back into kernel space into a socket buffer
  4. The operating system copies the data from the socket buffer to the NIC buffer where it is sent over the network

其實zero-copy這個技術我們已經在使用了,在NIO中的FileChannel中的transferTo就是采用這樣的原理的。

 

在這一篇,我想主要寫點兒kafka的存儲,以及對前文kafka的分布式一些補充,kafka的應用中,分布式使用是一個很關鍵的主題,更好的理解producer、broker和consumer的分布式構建有利於提高系統整體的性能。這部分理論其實很簡單,所以就不花大精力去寫了。

在上一篇中,我們說到了kafka直接使用硬盤作為存儲,並且不使用內存緩存。我們還說到,之所以要這么應用,主要是考慮到硬盤在線性讀寫時候速度完全能滿足要求,以及使用內存緩存會帶來的一些負面影響。如果你不是很了解,可以先看看之前的那篇。

 

有關存儲方面,我們要引進幾個概念:

l  Partition:同一個topic下可以設置多個partition,目的是為了提高並行處理的能力。可以將同一個topic下的message存儲到不同的partition下。

l  Offset:kafka的存儲文件都是按照offset.kafka來命名,用offset做名字的好處是方便查找。例如你想找位於2049的位置,只要找到2048.kafka的文件即可。當然the first offset就是00000000000.kafka。

l  Messages:這里寫下message的構成,a fixed-size header和variable length opaque byte array payload組成。Header由version和checksum組成,checksum采用CRC32。

下圖就反應了日志都是append的這一個過程:

 

在寫的時候會有兩個參數需要注意:The log takes two configuration parameter M which gives the number of messages to write before forcing the OS to flush the file to disk, and S which gives a number of seconds after which a flush is forced. 

 

在分布式方面:

1.   broker的部署是一種no central master的概念,並且每個節點都是同等的,節點的增加和減少都不需要改變任何配置。

2.   producer和consumer通過zookeeper去發現topic,並且通過zookeeper來協調生產和消費的過程。

3.   producer、consumer和broker均采用TCP連接,通信基於NIO實現。Producer和consumer能自動檢測broker的增加和減少。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM