[size=large][b]原創文章,請各位多多指導,有錯誤希望各位能及時告訴我,感激不盡~[/b][/size]
(1) put put = new put(key);首先會構造put物件,以傳入的rowkey,如果未傳入時間戳,那麼就會預設為null,接下來就會判斷是否傳入的控制hbase事務的rowlock,如果傳入的rowlock不為空,那麼就拿到lockid,賦值給當前lockid.
(2) 接下來呼叫put.add(cfbt,columnkey,columnvalue);它會先從familymap中根據family轉化成的byte陣列,拿出list,如果為null,(第一次插入相關cf資料),會新建乙個list,接下來會根據family, qualifier, ts, value這幾個引數,生成keyvalue,keyvalue的結構為
[img]
呼叫的**為
return new keyvalue(this.row, family, qualifier, ts, keyvalue.type.put,value);將生產好的keyvalue,加入cf對於的keyvalue list中,然後將資訊再全部放入familymap中。
(3) 當put中add完要加入的colmn對應的cf,name,value之後,便呼叫table.put方法,這裡呼叫的方法是天蓉師姐改過原始碼之後的putone方法,原來的put方法會將你放入的put加入乙個writebuffer的arraylist中,然後統計當前currentwritebuffersize的大小,如果大於了writebuffersize,並且設定了autoflush,就會呼叫flushcommits方法,這個方法會將你放入writebuffer中的所有put物件,在新版本中是採用的呼叫processbatch方法,processbatch內部有retry機制,如果是retry,就會根據retry次數得到乙個pausetime,然後sleep該pausetime。 接下來,會通過tablename,row,是否啟用快取這3個引數,去定位region:
hregionlocation loc = locateregion(tablename, row.getrow(), true);
(a) 如果tablename == -root- 就會呼叫waitrootregionlocation方法,通過zookeeper得到rootregion的位址。接下來返回乙個new hregionlocation(hregioninfo.root_regioninfo, hsa);
(b) 如果tablename == .meta.,就會呼叫locateregioninmeta方法,先去從快取中拿,如果快取中沒有,會組合metakey,然後去獲得這個row所在的的region在哪個哪個regionserver上。
(c) 如果不是.meta.表也不是-root-表,那麼也會呼叫locateregioninmeta方法,parenttable傳入meta表,依然通過引數形成metakey,
定位到region之後,拿到region對應的serveraddress,然後組裝multiaction,將hserveraddress以及multiaction放入mapactionsbyserver中,接下來遍歷actionsbyserver,建立非同步任務,createcallable,然後將非同步任務submit給threadpool,call方法會呼叫public multiresponse multi(multiaction multi)方法,為這個multiaction中對應的每個action,即每個活動,判斷action型別,delete,get,put,然後針對不同的做不同的處理,這些是多執行緒的 處理,核心會呼叫dominibatchput方法,並在寫入完之後,清空writebuffer
dominibatchput方法:
1. 第一步是盡最大可能獲得鎖,(try to acquire as many locks as we can),保證我們至少有乙個鎖,期間會檢驗checkfamilies,並且如果沒有足夠的rows,會陷入阻塞,numreadytowrite這個屬性就是判斷有多少個rows需要put,知道獲得了next one,然後就是獲得鎖的過程。
2. 第二步,更新時間戳。
3. 第三步,寫入wal日誌,wallog與mysql的binlog類似,作用都是災難恢復,它記錄所有的資料改動。一旦伺服器崩潰,通過重放log,我們可以恢復崩潰之前的資料。這也意味如果寫入wal失敗,整個操作將認為失敗。(紅色字型參考的是網上資料)。
4. 第四步,寫入memstore中,然後返回operationstatuscode.success。
(4) 當dominibatchput呼叫完成之後,會返回addedsize,此時,將memstoresize加上addedsize然後判斷是否滿足條件flush到磁碟,這裡的條件是看size > this.memstoreflushsize;而memstoreflushsize是由regioninfo.gettabledesc().
getmemstoreflushsize()獲得的。預設大小是long default_memstore_flush_size = 1024*1024*64l;64mb。如果滿足了flush條件,就會把writestate.flushrequested標誌位設為true,由單獨的執行緒flush到磁碟上,成為乙個storefile。
但是官方的插入策略第一步是放入本地快取中,即writebuffer中,只有滿足條件了,才會呼叫flushcommits方法,也就是說放入本地快取的時候,並沒有計入wal日誌,如果這個時候機器掛了,那麼資料就丟失了,無法恢復。
其他實現是:
直接呼叫hregionserver的put方法,不將put放入writebuffer中,得到相應的region之後,呼叫region的put方法,這裡的put方法,也是更新時間戳,寫入wal日誌,寫入memstore中。
(5) hregion儲存了table中某乙個region的資料,它儲存了每一行的所有columns,乙個table由乙個或多個hregions組成,乙個hregion中包含了多個hstore,store是包含了部分列的行的集合,同時,他們組成了這些行的所有資料。
乙個hregion是靠表以及key的範圍定義的,它至少包含乙個store,store的數量是可配置的,以便同時進來的資料能存放在同乙個store中,目前,我們近似通過為每個列族建立乙個store
htabledescriptor包含了hregion所在的table的元資料資訊,regionname是乙個hregion的唯一識別符號,(startkey, endkey]定義了這個hregion的key區間。
Fabric 原始碼解析 原始碼目錄解析
這裡對重要的一些目錄進行說明 bccsp 與密碼學 加密 簽名 證書等等 相關的加密服務 將fabric中用到的密碼學相關的函式抽象成了一組介面,便於拓展。bddtests 一種新型的軟體開發模式 行為驅動開 需求 開發 common 一些公共庫 錯誤處理 日誌處理 賬本儲存 策略以及各種工具等等 ...
Spring原始碼解析之 Aop原始碼解析(2)
spring aop 更多的是oop開發模式的乙個補充,幫助oop以更好的方式來解決對於需要解決業務功能模組之上統一管理 的功能 以一副圖來做為aop功能的說明更直觀些。對於類似系統的安全檢查,系統日誌,事務管理等相關功能,物件導向的開發方法並沒有更好的解決方法 aop引入了一些概念。更多的是spr...
Integer原始碼解析
public class test else integer i3 200 integer i4 200 if i3 i4 else 結果為 原因integer 類會快取 128 到 127 之間的整數 但是如果new interger的話就是不同的物件了 源 分析 如果是在 128到正的127之間...