磁盘存储的性能问题
磁盤存儲的性能優化
我們現在大部分企業仍然用的是機械結構的磁盤,如果把消息以隨機的方式寫入到磁盤,那么磁盤首先要做的就是尋址,也就是定位到數據所在的物理地址,在磁盤上就要找到對應的柱面、磁頭以及對應的扇區;這個過程相對內存來說會消耗大量時間,為了規避隨機讀寫帶來的時間消耗,kafka采用順序寫的方式存儲數據。即使是這樣,但是頻繁的I/O操作仍然會造成磁盤的性能瓶頸
零拷貝
消息從發送到落地保存,broker維護的消息日志本身就是文件目錄,每個文件都是二進制保存,生產者和消費者使用相同的格式來處理。在消費者獲取消息時,服務器先從硬盤讀取數據到內存,然后把內存中的數據原封不動的通過socket發送給消費者。雖然這個操作描述起來很簡單,但實際上經歷了很多步驟。
操作系統將數據從磁盤讀入到內核空間的頁緩存
應用程序將數據從內核空間讀入到用戶空間緩存中
? 應用程序將數據寫回到內核空間到socket緩存中
操作系統將數據從socket緩沖區復制到網卡緩沖區,以便將數據經網絡發出
通過“零拷貝”技術,可以去掉這些沒必要的數據復制操作,同時也會減少上下文切換次數。現代的unix操作系統提供一個優化的代碼路徑,用于將數據從頁緩存傳輸到socket;在Linux中,是通過sendfile系統調用來完成的。Java提供了訪問這個系統調用的方法:FileChannel.transferTo API
使用sendfile,只需要一次拷貝就行,允許操作系統將數據直接從頁緩存發送到網絡上。所以在這個優化的路徑中,只有最后一步將數據拷貝到網卡緩存中是需要的
頁緩存
頁緩存是操作系統實現的一種主要的磁盤緩存,但凡設計到緩存的,基本都是為了提升i/o性能,所以頁緩存是用來減少磁盤I/O操作的。
磁盤高速緩存有兩個重要因素:
第一,訪問磁盤的速度要遠低于訪問內存的速度,若從處理器L1和L2高速緩存訪問則速度更快。
第二,數據一旦被訪問,就很有可能短時間內再次訪問。正是由于基于訪問內存比磁盤快的多,所以磁盤的內存緩存將給系統存儲性能帶來質的飛越。
當 一 個進程準備讀取磁盤上的文件內容時, 操作系統會先查看待讀取的數據所在的頁(page)是否在頁緩存(pagecache)中,如果存在(命中)則直接返回數據, 從而避免了對物理磁盤的I/0操作;如果沒有命中, 則操作系統會向磁盤發起讀取請求并將讀取的數據頁存入頁緩存, 之后再將數據返回給進程。同樣,如果 一 個進程需要將數據寫入磁盤, 那么操作系統也會檢測數據對應的頁是否在頁緩存中,如果不存在, 則會先在頁緩存中添加相應的頁, 最后將數據寫入對應的頁。 被修改過后的頁也就變成了臟頁, 操作系統會在合適的時間把臟頁中的數據寫入磁盤, 以保持數據的 一 致性
Kafka中大量使用了頁緩存, 這是Kafka實現高吞吐的重要因素之 一 。 雖然消息都是先被寫入頁緩存,然后由操作系統負責具體的刷盤任務的, 但在Kafka中同樣提供了同步刷盤及間斷性強制刷盤(fsync),可以通過 log.flush.interval.messages 和 log.flush.interval.ms 參數來控制。
同步刷盤能夠保證消息的可靠性,避免因為宕機導致頁緩存數據還未完成同步時造成的數據丟失。但是實際使用上,我們沒必要去考慮這樣的因素以及這種問題帶來的損失,消息可靠性可以由多副本來解決,同步刷盤會帶來性能的影響。 刷盤的操作由操作系統去完成即可
?
總結
- 上一篇: 副本的leader选举
- 下一篇: Kafka消息的可靠性