1. 程式人生 > >人工智慧的底層構架,認識HBase資料模型

人工智慧的底層構架,認識HBase資料模型

人工智慧作為當前最熱門的技術,其根本上離不開大資料的支援。如果把人工智慧比喻成一個神經網路,那麼資料則是在這個神經網路中用來傳遞資訊的化學物質,沒有資訊傳遞的神經網路顯然不名一文,因此大資料扮演著人工智慧基石的角色。

Hadoop生態系統的HDFS和MapReduce分別為大資料提供了儲存和分析處理能力,但是對線上實時的資料存取則無能為力,而HBase作為Apache頂級專案,彌補了Hadoop的這一缺陷,滿足了線上實時系統低延時的需求。目前HBase在各大網際網路公司幾乎都有應用,前景廣闊。

HBase的資料模型與傳統資料庫相比更加靈活,使用之前無須預先定義一個所謂的表模式(Schema),同一個表中不同行資料可以包含不同的列,而且HBase對列的數量並沒有限制。

當然如果一行包括太多的列,就會對效能產生負面影響。HBase很適合儲存不確定列、不確定大小的半結構化資料。

邏輯模型

​HBase是一個鍵值(key-value)型資料庫。HBase資料行可以類比成一個多重對映(map),通過多重的鍵(key)一層層遞進可以定位一個值(value)。因為HBase資料行列值可以是空白的(這些空白列是不佔用儲存空間的),所以HBase儲存的資料是稀疏的。

 

下面解釋一下與HBase邏輯模型相關的名詞。

(1)表(table):類似於關係型資料庫中的表,即資料行的集合。表名用字串表示,一個表可以包含一個或者多個分割槽(region)。

(2)行鍵(row key):用來標識表中唯一的一行資料,以位元組陣列形式儲存,類似於關係型資料庫中表的主鍵(不同的是從底層儲存來說,行鍵其實並不能唯一標識一行資料,因為HBase資料行可以有多個版本。

但是,一般在不指定版本或者資料時間戳的情況下,用行鍵可以獲取到當前最新生效的這行資料,因此從使用者檢視來說,預設情況下行鍵能夠標識唯一一行資料),同時行鍵也是HBase表中最直接最高效的索引,表中資料按行鍵的字典序排序。

(3)列族(column family):HBase是一個列式儲存資料庫,所謂列式就是根據列族儲存,每個列族一個儲存倉庫(Store),每個Store有多個儲存檔案(StoreFile)用來儲存實際資料。

(4)列限定符(column qualifier):每個列族可以有任意個列限定符用來標識不同的列,這個列也類似於關係型資料庫表的一列,與關係型資料庫不同的是列無須在表建立時指定,可以在需要使用時動態加入。

(5)單元格(cell):單元格由行鍵、列族、列限定符、時間戳、型別(Put、Delete等用來標識資料是有效還是刪除狀態)唯一決定,是HBase資料的儲存單元,以位元組碼的形式儲存。

(6)版本(version):HBase資料寫入後是不會被修改的,資料的Put等操作在寫入預寫入日誌(Write-Ahead-Log,WAL)(類似於Oracle Redo Log)後,會先寫入記憶體倉庫(MemStore),同時在記憶體中按行鍵排序,等到合適的時候會將MemStore中的資料重新整理到磁碟的StoreFile檔案。

因為資料已經排序,所以只需順序寫入磁碟,這樣的順序寫入對磁碟來說效率很高。由於資料不會被修改,因此帶來的問題就是資料會有多個版本,這些資料都會有一個時間戳用來標識資料的寫入時間。

(7)分割槽(region):當傳統資料庫表的資料量過大時,我們通常會考慮對錶做分庫分表。例如,淘寶的訂單系統可以按買家ID與按賣家ID分別分庫分表。同樣HBase中分割槽也是一個類似的概念,分割槽是叢集中高可用、動態擴充套件、負載均衡的最小單元,一個表可以分為任意個分割槽並且均衡分佈在叢集中的每臺機器上,分割槽按行鍵分片,可以在建立表的時候預先分片,也可以在之後需要的時候呼叫HBase shell命令列或者API動態分片。

接下來以使用者行為管理系統為例,假設現在需要用HBase來儲存電商系統的使用者行為資料,表s_behavior用來儲存這些行為資料,兩個列族pc和ph分別儲存電腦端與手機端的行為資料,列v用來儲存使用者瀏覽記錄,列o用來儲存使用者的下單記錄,圖1-1描述了這個表的HBase邏輯檢視。

圖1-1 HBase邏輯檢視

HBase按行鍵的字典序儲存資料行,其資料儲存層級可以用如下的一個Java中的Map結構類比:

Map<RowKey,Map<Column Family,Map<Column Qualifier,Map<Timestamp,Value>>>>

如下程式碼可以用來定位到某個鍵值對(或者說單元格):

map.get("12345_1516592489001_1").get("pc").get("v").get("1516592489001");

程式碼清單3-1的JSON字元串同樣近似地描述了這個多維的Map。

程式碼清單3-1 HBase邏輯檢視類比JSON

{

   "12345_1516592489001_1": {

      "pc": {

          "pc:v": {

             "1516592489000": "1001",

              "1516592489001": "1002"

           },

           "pc:o": {

              "1516592489000": "1001"

           }

       },

       "ph": {

           "ph:v": {

               "1516592489001": "1002"

           }

       }

   },

   "12345_1516592490000_2": {

       "ph": {

           "ph:v": {

               "1516592490000": "1004"

           }

       }

   }

}

物理模型

HBase是一個列式儲存資料庫,資料按列族聚簇儲存在儲存檔案(StoreFile)中,空白的列單元格不會被儲存,圖1-2描述了HBase表的物理儲存模型。

(1)HBase中表按照行鍵的範圍被劃分為不同的分割槽(Region),各個分割槽由分割槽伺服器負責管理並提供資料讀寫服務,HBase主節點程序(HMaster)負責分割槽的分配以及在叢集中的遷移。

(2)一個分割槽同時有且僅由一個分割槽伺服器提供服務。當分割槽增長到配置的大小後,如果開啟了自動拆分(也可以手動拆分或者建表時預先拆分),則分割槽伺服器會負責將這個分割槽拆分成兩個。

每個分割槽都有一個唯一的分割槽名,格式是“<表名,startRowKey,建立時間>”。一個分割槽下的每個列族都會有一個儲存倉庫(Store),因此一個表有幾個列族,那麼每個分割槽就會有幾個儲存倉庫。

(3)每個Store(儲存倉庫)有且僅有一個MemStore(記憶體倉庫),但是可以有多個儲存檔案。當分割槽伺服器處理寫入請求時,資料的變更操作在寫入WAL後,會先寫入MemStore,同時在記憶體中按行鍵排序。

當MemStore到達配置的大小或者叢集中所有MemStore使用的總記憶體達到配置的閾值百分比時,MemStore會重新整理為一個StoreFile(儲存檔案)到磁碟,儲存檔案只會順序寫入,不支援修改。

(4)資料塊(block)是HBase中資料讀取的最小單元,StoreFile由資料塊組成,可以在建表時按列族指定表資料的資料塊大小。如果開啟了HBase的資料壓縮功能,資料在寫入StoreFile之前會按資料塊進行壓縮,讀取時同樣對資料塊解壓後再放入快取。理想情況下,每次讀取資料的大小都是指定的資料塊大小的倍數,這樣可以避免一些無效的IO,效率最高。

圖1-2 HBase物理檢視

圖1-3描述了上面提到的表和分割槽等各模組分別由HBase的哪些程序負責管理。

圖1-3 HBase模組互動圖

(1)HMaster:負責監控叢集中所有的分割槽伺服器程序,負責所有元資料的更新(如分割槽由哪個分割槽伺服器提供服務)。

(2)HMaster同時負責分割槽在分割槽伺服器中的負載均衡,在一個分散式叢集中,HMaster程序通常與Hadoop的NameNode執行在同一個節點,每個叢集會部署至少兩個HMaster節點,一個作為活躍節點提供服務,另一個作為備用節點提供快速的災備切換,保證叢集的高可用。

(3)HRegionServer:管理其負責的分割槽,處理分割槽的讀寫請求、分割槽增大的拆分(split)以及分割槽的壓縮(compact)。HBase客戶端根據元資料(客戶端從HMaster獲取到元資料後會快取在本地,當分割槽操作丟擲特定異常後會從HMaster重新整理快取)定位到操作資料對應的分割槽所在分割槽伺服器之後,HBase客戶端對資料的讀寫就直接與分割槽伺服器互動,因此對分割槽的讀寫不會對HMaster造成壓力。

HRegionServer程序通常與Hadoop的DataNode執行在同一個節點,這樣對資料的讀取可以儘量做到本地讀取,減少網路請求。

(4)WAL:預設情況下一個分割槽伺服器僅有一個WAL。HBase客戶端資料請求操作會先寫入WAL檔案再寫入記憶體倉庫MemStore,這樣當分割槽伺服器宕機重啟的時候,可以用WAL來恢復分割槽伺服器的狀態(如MemStore中更新的資料沒有重新整理到StoreFile持久化,則分割槽伺服器啟動時需要通過WAL重做(replay)資料更新來恢復)。

如果資料操作寫入WAL失敗,則這個更新資料的請求也會失敗。由於一個分割槽伺服器只有一個WAL,對WAL的寫入必須是順序寫入,這裡可能導致效能瓶頸,HBase1.0引入了mutiWAL的支援,mutiWAL允許分割槽伺服器併發地寫入多個WAL,這個併發來自於對WAL更新按分割槽分組,也就是說不同分割槽可以支援併發寫多個WAL,因此mutiWAL無法提升對單個分割槽的高併發更新的效能。

(5)Store:每個分割槽的每個列族對應一個儲存倉庫,一個儲存倉庫包含一個MemStore和多個儲存檔案。當MemStore的大小達到了配置的閾值後,MemStore會重新整理為一個儲存檔案,儲存檔案順序寫入,不支援修改,以HFile的形式儲存在Hadoop的DataNode中。

(6)MemStore:MemStore位於分割槽伺服器的堆記憶體,資料在寫入MemStore的時候即會按行鍵排序,這樣重新整理到儲存檔案的時候可以直接順序寫入,提高寫效能。同時,MemStore作為一個記憶體級快取,能夠提供對新寫入資料的快速訪問(新插入資料總是比老資料使用頻繁)。

《HBase入門與實踐》

彭旭 著

本書以精練的語言介紹HBase的基礎知識,讓初學者能夠快速上手使用HBase,對HBase的核心思想(如資料讀取、資料備份等)和HBase架構(如LSM樹、WAL)有深入的分析,讓有經驗的HBase開發人員也能夠循序漸進地深入理解HBase原始碼,以便更好地去除錯和解決線上遇到的各種問題。本書更加專注HBase線上實時系統的調優,讓HBase叢集響應延遲更低,能夠更好地為線上實時系統服務。

邀請10名好友關注非同步圖書10天,即可免費獲得非同步新書。

長按二維碼,可以關注我們喲

每天與你分享IT好文。

點選閱讀原文,購買HBase入門與實踐

閱讀原文