1. 程式人生 > >非結構化資料的儲存與查詢

非結構化資料的儲存與查詢

 當今資訊化時代充斥著大量的資料。海量資料儲存是一個必然的趨勢。然而資料如何的儲存和查詢,尤其是當今非結構化資料的快速增長,對其資料的儲存,處理,查詢。使得如今的 關係資料庫儲存帶來了巨大的挑戰。分佈儲存技術是雲端計算的基礎,主要研究如何儲存、組織和管理資料中心上的大規模海量資料.由於面臨的資料規模和使用者規模更加龐大,在可擴充套件性、容錯性以及成本控制方面面臨著更加嚴峻的挑戰[1]。

        對於大量的半結構化資料(semi-structure data)和非結構化資料,對其儲存和併發計算以及擴充套件能力而設計出了NoSQL,像有googleBigtableAmaze Dynamo,以及

ApacheHbaseNoSQL支援強大的水平擴充套件能力和高效能,與關係資料庫不同的是,NoSQL可以採用鬆弛一致性(relax consistant),但是提供最終一致性保證資料的讀的不一致。像在Dynamo中為了提供高的寫的能力(購物時不會因為併發而不會新增購物車不能成功,而影響使用者體驗),不得不採取最終一致性。根據CAP原理,一致性、高可用性、分割槽容忍性(Partition-tolerance)三者中最多擇其二,舍其一。在Dynamo犧牲了一致性,但是提供高的可用性[6]。另外Dynamo採用非集中化管理,使得每個節點都是同等地位,充分利用分散式雜湊表(DHT的一種實現即一致性雜湊,使得Dynamo提供強大的可擴充套件性。
Hbase可以說提供強的一致性,但是犧牲掉了一定的高可用性,比如存在單點故障,在當一個Regionserver出問題或失去聯絡時,需要master來重新部署原Regionserver下面的是Region到別的空閒的伺服器下。這段時間無法與下面的Region聯絡。HbaseApache的頂級專案Hadoop的一個組成部分,hadoop是一種分散式系統基礎架構。它可以充分利用叢集的威力高速運算和儲存。下面著重介紹Hbase。

一、非結構化資料儲存結構

        HbaseApache的頂級子專案,它的理念來自於GoogleBigtable。它是分佈的、面向列的、多維的資料庫系統,它提供高的容錯性和可擴充套件性,它是建立

HDFSHadoop分散式檔案系統)之上。Hbase的表的每一行有行鍵(row key)和任意多的列(column)組成,其中多個列可以組成列族(column family)。每個資料單元(cell)可以擁有資料的多個版本(version),這個是使用時間戳來區分。所以Hbase是擁有map:(行鍵,列族:列,時間戳)對應一個值[2][7]

        Hbase是應用在分散式系統之中,他將大量的行分成行區域(Region),將化分後的區域分佈到叢集中去。HbaseHDFS同樣是使用master-slave結構,在Hbaseslave對應是Regionserver,負責管理master分下來的Rregion。同時master還負責負載平衡以及當Region出現錯誤時,master會收到Regionserver的請求訊息,會重新分配到新的空閒的節點(這涉及到HLog)。

正如上所說,Hbase是面向列的儲存,它在實際的物理儲存器中是以列族的儲存,所以在列族相同的會在儲存在一起。在與面向行的關係資料庫比較,這會節省了大量為空的屬性。Hbase也是一種NoSQL,它不像關係資料庫那樣提供結構化查詢語句來訪問其中的資料。NoSQL是一種模式自由(schema-free)的資料庫,良好是設計會提升資料結構而不存在表的重寫[3]

Hbase的容錯性不得不提到HDFSHDFSHadoop 分散式檔案系統,它可以部署在廉價的機器上,提高系統的容錯性和高的吞吐量。HDFS分為一個Namenode和多個DatanodeNamenode管理檔案系統的名字空間,它維護著檔案系統樹以及整個樹內所有的檔案和目錄。Datanode儲存著資料塊,負責刪除新增等操作。Hbase的檔案被分為固定大小的塊(預設的為64M),塊伺服器是儲存塊和對指定塊的讀寫操作。在分散式的叢集中,機器故障乃是常態,為了安全問題,所以不斷的檢測機器的狀況和資料的備份時必須的。HDFS的副本一般的情況下分為3份,一份是同個節點中,第二份放在不在機架上的另一個節點,最後一份是放在第二份相同機架的不同節點中[4]Master儲存著檔案系統元資料(metadata),主要分為3種元資料:檔案和塊的名字空間、檔案到塊的對映和塊副本的位置。塊伺服器儲存著資料,所以master必要和塊伺服器保持者聯絡。Master定期傳送心跳(heartbeat)與塊伺服器瞭解塊伺服器的狀況。客戶讀寫資料是都首先和master先取得聯絡然後再與塊伺服器完成讀寫操作。

在一致性上,HDFS 是一個鬆散的一致性檢查的模型。他主要是為了追加(append)操作而不是覆蓋重寫(overwrite)操作。因為覆蓋重寫的話可能在一次讀的操作會讀到與其他副本不一致的資料,而在追加操作,其中一個副本的不一致也不會導致客戶端讀到不一致的資料。同時HDFS在追加操作時採用租用(Lease)機制,即將塊的寫操作授權給主塊伺服器(primary chunk server),另外的副本稱為次塊伺服器(secondary chunk server)。當多個客戶端的併發寫操作時,主塊伺服器快取其寫的順序,之後聯絡次伺服器進行追加操作。從這裡可以看出,在HDFS的基礎之上提供版本一致性。而不同Dynamo採用向量時鐘即(節點,計數器)(node,counter)列表來鍾捕捉同一不同版本的物件是否有因果關係。當客戶端更新一個物件,它必須指定它正要更新哪個版本,當存在因果關係,直接覆蓋之前的版本。若是兩個獨立的版本,更新其向量時鐘,使得存在多個版本。同事Dynamo採用了NRW機制(N: 複製的節點數量,R: 成功讀操作的最小節點數,W: 成功寫操作的最小節點數),當R+W>N時可以說明至少有一個版本是最新的版本,這樣在資料的讀操作就可以保證資料的一致性。[6]當然在這裡也體現出了Dynamo的高可用行,比如設定W=1,即表明只要正確讀入一個節點即可,不須保證寫入的值全部傳給副本。

二、非結構化資料的讀寫操作

對Hbase中資料的讀寫首先是根據行鍵值或行鍵值域(row key range)來檢索,行鍵值是按照字典序排列的,針對同時訪問的資料設計好相似的行鍵值會相應地減少I/O操作。上面提過,由於行區域到達一定大小時會分解並分佈到叢集中去,在Hbase中使用B+樹來儲存某個區域的位置資訊。在樹頂是root表,其儲存META表的Region資訊,並且root表只有一個,META表中儲存著各個被劃分的區域的資訊,所以通過行健訪問時首先訪問root再一次訪問META表。由此客戶端訪問資料需要經過多次的網路互動,所以客戶端可以使用快取來緩解。客戶端是採用RPC機制與伺服器端即masterRegionServer進行通訊。另外Hbase還採用緩衝池來保持每次的連線,保證通訊不必產生重新連線的時間開銷。

客戶端要求更新資料的時候,為了容錯性,資料首先是HLog中,當HLog寫成功是,之後資料是寫入到menstore,當資料達到一定的大小時,資料會將記憶體重新整理(flush)到本地磁碟中,形成儲存檔案(storefile),此時檔案只是可讀的。當儲存檔案的大小到達一定的大小,會進行合併(compact),這個合併將行鍵值相同的合併到一起形成一個比較大的儲存檔案,其過程是對版本的合併與刪除的過程,所以從這個角度來看,Hbase是一個追加的過程。當然儲存檔案的大小到達一定的閥值時,會分裂(split)成兩個儲存檔案[2]。儲存檔案在組織成HFile以塊的形式存在底層的HDFS上。

在[5]中介紹Hbase作為HDFS上層的來評估在大規模資料中隨機讀和隨機寫的效能,文中是利用MySQL作為HDFS上層來儲存與此作對比。結果顯示在多使用者多併發讀和寫時Hbase--HDFS組合負載表現更加的理想。

三、資料的搜尋與查詢方法探索

     如今資料的以PB級別的,海量資料不斷增長,怎樣快速的儲存以及搜尋和查詢指定的檔案所需的時間問題。在關係資料庫中,利用索引減少I/O次數來減少讀指定的資料的時間,在Hbase中同樣可以使用索引。

    Hbase一般設定行鍵作為主鍵來查詢資料,而行鍵是按照字典序排的,同時Hbase支援利用字首來,所以合理利用行鍵會提高查詢效率的。在[2]中提到二級索引(secondary index)解決不只是利用行鍵最為自己的主鍵,比如購物網站使用者Hbase表的行鍵是使用者ID,但是網站為了統計某個時間段的交易記錄,在原來表的表上進行掃描可能會掃描整個表。為此我們可以設計另一張表,而這張表的主見是時間+使用者,在Hbase進行按字首掃描時,所需要的資料可能是放在同一塊中,減少了I/O次數。

    在[9]中是利用Hbase來儲存來處理資源描述框架(RDF)的WEB資料,針對PDF的三元(triple)結構(S,P,O),其中該文章中S代表行鍵,P代表列,O代表單元(cell)的值。資料檢索預設是按照行鍵值進行的,文章中建立了6個索引表( PSO, POS, SPO, SOP, OPS and OSP),這包含了所有行鍵與列的組合。當然這樣做,會產生了資料的冗餘,因為多建了5個索引。但是多出的索引滿足多種查詢。這也是二級索引的應用。

    在[11]中利用Hadoop架構對半結構化資料和非結構化資料的儲存、索引構建、資料查詢的整體設計。

          

整體分為兩個過程,第一步原始需要儲存的資料經過Uploader形成Hbase面向列結構的表,下一步通過indexer形成對資料整理後的索引。第一步與第二步中中涉及到MapReduce操作,MapReducegoogle提出的一種程式設計模型,是來處理大規模資料集的並行運算模型,它分為兩個部分:map操作和reduce操作。Map操作將資料進行處理形成一箇中間資料,且資料是(key,value)形式,reduce操作將map操作的結果作為輸入數[8],即:

                    map (k1,v1) ——————> list(k2,v2)

                    reduce (k2,list(v2)) ————>list(v2)

其中在第一步中的MapReduce操作根據索引規則(index rule)進行操作(索引規則是利用半結構化資料或結構化資料的某種邊界特徵來分解原資料集)。客戶端API可以通過index table進行對特定值或某個範圍值進行檢索。再從內容表(content table)中尋找指定的值。

   在Hbase中為客戶端提供一系列的API來訪問資料,get(byte[] row)來獲取指定的行對應的資料,然後實際上是客戶端在指定的Region中收集到的行後在客戶端來進一步執行。另外利用mapreduce雖然提供了強大的計算能力,但是它並不是線上業務的很好的方案。在[10]中提到一種協處理(Coprocessor)框架,它允許HBase 管理員在Region server中載入定製的程式碼,使的可以實現一些集合函式像行計數器、求最大值、最小值等。Coprocessor的機制可以理解為,Regionserver端添加了一些回撥函式。客戶端可以在多個節點呼叫並且可以並行執行。這樣使得客戶端不像以前那樣請求到的資料在客戶端進一步執行,而是請求在各個Region中併發執行後的結果直接返回給客戶端,大大提高了效率。