設計key-value數據的存儲查詢模塊

openkk 12年前發布 | 22K 次閱讀 K/V存儲 NoSQL數據庫

(百度2011)單機存儲100億大數據量的key-value數據,要求能夠支持插入和查詢操作,單條數據長度不定,平均約1024字節,假設可用內存10G,磁盤空間不限,請設計一個存儲查詢模塊,支持按照key來獲取對應的value,設計目標以查詢性能為先,盡量節約資源,查詢可以理解為網民的檢索行為。

1)        說明該設計方案和主要思路,以及優缺點

2)        請詳細說明該設計思路下查詢和插入的操作流程

3)        如果增加更新操作,請評估前面的設計方案是否可行,需要做怎樣的修改,不可行則指明主要問題點。

分析:

1)數據量大小為:

data_size=100億*1024Byte=10^10*10^3Byte=10^13Byte=10^4G

假設每個key的長度不超過128Byte。

使用2種文件存儲數據:索引文件和數據文件。

索引文件采用類似B+樹的結構化存儲,一條數據對應一條記錄,一條記錄包括:數據的key、存儲該數據的數據文件ID以及數據文件偏移量,占用空間:

record_size=key_size+data_file_ID_size+offset_size=128+4+8=140Byte。

B+樹共有3層,內節點只存儲最多M個關鍵字key和相應的M棵子樹的位置,第i個關鍵字是第i棵子樹中的最小關鍵字,葉節點存儲最多M個key-value數據。每個節點最多包含M個key,M^3=100億=10^10,M=2200。

內節點有2種形式:一是存儲在索引文件中,包含的域有:關鍵字key,相應的子節點的索引文件ID和文件偏移量,占用空間:

inner_node_size_in_file=(key_size+index_file_ID_size+file_offset_size)*M=(128+4+8)*2200

=30800Byte=300K。

二是存儲在內存中,除了上面提到的域,還包括指向子節點的指針域,占用空間:

Inner_node_size_in_memory*M=(inner_node_size_in_file+pointer_size)*M

=144*2200Byte=316800Byte=310K。

第一層和第二層占用空間:

(M+1)*inner_node_size_in_momery=666M,

可以全部存儲在內存中。

         內節點按順序寫入索引文件,采用惰性空間分配策略,即使內節點沒有滿,也分配最大空間inner_node_size_in_file。這樣保證內節點可以在原地更新,保持有序狀態。假設索引文件最大index_file_size=2G,一個索引文件可以容納內節點數目:

Inner_count_in_file=index_file_size/ inner_node_size_in_momery

=6990>inner_node_count=M+1

一個索引文件足夠了。

葉節點包含key-value數據,占用空間:

Leaf_size_in_memory=M*data_size=2200*1024=2200K

葉節點以在文件尾追加方式寫入數據文件,不需要保持有序,因為B+樹的第二層內節點記錄了所有葉節點的數據文件ID和文件偏移量。假設一個數據文件大小是data_file_size=2G,數據文件數目為

data_file_count=data_size/data_file_size=5000

優點:

1)      B+樹采用3層,第1層和第2層是內節點,是索引節點,存儲在索引文件,可以全部存儲在內存,第3層是葉節點,存儲在數據文件,部分緩存在內存。插入和查找一條數據,最多需要訪問硬盤一次。

2)      索引文件采用惰性空間分配策略保證內節點可以在原地更新,保持有序狀態。

3)      數據文件的更新一直是在尾部追加,不需要移動數據。

缺點:

1)      索引文件浪費了部分空間。

第二問:

查找:在根節點二叉查找關鍵字,下降到第二層某一個節點,二叉查找關鍵字,下降到第三層某一個關鍵字,若該條數據不在內存中,從數據文件讀入,若在內存中,直接返回數據。

插入:與查找類似,找到該條數據應該在的位置,添加到最后一個數據文件的末尾。

第三問:若增加更新操作,前面的方案可行,需要做下列修改:

將數據按照大小分類存儲到不同的數據文件中。假設數據大小平均分布在512Byte到1536Byte之間,步長平均為128Byte,數據文件分類為存儲512Byte的,存儲512+128Byte的,存儲512+128*2Byte的,……,類似內存池的做法。更新數據時,將數據寫到能容納該條數據的最小分類的數據文件,將該位置記為空閑,加到該數據文件的空閑位置鏈表。鏈表的指針可以用空閑位置的前4個字節表示,文件的最開始4個字節表示鏈表頭部指針。當然,這樣會浪費部分空間。可以監控每種文件的空間使用情況,做出調整。

 本文由用戶 openkk 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!