您好,登錄后才能下訂單哦!
這篇文章主要介紹“Hbase WAL線程模型是怎樣的”,在日常操作中,相信很多人在Hbase WAL線程模型是怎樣的問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”Hbase WAL線程模型是怎樣的”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!
Hbase的WAL機制是保證hbase使用lsm樹存儲模型把隨機寫轉化成順序寫,并從內存read數據,從而提高大規模讀寫效率的關鍵一環。wal的多生產者單消費者的線程模型讓wal的寫入變得安全而高效。
wal為了高效安全有序的寫入,筆者認為最關鍵的兩個機制是wal中使用的線程模型和多生產者單消費者模型。
其線程模型主要實現實在FSHLog中,FSHLog是WAL接口的實現類,實現了最關鍵的apend()和sync()方法,其模型如圖所示:
這個圖主要描述了HRegion中調用append和sync后,hbase的wal線程流轉模型。最左邊是有多個client提交到HRegion的append和sync操作。當調用append后WALEdit和WALKey會被封裝成FSWALEntry類進而再封裝成RinbBufferTruck類放入一個線程安全的Buffer(LMAX Disruptor RingBuffer)中。當調用sync后會生成一個SyncFuture進而封裝成RinbBufferTruck類同樣放入這個Buffer中,然后工作線程此時會被阻塞等待被notify()喚醒。在最右邊會有一個且只有一個線程專門去處理這些RinbBufferTruck,如果是FSWALEntry則寫入hadoop sequence文件。因為文件緩存的存在,這時候很可能client數據并沒有落盤。所以進一步如果是SyncFuture會被批量的放到一個線程池中,異步的批量去刷盤,刷盤成功后喚醒工作線程完成wal。
下面將從源碼角度分析其中具體實現過程和細節。
工作線程中當HRegion準備好一個行事務“寫”操作的,WALEdit,WALKey后就會調用FSHLog的append方法:
如果client設置的持久化等級是USER_DEFAULT,SYNC_WAL或FSYNC_WAL,那么工作線程的HRegion還將調用FSHLog的sync()方法:
追蹤代碼可以分析出Sync()方法會往ringbuffer中放入一個SyncFuture對象,并阻塞等待完成(喚醒)。
像模型圖中所展示的多個工作線程封裝后拿到由ringbuffer生成的sequence后作為生產者放入ringbuffer中。在FSHLog中有一個私有內部類RingBufferEventHandler類實現了LAMX Disruptor的EventHandler接口,也即是實現了OnEvent方法的ringbuffer的消費者。Disruptor通過 java.util.concurrent.ExecutorService 提供的線程來觸發 Consumer 的事件處理,可以看到hbase的wal中只啟了一個線程,從源碼注釋中也可以看到RingBufferEventHandler在運行中只有單個線程。由于消費者是按照sequence的順序刷數據,這樣就能保證WAL日志并發寫入時只有一個線程在真正的寫入日志文件的可感知的全局唯一順序。
這部分源碼可以看到RingBufferTruck類的結構,從注釋可以看到選擇SyncFuture和FSWALEntry一個放入ringbuffer中。
這部分源碼可以看到append的最終歸屬就是根據sequence有序的把FSWALEntry實例entry寫入HadoopSequence文件。這里有序的原因是多工作線程寫之前通過ringbuffer線程安全的CAS得到一個遞增的sequence,ringbuffer會根據sequence取出FSWALEntry并落盤。這樣做其實只有在得到遞增的sequence的時候需要保證線程安全,而java的CAS通過輪詢并不用加鎖,所以效率很高。
SyncRunner是一個線程,wal實際有一個SyncRunner的線程組,專門負責之前append到文件緩存的刷盤工作。
SyncRunner的線程方法(run())負責具體的刷寫文件緩存到磁盤的工作。首先去之前提交的synceFutues中拿到其中sequence最大的SyncFuture實例,并拿到它對應ringbuffer的sequence。再去比對當前最大的sequence,如果發現比當前最大的sequence則去調用releaseSyncFuture()方法釋放synceFuture,實際就是notify通知正被阻塞的sync操作,讓工作線程可以繼續往下繼續。前面解釋了sequence是根據提交順序過來的,并且解釋了append到文件緩存的時候也是全局有序的,所以這里取最大的去刷盤,只要最大sequence已經刷盤,那么比這個sequence的也就已經刷盤成功。最后調用當前HadoopSequence文件writer刷盤,并notify對應的syncFuture。這樣整個wal寫入也完成了。
到此,關于“Hbase WAL線程模型是怎樣的”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。