3.6.3 获取分区的读取偏移量
3.6.3 獲取分區(qū)的讀取偏移量
讀取分區(qū)的偏移量涉及日志存儲,這里我們先給出一些簡單的結(jié)論(具體細(xì)節(jié)會在第6章詳細(xì)分析):一個分區(qū)有多個片段文件(Segment),每個片段文件都包含全局有序的片段基準(zhǔn)偏移量(segmentBaseOffset)。客戶端調(diào)用getlastOffset()獲取的是每個片段文件的基準(zhǔn)偏移量。
客戶端發(fā)送的偏移氈’請求(OffsetRequest)包含的數(shù)據(jù)是:分區(qū)偏移量的請求信息(PartitionOffsetinfo)。這個對象有兩個參數(shù):whichTime表示拉取的時間戳,默認(rèn)第一次拉取的時間戳為EarliestTime=-2,如果拉取響應(yīng)的錯誤碼是OffsetOutofRange,則時間戳設(shè)置為LatestTime=-1;maxNuMOffsets表示需要獲取多少個片段文件的基準(zhǔn)偏移量,消費(fèi)者獲取最近的偏移量通常只需要一個偏移盤值,所以第二個參數(shù)值為1。相關(guān)代碼如下:
消費(fèi)者發(fā)送的偏移量請求類型是LIST_OFFSETS,服務(wù)端使用handleOffsetRequest()處理請求,并返回分區(qū)的偏移量集合。存儲消息時除了存儲消息內(nèi)容本身,還會存儲消息對應(yīng)的偏移盞,但Li.stOffsets并不是要返回所有消息的偏移量,而是每個片段文件的基準(zhǔn)偏移量。一個分區(qū)的片段文件數(shù)量并不會很多,相比有多少條消息就返回多少個偏移盤,后者的數(shù)據(jù)盤傳輸更少且更快。
消費(fèi)者讀取分區(qū)的偏移雖有一個限制條件:不能超過服務(wù)端中這個分區(qū)的最高水位(HighWatermark,下文簡稱HW)。服務(wù)端只能保證HW之前的消息已經(jīng)提交,而HW之后的消息沒有提交。fetchOffsets()返回的是按照偏移量降序排列的數(shù)組,如果偏移量比HW大,則會被丟棄。相關(guān)代碼如下:
fetchOffsetsBefore()方法獲取指定時間戳之前的偏移量,最后返回的是片段文件對應(yīng)的基準(zhǔn)偏移量。每個片段文件對應(yīng)一個基準(zhǔn)偏移盤,startindex表示片段文件的索引編號。讀取片段文件跟重置策略有關(guān),如果重置策略是最早(EARLIEST_TImESTAmP),IQiJstart!ndex置為O(即第一個片段文件);如果是最近(LATEST_TImESTAmP),則是最后一個片段文件的索引編號。
offsetTimeArray數(shù)組會按照時間戳的升序,存儲所有片段文件的基準(zhǔn)偏移量和最近修改的時間,這個修改時間就是用來和時間戳參數(shù)比較的依據(jù):要返回指定時間戳之前的偏移盤,應(yīng)該從后面的片段文件開始往前推;如果片段文件的最近修改時間比指定的時間戳小,貝iJ設(shè)置start!ndex為當(dāng)前找到的片段文件。
片段文件的偏移盤和時間戳是成正比增加的。為了簡單起見,假設(shè)時間戳和偏移量是等價的,并假設(shè)我們要獲取時間戳為12之前的3個偏移盤。首先找到小于時間戳的最大值是l1,startindex就是位置ll,然后再往前找3個,假設(shè)allOffsets為[11,8,5],并且hw為10,則hw+:allOffsetsdropWhile(>hw)的結(jié)果為List(l0,8,5)。相關(guān)代碼如下:
注意:dropWhile的含義是將大于hw的刪掉。因?yàn)閍llOffsets是降序排列,如果allOffsets中第一個元素就比hw小,就不會丟棄任何元素,比如10+:List(8,5).dropWhile(>10)=List(10,8,5)。如果allOffsets中最小的都比hw要大,最后就只有hw,比如10+:Li.st(20,17,14).dropWhile(_>10)=List(10)。
客戶端有了分區(qū),而且也知道要從分區(qū)的什么位置開始讀取消息,接下來就是向分區(qū)的主副本節(jié)點(diǎn)發(fā)送拉II~:請求以得到消息。
總結(jié)
以上是生活随笔為你收集整理的3.6.3 获取分区的读取偏移量的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 好记心不如烂笔头,ssh登录 The a
- 下一篇: 神经网络自适应PID控制及其应用