SpatialHadoop中空間索引系列之(一)空間索引構建
SptialHadoop是基於hadoop擴充套件的用於處理空間大資料的與計算平臺。最近的工作研究一下在大資料環境下空間索引的構建方法。今天就討論下在spatialhadoop當中,空間索引是如何構建的。文章地址:Spatialhadoop
1、概述
為了彌補在hadoop中建立索引結構的不足,我們採用了兩層索引的方法,包括全域性索引和區域性索引。全域性索引儲存在主節點上,主節點通過一個分割槽集合來對儲存在子節點上的資料進行切分,每一個分割槽都有一個區域性索引用來組織自己的資料。這樣的組織方式主要解決了兩個問題:1)它適合mapreduce程式設計正規化,本地索引能夠通過一個mapreduce工作來並行處理;2)本地索引的大小允許每一個被批量載入到記憶體中和通過擴充套件的方式寫入到一個檔案中。使用者可以通過下面的spatialhadoop shell命令來對一個輸入檔案 src file 建立不同型別的索引,最終生成一個輸出檔案 dst file。這裡的索引型別包括grid,rtree,和 r+tree:index <src file> <dst file> sindex:<index-type>。
2、索引構建
忽略底層空間索引的構建,在spatialhadoop中構建索引可以分為三個階段:分割槽、區域性索引和全域性索引。不同型別的空間索引在細節上還有所差異。
第一階段:分割槽:在這個階段,系統將輸入的檔案從空間上分成n個區,在分割槽的過程中需要滿足三個目標:(1)合適的塊:每一個分割槽應該適合HDFS塊的大小 64MB;(2)空間位置:相鄰的要素被分在同一個區域中;(3)負載均衡:所有的分割槽應該大小大致相同。我們通過以下三個步驟來實現這三個目標:
步驟1:計算分割槽的個數。不考慮空間索引的型別,我們計算以下分割槽的個數 n,計算公式:n=S(1+a)/B,其中S是指資料檔案的大小,B是指HDFS中塊的大小(64MB),a是指額外開銷率,預設值是0.2,主要是指重複的記錄和儲存區域性索引的額外開銷。總之,該方程是的平均分割槽大小比B小。
步驟2:計算分割槽邊界。在這個階段,每一個單獨的分割槽定義一個矩形,我們確定的空間區域能夠覆蓋該分割槽。為了適應分佈不均甚至成偏態分佈的資料,根據底層索引構建的不同,分割槽邊界的計算方法也不相同。該部分輸出的結果是n個分割槽的矩形的集合,這個集合覆蓋了整個空間區域。
步驟3:物理分割槽。在步驟2中計算了分割槽邊界,我們開始通過一個mapreduce工作來從物理上對輸入的檔案進行分割槽。這裡的問題主要解決怎麼處理具有空間範圍的要素,如面,這些要素往往會覆蓋多個分割槽。一些索引方法會給最合適的分割槽分配一條記錄,同時,所有覆蓋的分割槽會複製這條記錄。重複的記錄會在後期查詢過程進行處理,以此來保證結果的準確性。最後,對每一條記錄r分配到對應的分割槽P中,map功能寫入一對中間鍵<p,r>。這些中間鍵通過p進行分組,然後進行區域性索引階段的reducer工作。
2)第二階段:構建區域性索引。該部分的目的是針對每一個物理分割槽的資料內容構建所需的區域性索引(如Grid或者R-tree)。該部分通過reduce功能將記錄分配到每一個分割槽,在區域性索引檔案中儲存所有記錄。每一個分割槽區域性索引必須滿足一個HDFS塊的大小。因為(1)這樣允許所有的空間操作可以通過mapreduce正規化來獲取區域性索引,在區域性索引中每一個索引都可以通過一個map任務來完成。(2)能夠確保當hadoop重置所有塊的時候,區域性索引可以被作為一個塊。在第一個階段中,分割槽已經被實現了,並且保證了每一個分割槽適合HDFS塊的大小。一旦一個分割槽太大,我們按照64MB將其分為更小的塊,這樣能夠作為一個單獨的塊寫入。為了確保區域性索引連線後能夠與塊保持一致,每一個檔案將會附加虛擬資料使其大小正好為64MB。
3)第三階段:構建全域性索引。這個階段的目的是對所有的分割槽來構建全域性索引。一旦mapreduce分割槽工作完成,我們將開始一個HDFS concat 命令,通過該命令可以連線所有的區域性索引檔案生成一個索引檔案,這個就是最終的索引檔案。然後,主節點通過記憶體計算來構建全域性索引,該索引是將所有檔案塊的矩形邊界作為索引鍵。全域性索引通過批量載入來構建,該過程在主節點內容中一直進行。一旦主節點宕機或者重啟,只有在重新要求的情況下,才會重新構建全域性索引。下一節,將從程式碼上來解析下內部的實現。