HDFS - 雙緩衝機制如何保證對元數據的高併發請求

咱們在HDFS - 什麼是元數據中提到了,元數據會存在與內存和磁盤中,內存爲了提升響應速度,磁盤是爲了持久化保證數據的安全,可是寫磁盤的速度相對於內存是慢了幾個數量級的,若是NameNode每次都要把數據落到磁盤上那是沒辦法處理那麼多客戶端的請求的,因此NameNode用了雙緩衝機制以及分段加鎖。
所謂雙緩衝就是定義了兩個內存塊,一個是bufCurrent,用於當前寫入元數據的,一個是bufReady,用於寫入磁盤的,兩個內存塊都是512k。
image.pngsegmentfault

第一把鎖

線程1會先獲取鎖,而後會看看當前有沒有在交換緩存(這裏經過isAutoSyncScheduled來判斷),若是沒有,就去獲取一個全局惟一的事務ID,這個ID是遞增的。拿到事務ID後,就開始寫入bufCurrent,寫完後判斷bufCurrent是否超過了512k,若是沒有,線程1的流程就結束了(後面結束的背景是白色的)。
因爲線程2,3,4在線程1沒釋放鎖的時候,都會一直等到,若是線程2,3,4拿到了鎖,也會繼續上面線程1的操做。
因爲這個鎖裏的操做都是基於內存的,因此速度就會很是塊。
image.png
咱們假設線程4寫完後,發現bufCurrent內存超過了512k,此時就會把isAutoSyncScheduled設置爲true,說明要開始交換內存了,其餘線程就不能作以上的操做了。這裏的bufCurrent就是線程1,2,3,4寫入的數據。
image.png
這個時候,線程5進來並拿到鎖,咱們給拿鎖的進程顏色標深一點,發現要開始交換內存了,因而他就是wait狀態。
image.png緩存

第二把鎖

咱們假設接下來獲取到鎖的是線程4。他發現此時並無其餘線程交換內存(這裏經過isSyncRunning判斷),因而他就開始bufCurrent和bufReady的內存進行了交換,交換後,bufCurrent的數據就清空了。在這裏還會把isSyncRunning設置true,而後isAutoSyncScheduled設置爲false,最後就喚醒wait的線程。
image.png
線程4喚醒其餘線程後,他就開始把bufReady的數據寫入磁盤,這個操做是很耗時的,因此並無加鎖,可是他是運行狀態,因此下圖標記爲綠色。
這裏的bufReady就是線程1,2,3,4寫入的數據。
此時是線程5獲取了鎖,發現內存交換完畢了,開始往bufCurrent寫數據。
image.png
此後線程6拿到了鎖,此時bufCurrent又超過了512k了,就會把isAutoSyncScheduled設置爲true,說明開始交換內存,其餘線程就不能往bufCurrent寫入數據了。可是他發現isSyncRunning爲true,說明有其餘線程在寫磁盤了,因此他就開始wait。
image.png安全

第三把鎖

此時線程4寫完了磁盤,而後他獲取到鎖,就會把synctxid更改成本身的事務ID,而後賦值isSyncRunning爲false,說明磁盤寫入完成了。最後喚醒其餘wait的線程。
image.png
此時線程6從新拿到了鎖,他發現isSyncRunning爲false了,那就是說明其餘線程已經把本身的內容刷入磁盤了,因此線程6開始了上面線程4的操做,交換內存,寫入磁盤。性能

總結

第一把鎖,主要是判斷isAutoSyncScheduled以及對isAutoSyncScheduled的賦值,這個主要是說明bufCurrent和bufReady開始交換內存了。
第二把鎖,主要是判斷isSyncRunning以及對isSyncRunning和isAutoSyncScheduled的賦值。isSyncRunning是用來判斷是否在寫磁盤,isAutoSyncScheduled用來判斷是否在交換內存,若是在交換,就不能寫入bufCurrent,若是在寫磁盤,那就不能寫磁盤。
第三把鎖,賦值isSyncRunning,說明磁盤寫入完成。
這期間最耗時的操做並無加鎖,其餘內存操做的加鎖,可是速度比較快,採用在這種分段加鎖的方式和雙緩衝機制,大大提升了性能。spa

相關文章
相關標籤/搜索