Understanding HBase and BigTable 译文
有時間翻譯一下這篇文章。http://jimbojw.com/#understan...
Google BigTable論文可下載:https://ai.google/research/pu...
在學習HBase(Google BigTable 的開源實現)的時候,我們面臨的最為困難的部分就是你需要重構你的思路來理解BigTable的概念。
非常不幸的是,在BigTable和HBase名稱中出現的table和base這兩個單詞,很容易讓我們與RDBMS(關系型數據庫管理系統)中的概念相混淆。
本文旨在從概念維度去描述清楚分布式數據存儲系統的含義。我們希望在讀完這篇文章之后,你能夠更有經驗去決定你到底需要的是HBase還是一個傳統數據庫系統。
術語
幸運的是,在論文Google's BigTable Paper中已經清晰的解釋了BigTable是什么。在Data Model章節的第一句話是:
BigTable是一種稀疏的、分布式的、持久化的多維有序字典。
論文繼續解釋到:
BigTable由索引行、索引列以及時間戳組成,在字典中的每個值都是無解釋的字節數組。
在Hadoop wiki的HBaseArchitecture頁面中指出:
HBase使用了一種與Bigtable非常相似的數據模型。用戶在標記表中存儲數據行,數據行中有一個有序的key和任意數量的列。這張表的存儲是稀疏的,所以如果用戶喜歡的話,甚至可以在同一張表的每行中瘋狂的存儲差異巨大的列。
上面提到的這些概念似乎很神秘,但其實如果你要是想明白的話這些說法都是有道理的。下面我們就按照順序討論一下幾個主題:字典、持久化、分布式、有序、多維和稀疏。
相比起試圖直接描述一個完成的系統框架,我覺得描述清楚構建系統框架的核心要素更加容易理解。
字典
HBase 和 BigTable的核心是字典。根據你所使用的編程語言背景,你可能更加熟悉與之類似的詞語是數組(PHP)、字典(Python)、哈希表(Ruby)和對象(JavaScript)。
維基百科對字典的定義是:由一組關鍵字和值組成的抽象數據類型,其中每個關鍵字都關聯一個值。
使用JavaScript Object Notation語法,簡單的字段示意如下所示:
{"zzzzz" : "woot","xyz" : "hello","aaaab" : "world","1" : "x","aaaaa" : "y" }持久化
持久化意思是說添加到字典中的數據在系統創建或處理完成后永遠存在,這個概念和其他各種持久化存儲系統并無不同,比如存放在文件系統中的文件一樣。
分布式
HBase 和 BigTable 構建在分布式文件系統之上以便底層文件存儲能夠在獨立機器陣列中分布存儲。
HBase能夠構建在Hadoop's Distributed File System (HDFS)或者Amazon的Simple Storage Service (S3)上,而BigTable能夠在Google File System (GFS)中使用。
數據以一種類似于RAID系統的方式在多個參與節點中進行復制。
本文的目標并不關心分布式系統的實現方式,本文要說明的重點是HBase和BigTable是分布式的,提供了一個保護層,如集群中某一節點故障。
有序
不像大多數字典的實現,在HBase/BigTable中鍵值對保持嚴格的字典序。即關鍵字『aaaaa』之后緊挨著『aaaab』,并且與『zzzzz』距離很遠。
考慮我們之前的例子,有序的版本看起來是這樣的:
{"1" : "x","aaaaa" : "y","aaaab" : "world","xyz" : "hello","zzzzz" : "woot" }?由于這些系統常常非常巨大而且是分布式的,有序特征實際上非常重要。相似的關鍵字的行緊密相鄰,當你必須對表進行掃描時,你最感興趣的條目之間彼此相鄰。
那么,選擇什么樣的行關鍵字就顯得十分重要。舉個例子,考慮一個表的關鍵字是主機名,那么最好的辦法就是使用主機名的逆序列出他們,例如使用com.jimbojw.www而不是www.jimbojw.com,以便相同子域的那些行都與父域名稱相鄰。
繼續域名的例子,域名為mail.jimbojw.com的行將與名稱為www.jimbojw.com的行緊鄰,而不是mail.xyz.com。
在HBase/BigTable中的有序并不意味著值是有序的。除了關鍵字外并沒有任何自動的索引方式,這里的實現就和舊有的字典實現一樣。
多維
到目前為止,我們還沒有提到任何有關『列』的概念,處理『表』,而不是普通意義上的哈希表。『列』這個詞也像是『table』和『base』的概念一樣,承載了太多的RDBMS的情感在內。
代替的,我們可以把它理解為一個多維字典——即字典中嵌套字典。在上面JSON示例中增加一維:
{"1" : {"A" : "x","B" : "z"},"aaaaa" : {"A" : "y","B" : "w" },"aaaab" : {"A" : "world","B" : "ocean"},"xyz" : {"A" : "hello", "B" : "there" },"zzzzz" : {"A" : "woot", "B" : "1337" } }?在上面的例子里,你注意到每個key都指向含有兩個key:A和B的字典。從這里開始,我們將頂級的鍵值對稱之為行。在BigTable/HBase概念中,A和B被稱之為『列簇』。
表創建時列簇即被指定,之后不可能或者很難被修改。增加新的列簇也十分昂貴,因此最為明智的做法是在最開始就指定好列簇。
幸運的是,列簇可以有任意列,由『標識符』或『標簽』指定。下面是JSON示例的子集,其中包含列標識符:
{ // ... "aaaaa" : {"A" : {"foo" : "y","bar" : "d"},"B" : {"" : "w"}},"aaaab" : {"A" : {"foo" : "world","bar" : "domination"},"B" : {"" : "ocean"} }, // ... }?注意表示的兩個行,A列簇有兩個列:foo和bar,B列簇僅有一個列,它的標識符是空字符。
當向HBase/BigTable查詢數據時,你必須提供全部列名,形式為:family:qualifier。對于這個例子,以上例子有三個列子:A:foo,A:bar和B:。
注意,盡管列簇是靜態的,列本身不是,考慮下面展開的行:
{ // ..."zzzzz" : {"A" : {"catch_phrase" : "woot",}} }?在這個示例中,行zzzzz有一列『A:catch_phrase』。由于每一行都有任意數目不同的列,沒有內建的方式查詢所有行中的所有列的列表。為了獲得信息,你需要做一次全表掃描。但是你可以查詢所有列簇的列表,因為他們是不可變的。
在HBase/BigTable中的最后一維是時間。所有數據要么使用整型時間戳,要么使用自定義的整型數據去標識版本。客戶端在插入數據時可以指定時間戳。
使用任意整型時間戳的例子:
{ // ... "aaaaa" : {"A" : {"foo" : {15 : "y",4 : "m"},"bar" : {15 : "d",}},"B" : {"" : {6 : "w"3 : "o"1 : "w"}}}, // ... }?每個列簇都有自己的規則規定了一個單元格最多能有多少個版本,在不給定時間戳的情況下,應用將請求被給定單元格數據。通常情況下,HBase/BigTable將返回最近的版本(即時間戳的值最大),因為它是按照時間逆序存儲的。
如果應用程序請求給定時間戳的給定行,HBase將返回時間戳等于或小于給定時間戳的單元格數據。
使用我們想象的HBase表,請求"aaaaa"/"A:foo"返回"y",請求"aaaaa"/"A:foo"/10返回"m",請求"aaaaa"/"A:foo"/2返回空結果。
稀疏
最后一點是稀疏。上面提到過了,在每個列簇中可以有任意數量的列,或者沒有。另一種類型的稀疏是基于行的間隙,這僅僅意味著鍵之間可能存在間隙。
當然,如果你以HBase/BigTable中基于字典的概念考慮的話就很好理解,而非RDBMS中相似的概念。
結語
希望本文能夠幫助你從概念上理解HBase數據模型感覺是什么。
就像總結說的一樣,我期待著你的想法、評論和建議。
總結
以上是生活随笔為你收集整理的Understanding HBase and BigTable 译文的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 02go 基础知识
- 下一篇: 数据结构第二章线性表学习笔记