久久久久久久视色,久久电影免费精品,中文亚洲欧美乱码在线观看,在线免费播放AV片

<center id="vfaef"><input id="vfaef"><table id="vfaef"></table></input></center>

    <p id="vfaef"><kbd id="vfaef"></kbd></p>

    
    
    <pre id="vfaef"><u id="vfaef"></u></pre>

      <thead id="vfaef"><input id="vfaef"></input></thead>

    1. 站長資訊網(wǎng)
      最全最豐富的資訊網(wǎng)站

      Kafka日志存儲原理

      引言

      Kafka中的Message是以topic為基本單位組織的,不同的topic之間是相互獨立的。每個topic又可以分成幾個不同的partition(每個topic有幾個partition是在創(chuàng)建topic時指定的),每個partition存儲一部分Message。借用官方的一張圖,可以直觀地看到topic和partition的關(guān)系。
      Kafka日志存儲原理

      partition是以文件的形式存儲在文件系統(tǒng)中,比如,創(chuàng)建了一個名為page_visits的topic,其有5個partition,那么在Kafka的數(shù)據(jù)目錄中(由配置文件中的log.dirs指定的)中就有這樣5個目錄: page_visits-0, page_visits-1,page_visits-2,page_visits-3,page_visits-4,其命名規(guī)則為<topic_name>-<partition_id>,里面存儲的分別就是這5個partition的數(shù)據(jù)。

      接下來,本文將分析partition目錄中的文件的存儲格式和相關(guān)的代碼所在的位置。

      Partition的數(shù)據(jù)文件

      Partition中的每條Message由offset來表示它在這個partition中的偏移量,這個offset不是該Message在partition數(shù)據(jù)文件中的實際存儲位置,而是邏輯上一個值,它唯一確定了partition中的一條Message。因此,可以認為offset是partition中Message的id。partition中的每條Message包含了以下三個屬性:

      • offset
      • MessageSize
      • data

      其中offset為long型,MessageSize為int32,表示data有多大,data為message的具體內(nèi)容。它的格式和Kafka通訊協(xié)議中介紹的MessageSet格式是一致。

      Partition的數(shù)據(jù)文件則包含了若干條上述格式的Message,按offset由小到大排列在一起。它的實現(xiàn)類為FileMessageSet,類圖如下:
      Kafka日志存儲原理
      它的主要方法如下:

      • append: 把給定的ByteBufferMessageSet中的Message寫入到這個數(shù)據(jù)文件中。
      • searchFor: 從指定的startingPosition開始搜索找到第一個Message其offset是大于或者等于指定的offset,并返回其在文件中的位置Position。它的實現(xiàn)方式是從startingPosition開始讀取12個字節(jié),分別是當(dāng)前MessageSet的offset和size。如果當(dāng)前offset小于指定的offset,那么將position向后移動LogOverHead+MessageSize(其中LogOverHead為offset+messagesize,為12個字節(jié))。
      • read:準確名字應(yīng)該是slice,它截取其中一部分返回一個新的FileMessageSet。它不保證截取的位置數(shù)據(jù)的完整性。
      • sizeInBytes: 表示這個FileMessageSet占有了多少字節(jié)的空間。
      • truncateTo: 把這個文件截斷,這個方法不保證截斷位置的Message的完整性。
      • readInto: 從指定的相對位置開始把文件的內(nèi)容讀取到對應(yīng)的ByteBuffer中。

      我們來思考一下,如果一個partition只有一個數(shù)據(jù)文件會怎么樣?

      1. 新數(shù)據(jù)是添加在文件末尾(調(diào)用FileMessageSet的append方法),不論文件數(shù)據(jù)文件有多大,這個操作永遠都是O(1)的。
      2. 查找某個offset的Message(調(diào)用FileMessageSet的searchFor方法)是順序查找的。因此,如果數(shù)據(jù)文件很大的話,查找的效率就低。

      那Kafka是如何解決查找效率的的問題呢?有兩大法寶:1) 分段 2) 索引。

      數(shù)據(jù)文件的分段

      Kafka解決查詢效率的手段之一是將數(shù)據(jù)文件分段,比如有100條Message,它們的offset是從0到99。假設(shè)將數(shù)據(jù)文件分成5段,第一段為0-19,第二段為20-39,以此類推,每段放在一個單獨的數(shù)據(jù)文件里面,數(shù)據(jù)文件以該段中最小的offset命名。這樣在查找指定offset的Message的時候,用二分查找就可以定位到該Message在哪個段中。

      為數(shù)據(jù)文件建索引

      數(shù)據(jù)文件分段使得可以在一個較小的數(shù)據(jù)文件中查找對應(yīng)offset的Message了,但是這依然需要順序掃描才能找到對應(yīng)offset的Message。為了進一步提高查找的效率,Kafka為每個分段后的數(shù)據(jù)文件建立了索引文件,文件名與數(shù)據(jù)文件的名字是一樣的,只是文件擴展名為.index。
      索引文件中包含若干個索引條目,每個條目表示數(shù)據(jù)文件中一條Message的索引。索引包含兩個部分(均為4個字節(jié)的數(shù)字),分別為相對offset和position。

      • 相對offset:因為數(shù)據(jù)文件分段以后,每個數(shù)據(jù)文件的起始offset不為0,相對offset表示這條Message相對于其所屬數(shù)據(jù)文件中最小的offset的大小。舉例,分段后的一個數(shù)據(jù)文件的offset是從20開始,那么offset為25的Message在index文件中的相對offset就是25-20 = 5。存儲相對offset可以減小索引文件占用的空間。
      • position,表示該條Message在數(shù)據(jù)文件中的絕對位置。只要打開文件并移動文件指針到這個position就可以讀取對應(yīng)的Message了。

      index文件中并沒有為數(shù)據(jù)文件中的每條Message建立索引,而是采用了稀疏存儲的方式,每隔一定字節(jié)的數(shù)據(jù)建立一條索引。這樣避免了索引文件占用過多的空間,從而可以將索引文件保留在內(nèi)存中。但缺點是沒有建立索引的Message也不能一次定位到其在數(shù)據(jù)文件的位置,從而需要做一次順序掃描,但是這次順序掃描的范圍就很小了。

      在Kafka中,索引文件的實現(xiàn)類為OffsetIndex,它的類圖如下:
      Kafka日志存儲原理

      主要的方法有:

      • append方法,添加一對offset和position到index文件中,這里的offset將會被轉(zhuǎn)成相對的offset。
      • lookup, 用二分查找的方式去查找小于或等于給定offset的最大的那個offset

      小結(jié)

      我們以幾張圖來總結(jié)一下Message是如何在Kafka中存儲的,以及如何查找指定offset的Message的。

      Message是按照topic來組織,每個topic可以分成多個的partition,比如:有5個partition的名為為page_visits的topic的目錄結(jié)構(gòu)為:
      Kafka日志存儲原理

      partition是分段的,每個段叫LogSegment,包括了一個數(shù)據(jù)文件和一個索引文件,下圖是某個partition目錄下的文件:
      Kafka日志存儲原理
      可以看到,這個partition有4個LogSegment。

      查找Message原理圖:
      Kafka日志存儲原理
      比如:要查找絕對offset為7的Message:

      1. 首先是用二分查找確定它是在哪個LogSegment中,自然是在第一個Segment中。
      2. 打開這個Segment的index文件,也是用二分查找找到offset小于或者等于指定offset的索引條目中最大的那個offset。自然offset為6的那個索引是我們要找的,通過索引文件我們知道offset為6的Message在數(shù)據(jù)文件中的位置為9807。
      3. 打開數(shù)據(jù)文件,從位置為9807的那個地方開始順序掃描直到找到offset為7的那條Message。

      這套機制是建立在offset是有序的。索引文件被映射到內(nèi)存中,所以查找的速度還是很快的。

      一句話,Kafka的Message存儲采用了分區(qū)(partition),分段(LogSegment)和稀疏索引這幾個手段來達到了高效性。

       

      Kafka使用jmxtrans+influxdb+grafana監(jiān)控JMX指標  http://www.sfodin.cn/Linux/2019-04/158037.htm

       

      Kafka單機環(huán)境搭建簡記  http://www.sfodin.cn/Linux/2019-03/157651.htm

       

       

      贊(0)
      分享到: 更多 (0)
      網(wǎng)站地圖   滬ICP備18035694號-2    滬公網(wǎng)安備31011702889846號