1-HBase的安裝php
2-Java操做HBase例子html
3-HBase簡單的優化技巧java
4–存儲node
5(集羣) -壓力分載與失效轉發linux
7 -安全&權限算法
HBase是什麼?數據庫
HBase是Apache Hadoop中的一個子項目,Hbase依託於Hadoop的HDFS做爲最基本存儲基礎單元,經過使用hadoop的DFS工具就能夠看到這些這些數據 存儲文件夾的結構,還能夠經過Map/Reduce的框架(算法)對HBase進行操做,如右側的圖所示:apache
HBase在產品中還包含了Jetty,在HBase啓動時採用嵌入式的方式來啓動Jetty,所以能夠經過web界面對HBase進行管理和查看當前運行的一些狀態,很是輕巧。
爲何採用HBase?
HBase 不一樣於通常的關係數據庫,它是一個適合於非結構化數據存儲的數據庫.所謂非結構化數據存儲就是說HBase是基於列的而不是基於行的模式,這樣方面讀寫你的大數據內容。
HBase是介於Map Entry(key & value)和DB Row之間的一種數據存儲方式。就點有點相似於如今流行的Memcache,但不只僅是簡單的一個key對應一個 value,你極可能須要存儲多個屬性的數據結構,但沒有傳統數據庫表中那麼多的關聯關係,這就是所謂的鬆散數據。
簡單來講,你在HBase中的表建立的能夠看作是一張很大的表,而這個表的屬性能夠根據需求去動態增長,在HBase中沒有表與表之間關聯查詢。你只須要 告訴你的數據存儲到Hbase的那個column families 就能夠了,不須要指定它的具體類型:char,varchar,int,tinyint,text等等。可是你須要注意HBase中不包含事務此類的功 能。
Apache HBase 和Google Bigtable 有很是類似的地方,一個數據行擁有一個可選擇的鍵和任意數量的列。表是疏鬆的存儲的,所以用戶能夠給行定義各類不一樣的列,對於這樣的功能在大項目中很是實用,能夠簡化設計和升級的成本。
如何運行HBase?
從 Apache的HBase的鏡像網站上下載一個穩定版本的HBase http://mirrors.devlib.org/apache/hbase/stable/hbase-0.20.6.tar.gz, 下載完成後,對其進行解壓縮。肯定你的機器中已經正確的安裝了Java SDK、SSH,不然將沒法正常運行。
$ cd /work/hbase
進入此目錄
$ vim conf/hbase-env.sh
export JAVA_HOME=/JDK_PATH
編輯 conf/hbase-env.sh 文件,將JAVA_HOME修改成你的JDK安裝目錄
$ vim conf/regionservers
輸入你的全部HBase服務器名,localhost,或者是ip地址
$ bin/start-hbase.sh
啓動hbase, 中間須要你輸入兩次密碼,也能夠進行設置不須要輸入密碼,啓動成功,如圖所示:
$ bin/hbase rest start
啓動hbase REST服務後就能夠經過對uri: http://localhost:60050/api/ 的通用REST操做(GET/POST/PUT/DELETE)實現對hbase的REST形式數據操做.
也能夠輸入如下指令進入HQL指令模式
$ bin/hbase shell
$ bin/stop-hbase.sh
關閉HBase服務
啓動時存在的問題
因爲linux系統的主機名配置不正確,在運行HBase服務器中可能存在的問題,如圖所示:
2010-11-05 11:10:20,189 ERROR org.apache.hadoop.hbase.master.HMaster: Can not start master
java.net.UnknownHostException: ubuntu-server216: ubuntu-server216
表示你的主機名不正確,你能夠先查看一下 /etc/hosts/中名稱是什麼,再用 hostname 命令進行修改, hostname you_server_name
查看運行狀態
若是你須要對HBase的日誌進行監控你能夠查看 hbase.x.x./logs/下的日誌文件,可使用tail -f 來查看。
經過 web方式查看運行在 HBase 下的zookeeper http://localhost:60010/zk.jsp
若是你須要查看當前的運行狀態能夠經過web的方式對HBase服務器進行查看,如圖所示:
擴展閱讀1:
Apach 的 Hadoop的項目中包含了那些產品,如圖所示:
Pig 是在MapReduce上構建的查詢語言(SQL-like),適用於大量並行計算。
Chukwa 是基於Hadoop集羣中監控系統,簡單來講就是一個「看門狗」 (WatchDog)
Hive 是DataWareHouse 和 Map Reduce交集,適用於ETL方面的工做。
HBase 是一個面向列的分佈式數據庫。
Map Reduce 是Google提出的一種算法,用於超大型數據集的並行運算。
HDFS 能夠支持千萬級的大型分佈式文件系統。
Zookeeper 提供的功能包括:配置維護、名字服務、分佈式同步、組服務等,用於分佈式系統的可靠協調系統。
Avro 是一個數據序列化系統,設計用於支持大批量數據交換的應用。
擴展閱讀2:
什麼是列存儲?列存儲不一樣於傳統的關係型數據庫,其數據在表中是按行存儲的,列方式所帶來的重要好處之一就是,因爲查詢中的選擇規則是經過列來定義的,因 此整個數據庫是自動索引化的。按列存儲每一個字段的數據彙集存儲,在查詢只須要少數幾個字段的時候,能大大減小讀取的數據量,一個字段的數據彙集存儲,那就 更容易爲這種彙集存儲設計更好的壓縮/解壓算法。這張圖講述了傳統的行存儲和列存儲的區別:
擴展閱讀3:
對系統海量的Log4J日誌能夠存放在一個集中式的機器上,在此機器上安裝 splunk 能夠方便對全部日誌查看,安裝方法能夠參考:
http://www.splunk.com/base/Documentation/latest/Installation/InstallonLinux
本篇文章講述用HBase Shell命令 和 HBase Java API 對HBase 服務器 進行操做。在此以前須要對HBase的整體上有個大概的瞭解。好比說HBase服務器內部由哪些主要部件構成?HBase的內部工做原理是什麼?我想學習任何一項知識、技術的態度不能只是知道如何使用,對產品的內部構建一點都不去關心,那樣出了問題,很難讓你很快的找到答案,甚至咱們但願最後能對該項技術的領悟出本身的心得,爲我所用,借鑑該項技術其中的設計思想創造出本身的解決方案,更靈活的去應對多變的計算場景與架構設計。以我目前的對HBase的瞭解還不夠深刻,未來不斷的學習,我會把我所知道的點滴分享到這個Blog上。
先來看一下讀取一行記錄HBase是如何進行工做的,首先HBase Client端會鏈接Zookeeper Qurom(從下面的代碼也能看出來,例如:HBASE_CONFIG.set("hbase.zookeeper.quorum", "192.168.50.216") )。經過Zookeeper組件Client能獲知哪一個Server管理-ROOT- Region。那麼Client就去訪問管理-ROOT-的Server,在META中記錄了HBase中全部表信息,(你可使用 scan '.META.' 命令列出你建立的全部表的詳細信息),從而獲取Region分佈的信息。一旦Client獲取了這一行的位置信息,好比這一行屬於哪一個Region,Client將會緩存這個信息並直接訪問HRegionServer。長此以往Client緩存的信息漸漸增多,即便不訪問.META.表也能知道去訪問哪一個HRegionServer。HBase中包含兩種基本類型的文件,一種用於存儲WAL的log,另外一種用於存儲具體的數據,這些數據都經過DFS Client和分佈式的文件系統HDFS進行交互實現存儲。
如圖所示:
再來看看HBase的一些內存實現原理:
HMaster— HBase中僅有一個Master server。
HRegionServer—負責多個HRegion使之能向client端提供服務,在HBase cluster中會存在多個HRegionServer。
ServerManager—負責管理Region server信息,如每一個Region server的HServerInfo(這個對象包含HServerAddress和startCode),已load Region個數,死亡的Region server列表
RegionManager—負責將region分配到region server的具體工做,還監視root和meta 這2個系統級的region狀態。
RootScanner—按期掃描root region,以發現沒有分配的meta region。
MetaScanner—按期掃描meta region,以發現沒有分配的user region。
HBase基本命令
下面咱們再看看看HBase的一些基本操做命令,我列出了幾個經常使用的HBase Shell命令,以下:
名稱 |
命令表達式 |
|
建立表 | create '表名稱', '列名稱1','列名稱2','列名稱N' | |
添加記錄 | put '表名稱', '行名稱', '列名稱:', '值' | |
查看記錄 | get '表名稱', '行名稱' | |
查看錶中的記錄總數 | count '表名稱' | |
刪除記錄 | delete '表名' ,'行名稱' , '列名稱' | |
刪除一張表 | 先要屏蔽該表,才能對該表進行刪除,第一步 disable '表名稱' 第二步 drop '表名稱' | |
查看全部記錄 | scan "表名稱" | |
查看某個表某個列中全部數據 | scan "表名稱" , ['列名稱:'] | |
更新記錄 | 就是重寫一遍進行覆蓋 |
若是你是一個新手隊HBase的一些命令還不算很是熟悉的話,你能夠進入 hbase 的shell 模式中你能夠輸入 help 命令查看到你能夠執行的命令和對該命令的說明,例如對scan這個命令,help中不只僅提到有這個命令,還詳細的說明了scan命令中可使用的參數和做用,例如,根據列名稱查詢的方法和帶LIMIT 、STARTROW的使用方法:
scan Scan a table; pass table name and optionally a dictionary of scanner specifications. Scanner specifications may include one or more of the following: LIMIT, STARTROW, STOPROW, TIMESTAMP, or COLUMNS. If no columns are specified, all columns will be scanned. To scan all members of a column family, leave the qualifier empty as in 'col_family:'. Examples: hbase> scan '.META.' hbase> scan '.META.', {COLUMNS => 'info:regioninfo'} hbase> scan 't1', {COLUMNS => ['c1', 'c2'], LIMIT => 10, STARTROW => 'xyz'} |
使用Java API對HBase服務器進行操做
須要下列jar包
hbase-0.20.6.jar hadoop-core-0.20.1.jar commons-logging-1.1.1.jar zookeeper-3.3.0.jar log4j-1.2.91.jar import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.hbase.HBaseConfiguration; import org.apache.hadoop.hbase.HColumnDescriptor; import org.apache.hadoop.hbase.HTableDescriptor; import org.apache.hadoop.hbase.KeyValue; import org.apache.hadoop.hbase.client.HBaseAdmin; import org.apache.hadoop.hbase.client.HTable; import org.apache.hadoop.hbase.client.Result; import org.apache.hadoop.hbase.client.ResultScanner; import org.apache.hadoop.hbase.client.Scan; import org.apache.hadoop.hbase.io.BatchUpdate; @SuppressWarnings("deprecation") public class HBaseTestCase { static HBaseConfiguration cfg = null; static { Configuration HBASE_CONFIG = new Configuration(); HBASE_CONFIG.set("hbase.zookeeper.quorum", "192.168.50.216"); HBASE_CONFIG.set("hbase.zookeeper.property.clientPort", "2181"); cfg = new HBaseConfiguration(HBASE_CONFIG); } /** * 建立一張表 */ public static void creatTable(String tablename) throws Exception { HBaseAdmin admin = new HBaseAdmin(cfg); if (admin.tableExists(tablename)) { System.out.println("table Exists!!!"); } else{ HTableDescriptor tableDesc = new HTableDescriptor(tablename); tableDesc.addFamily(new HColumnDescriptor("name:")); admin.createTable(tableDesc); System.out.println("create table ok ."); } } /** * 添加一條數據 */ public static void addData (String tablename) throws Exception{ HTable table = new HTable(cfg, tablename); BatchUpdate update = new BatchUpdate("Huangyi"); update.put("name:java", "http://www.javabloger.com".getBytes()); table.commit(update); System.out.println("add data ok ."); } /** * 顯示全部數據 */ public static void getAllData (String tablename) throws Exception{ HTable table = new HTable(cfg, tablename); Scan s = new Scan(); ResultScanner ss = table.getScanner(s); for(Result r:ss){ for(KeyValue kv:r.raw()){ System.out.print(new String(kv.getColumn())); System.out.println(new String(kv.getValue() )); } } } public static void main (String [] agrs) { try { String tablename="tablename"; HBaseTestCase.creatTable(tablename); HBaseTestCase.addData(tablename); HBaseTestCase.getAllData(tablename); } catch (Exception e) { e.printStackTrace(); } } } |
這篇文章淺顯的從幾個方面談談HBase的一些優化技巧,只能做爲我學習筆記的一部分,由於學多了怕忘,留給本身之後看看。
1 修改 linux 系統參數
Linux系統最大可打開文件數通常默認的參數值是1024,若是你不進行修改併發量上來的時候會出現「Too Many Open Files」的錯誤,致使整個HBase不可運行,你能夠用ulimit -n 命令進行修改,或者修改/etc/security/limits.conf 和/proc/sys/fs/file-max 的參數,具體如何修改能夠去Google 關鍵字 「linux limits.conf 」
2 JVM 配置
修改 hbase-env.sh 文件中的配置參數,根據你的機器硬件和當前操做系統的JVM(32/64位)配置適當的參數
HBASE_HEAPSIZE 4000 HBase使用的 JVM 堆的大小
HBASE_OPTS "‐server ‐XX:+UseConcMarkSweepGC"JVM GC 選項
HBASE_MANAGES_ZKfalse 是否使用Zookeeper進行分佈式管理
3 HBase持久化
重啓操做系統後HBase中數據全無,你能夠不作任何修改的狀況下,建立一張表,寫一條數據進行,而後將機器重啓,重啓後你再進入HBase的shell中使用 list 命令查看當前所存在的表,一個都沒有了。是否是很杯具?沒有關係你能夠在hbase/conf/hbase-default.xml中設置hbase.rootdir的值,來設置文件的保存位置指定一個文件夾 ,例如:<value>file:///you/hbase-data/path</value>,你創建的HBase中的表和數據就直接寫到了你的磁盤上,如圖所示:
一樣你也能夠指定你的分佈式文件系統HDFS的路徑例如: hdfs://NAMENODE_SERVER:PORT/HBASE_ROOTDIR,這樣就寫到了你的分佈式文件系統上了。
4 配置HBase運行參數
其次就須要對hbase/conf/hbase-default.xml 文件進行配置,如下是我認爲比較重要的配置參數
hbase.client.write.buffer
描述:這個參數能夠設置寫入數據緩衝區的大小,當客戶端和服務器端傳輸數據,服務器爲了提升系統運行性能開闢一個寫的緩衝區來處理它, 這個參數設置若是設置的大了,將會對系統的內存有必定的要求,直接影響系統的性能。
hbase.master.meta.thread.rescanfrequency
描述:多長時間 HMaster對系統表 root 和 meta 掃描一次,這個參數能夠設置的長一些,下降系統的能耗。
hbase.regionserver.handler.count
描述:因爲HBase/Hadoop的Server是採用Multiplexed, non-blocking I/O方式而設計的,因此它能夠透過一個Thread來完成處理,可是因爲處理Client端所呼叫的方法是Blocking I/O,因此它的設計會將Client所傳遞過來的物件先放置在Queue,並在啓動Server時就先產生一堆Handler(Thread),該Handler會透過Polling的方式來取得該物件並執行對應的方法,默認爲25,根據實際場景能夠設置大一些。
hbase.regionserver.thread.splitcompactcheckfrequency
描述:這個參數是表示多久去RegionServer服務器運行一次split/compaction的時間間隔,固然split以前會先進行一個compact操做.這個compact操做多是minor compact也多是major compact.compact後,會從全部的Store下的全部StoreFile文件最大的那個取midkey.這個midkey可能並不處於所有數據的mid中.一個row-key的下面的數據可能會跨不一樣的HRegion。
hbase.hregion.max.filesize
描述:HRegion中的HStoreFile最大值,任何表中的列族一旦超過這個大小將會被切分,而HStroeFile的默認大小是256M。
hfile.block.cache.size
描述:指定 HFile/StoreFile 緩存在JVM堆中分配的百分比,默認值是0.2,意思就是20%,而若是你設置成0,就表示對該選項屏蔽。
hbase.zookeeper.property.maxClientCnxns
描述: 這項配置的選項就是從zookeeper中來的,表示ZooKeeper客戶端同時訪問的併發鏈接數,ZooKeeper對於HBase來講就是一個入口這個參數的值能夠適當放大些。
hbase.regionserver.global.memstore.upperLimit
描述:在Region Server中全部memstores佔用堆的大小參數配置,默認值是0.4,表示40%,若是設置爲0,就是對選項進行屏蔽。
hbase.hregion.memstore.flush.size
描述:Memstore中緩存的內容超過配置的範圍後將會寫到磁盤上,例如:刪除操做是先寫入MemStore裏作個標記,指示那個value, column 或 family等下是要刪除的,HBase會按期對存儲文件作一個major compaction,在那時HBase會把MemStore刷入一個新的HFile存儲文件中。若是在必定時間範圍內沒有作major compaction,而Memstore中超出的範圍就寫入磁盤上了。
5 HBase中log4j的日誌
HBase中日誌輸出等級默認狀態下是把debug、 info 級別的日誌打開的,能夠根據本身的須要調整log級別,HBase的log4j日誌配置文件在 hbase\conf\log4j.properties 目錄下。
在HBase中建立的一張表能夠分佈在多個Hregion,也就說一張表能夠被拆分紅多塊,每一塊稱咱們呼爲一個Hregion。每一個Hregion會保 存一個表裏面某段連續的數據,用戶建立的那個大表中的每一個Hregion塊是由Hregion服務器提供維護,訪問Hregion塊是要經過 Hregion服務器,而一個Hregion塊對應一個Hregion服務器,一張完整的表能夠保存在多個Hregion 上。HRegion Server 與Region的對應關係是一對多的關係。每個HRegion在物理上會被分爲三個部分:Hmemcache(緩存)、Hlog(日誌)、HStore(持久層)。
上述這些關係在我腦海中的樣子,如圖所示:
1.HRegionServer、HRegion、Hmemcache、Hlog、HStore之間的關係,如圖所示:
2.HBase表中的數據與HRegionServer的分佈關係,如圖所示:
HBase讀數據
HBase讀取數據優先讀取HMemcache中的內容,若是未取到再去讀取Hstore中的數據,提升數據讀取的性能。
HBase寫數據
HBase寫入數據會寫到HMemcache和Hlog中,HMemcache創建緩存,Hlog同步Hmemcache和Hstore的事務日誌,發起Flush Cache時,數據持久化到Hstore中,並清空HMemecache。
客戶端訪問這些數據的時候經過Hmaster ,每一個 Hregion 服務器都會和Hmaster 服務器保持一個長鏈接,Hmaster 是HBase分佈式系統中的管理者,他的主要任務就是要告訴每一個Hregion 服務器它要維護哪些Hregion。用戶的這些都數據能夠保存在Hadoop 分佈式文件系統上。 若是主服務器Hmaster死機,那麼整個系統都會無效。下面我會考慮如何解決Hmaster的SPFO的問題,這個問題有點相似Hadoop的SPFO 問題同樣只有一個NameNode維護全局的DataNode,HDFS一旦死機所有掛了,也有人說採用Heartbeat來解決這個問題,但我總想找出 其餘的解決方案,多點時間,總有辦法的。
昨天在hadoop-0.21.0、hbase-0.20.6的環境中折騰了好久,一直報錯,錯誤信息以下:
Exception in thread "main" java.io.IOException: Call to localhost/serv6:9000 failed on local exception: java.io.EOFException 10/11/10 15:34:34 ERROR master.HMaster: Can not start master java.lang.reflect.InvocationTargetException at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27) at java.lang.reflect.Constructor.newInstance(Constructor.java:513) at org.apache.hadoop.hbase.master.HMaster.doMain(HMaster.java:1233) at org.apache.hadoop.hbase.master.HMaster.main(HMaster.java:1274) |
死活鏈接不上HDFS,也沒法鏈接HMaster,鬱悶啊。
我想一想啊,慢慢想,我眼前一亮 java.io.EOFException 這個異常,是否是有多是RPC 協定格式不一致致使的?也就是說服務器端和客戶端的版本不一致的問題?換了一個HDFS的服務器端之後,一切都好了,果真是版本的問題,最後採用 hadoop-0.20.2 搭配hbase-0.20.6 比較妥當。
最後的效果如圖所示:
上圖的一些文字說明:
hadoop版本是0.20.2 ,
hbase版本是0.20.6,
在hbase中建立了一張表 tab1,退出hbase shell環境,
用hadoop命令查看,文件系統中的文件果真多了一個剛剛建立的tab1目錄,以上這張圖片說明HBase在分佈式文件系統Apache HDFS中運行了。
在上一篇關於HBase的文章中曾經講述過HBase在分佈式中的架構,這篇文章將會講述HBase在分佈式環境中是如何排除單點故障的(SPFO),作一個小實驗講述HBase在分佈式環境中的高可用性,親眼看到一些現象,延伸一些思考的話題。
先來回顧一下HBase主要部件:
HBaseMaster
HRegionServer
HBase Client
HBase Thrift Server
HBase REST Server
HBaseMaster
HMaster 負責給HRegionServer分配區域,而且負責對集羣環境中的HReginServer進行負載均衡,HMaster還負責監控集羣環境中的HReginServer的運行情況,若是某一臺HReginServer down機,HBaseMaster將會把不可用的HReginServer來提供服務的HLog和表進行從新分配轉交給其餘HReginServer來提供,HBaseMaster還負責對數據和表進行管理,處理表結構和表中數據的變動,由於在 META 系統表中存儲了全部的相關表信息。而且HMaster實現了ZooKeeper的Watcher接口能夠和zookeeper集×××互。
HRegionServer
HReginServer負責處理用戶的讀和寫的操做。HReginServer經過與HBaseMaster通訊獲取本身須要服務的數據表,並向HMaster反饋本身的運行情況。當一個寫的請求到來的時候,它首先會寫到一個叫作HLog的write-ahead log中。HLog被緩存在內存中,稱爲Memcache,每個HStore只能有一個Memcache。當Memcache到達配置的大小之後,將會建立一個MapFile,將其寫到磁盤中去。這將減小HReginServer的內存壓力。當一塊兒讀取的請求到來的時候,HReginServer會先在Memcache中尋找該數據,當找不到的時候,纔會去在MapFiles 中尋找。
HBase Client
HBase Client負責尋找提供需求數據的HReginServer。在這個過程當中,HBase Client將首先與HMaster通訊,找到ROOT區域。這個操做是Client和Master之間僅有的通訊操做。一旦ROOT區域被找到之後,Client就能夠經過掃描ROOT區域找到相應的META區域去定位實際提供數據的HReginServer。當定位到提供數據的HReginServer之後,Client就能夠經過這個HReginServer找到須要的數據了。這些信息將會被Client緩存起來,當下次請求的時候,就不須要走上面的這個流程了。
HBase服務接口
HBase Thrift Server和HBase REST Server是經過非Java程序對HBase進行訪問的一種途徑。
進入正題
先來看一個HBase集羣的模擬環境,此環境中一共有4臺機器,分別包含 zookeeper、HBaseMaster、HReginServer、HDSF 4個服務,爲了展現失效轉發的效果HBaseMaster、HReginServer各有2臺,只是在一臺機器上即運行了HBaseMaster,也運行了HReginServer。
注意,HBase的集羣環境中HBaseMaster只有失效轉發沒有壓力分載的功能,而HReginServer即提供失效轉發也提供壓力分載。
服務器清單以下:
zookeeper 192.168.20.214
HBaseMaster 192.168.20.213/192.168.20.215
HReginServer 192.168.20.213/192.168.20.215
HDSF 192.168.20.212
整個模擬環境的架構如圖所示:
注意,這裏只是作了一個模擬環境,由於這個環境的重點是HBase,因此zookeeper和HDFS服務都是單臺。
雖說在整個HBase的集羣環境中只能有一個HMaster,但是在集羣環境中HMaster能夠啓動多個,但真正使用到的HMaster Server只有一個,他不down掉的時候,其餘啓動的HMaster Server並不會工做,直到與ZooKeeper服務器判斷與當前運行的HMaster通信超時,認爲這個正在運行的HMaster服務器down掉了,Zookeeper纔會去鏈接下一臺HMaster Server。
簡單來講,若是運行中HMaster服務器down掉了,那麼zookeeper會從列表中選擇下一個HMaster 服務器進行訪問,讓他接管down掉的HMaster任務,換而言之,用Java客戶端對HBase進行操做是經過ZooKeeper的,也就是說若是zookeeper集羣中的節點全掛了 那麼HBase的集羣也掛了。自己HBase並不存儲中的任何數據 真正的數據是保存在HDFS上,因此HBase的數據是一致的,可是HDFS文件系統掛了,HBase的集羣也掛。
在一臺HMaster失敗後,客戶端對HBase集羣環境訪問時,客戶端先會經過zookeeper識別到HMaster運行異常,直到確認屢次後,才鏈接到下一個HMaster,此時,備份的HMaster服務才生效,在IDE環境中的效果,如圖所示:
上圖中能看見拋出的一些異常和name:javahttp://www.javabloger.com和name:javahttp://www.javabloger.com1的結果集,由於我在serv215機器上用killall java命令把 HMaster和HReginServer都關掉,而且馬上用Java客戶端對HBase的集羣環境進行訪問有異常拋出,可是retry到必定次數後查詢出結果,前面已經說了訪問HBase是經過zookeeper再和真正的數據打交道,也就是說zookeeper接管了一個standby 的 HMaster,讓原先Standby的HMaster接替了失效的HMaster任務,而被接管的HBaseMaster再對HReginServer的任務進行分配,當 HReginServer失敗後zookeeper會通知 HMaster對HReginServer的任務進行分配。這樣充分的說明了HBase作到了實效轉發的功能。
如圖所示:
口水:
一、HBase的失效轉發的效率比較慢了,不期望能在1-2秒切換和恢復完畢,也許是我暫時沒有發現有什麼參數能夠提升失效轉發和恢復過程的速度,未來會繼續關注這個問題。
二、在官方網站上看見HBase0.89.20100924的版本有篇講述關於數據同步的文章,我嘗試了一下在一臺機器上能夠運行所謂的HBase虛擬集羣環境,可是切換到多臺機器的分佈式環境中,單點失效轉發的速度很慢比HBase0.20.6還要慢,我又檢查了是否存在網絡的問題,目前還沒有找到正確的答案,對與HBase0.89.20100924 新版中的數據同步的原理,如圖所示:(更多信息)
個人廢話1:
任何一項新技術並不是救命稻草,一抹一擦立馬藥到病除的百寶箱,並不是使用Spring或者NOSQL的產品就神乎其神+五顏六色,若是那樣基本是扯淡。同類 型產品中無論那種技術最終要達到的目的是同樣的,經過新的技術手段你每每可能避諱了當前你所須要面對的問題,但事後新的問題又來了。也許回過頭來看看還不 如在原來的基礎上多動動腦筋 想一想辦法 作些改良能夠獲得更高的回報。
傳統數據庫是以數據塊來存儲數據,簡單來講,你的表字段越多,佔用的數據空間就越多,那麼查詢有可能就要跨數據塊,將會致使查詢的速度變慢。在大型系統中一張表上百個字段,而且表中的數據上億條這是徹底是有可能的。所以會帶來數據庫查詢的瓶頸。咱們都知道一個常識數據庫中表記錄的多少對查詢的性能有很是大的影響,此時你頗有可能想到分表、分庫的作法來分載數據庫運算的壓力,那麼又會帶來新的問題,例如:分佈式事務、全局惟一ID的生成、跨數據庫查詢 等,依舊會讓你面對棘手的問題。若是打破這種按照行存儲的模式,採用一種基於列存儲的模式,對於大規模數據場景這樣狀況有可能發生一些好轉。因爲查詢中的選擇規則是經過列來定義的,所以整個數據庫是自動索引化的。按列存儲每一個字段的數據彙集存儲, 能夠動態增長,而且列爲空就不存儲數據,節省存儲空間。 每一個字段的數據按照彙集存儲,能大大減小讀取的數據量,查詢時指哪打哪,來的更直接。無需考慮分庫、分表 Hbase將對存儲的數據自動切分數據,並支持高併發讀寫操做,使得海量數據存儲自動具備更強的擴展性。
Java中的HashMap是Key/Value的結構,你也能夠把HBase的數據結構看作是一個Key/Value的體系,話說HBase的區域由表名和行界定的。在HBase區域每個"列族"都由一個名爲HStore的對象管理。每一個HStore由一個或多個MapFiles(Hadoop中的一個文件類型)組成。MapFiles的概念相似於Google的SSTable。 在Hbase裏面有如下兩個主要的概念,Row key 和 Column Family,其次是Cell qualifier和Timestamp tuple,Column family咱們一般稱之爲「列族」,訪問控制、磁盤和內存的使用統計都是在列族層面進行的。列族Column family是以前預先定義好的數據模型,每個Column Family均可以根據「限定符」有多個column。在HBase每一個cell存儲單元對同一份數據有多個版本,根據惟一的時間戳來區分每一個版本之間的差別,最新的數據版本排在最前面 。
口水:Hbase將table水平劃分紅N個Region,region按column family劃分紅Store,每一個store包括內存中的memstore和持久化到disk上的HFile。
上述可能我表達的還不夠到位,下面來看一個實踐中的場景,將原來是存放在MySQL中Blog中的數據遷移到HBase中的過程:
MySQL中現有的表結構:
遷移HBase中的表結構:
原來系統中有2張表blogtable和comment表,採用HBase後只有一張blogtable表,若是按照傳統的RDBMS的話,blogtable表中的列是固定的,好比schema 定義了Author,Title,URL,text等屬性,上線後表字段是不能動態增長的。可是若是採用列存儲系統,好比Hbase,那麼咱們能夠定義blogtable表,而後定義info 列族,User的數據能夠分爲:info:title ,info:author ,info:url 等,若是後來你又想增長另外的屬性,這樣很方便只須要 info:xxx 就能夠了。
對於Row key你能夠理解row key爲傳統RDBMS中的某一個行的主鍵,Hbase是不支持條件查詢以及Order by等查詢,所以Row key的設計就要根據你係統的查詢需求來設計了額。 Hbase中的記錄是按照rowkey來排序的,這樣就使得查詢變得很是快。
具體操做過程以下:
============================建立blogtable表========================= create 'blogtable', 'info','text','comment_title','comment_author','comment_text' ============================插入概要信息========================= put 'blogtable', '1', 'info:title', 'this is doc title' put 'blogtable', '1', 'info:author', 'javabloger' put 'blogtable', '1', 'info:url', 'http://www.javabloger.com/index.php' put 'blogtable', '2', 'info:title', 'this is doc title2' put 'blogtable', '2', 'info:author', 'H.E.' put 'blogtable', '2', 'info:url', 'http://www.javabloger.com/index.html' ============================插入正文信息========================= put 'blogtable', '1', 'text:', 'what is this doc context ?' put 'blogtable', '2', 'text:', 'what is this doc context2?' ==========================插入評論信息=============================== put 'blogtable', '1', 'comment_title:', 'this is doc comment_title ' put 'blogtable', '1', 'comment_author:', 'javabloger' put 'blogtable', '1', 'comment_text:', 'this is nice doc' put 'blogtable', '2', 'comment_title:', 'this is blog comment_title ' put 'blogtable', '2', 'comment_author:', 'H.E.' put 'blogtable', '2', 'comment_text:', 'this is nice blog' |
HBase的數據查詢\讀取,能夠經過單個row key訪問,row key的range和全表掃描,大體以下:
注意:HBase不能支持where條件、Order by 查詢,只支持按照Row key來查詢,可是能夠經過HBase提供的API進行條件過濾。
例如:http://hbase.apache.org/apidocs/org/apache/hadoop/hbase/filter/ColumnPrefixFilter.html
scan 'blogtable' ,{COLUMNS => ['text:','info:title'] } —> 列出 文章的內容和標題
scan 'blogtable' , {COLUMNS => 'info:url' , STARTROW => '2'} —> 根據範圍列出 文章的內容和標題
get 'blogtable','1' —> 列出 文章id 等於1的數據
get 'blogtable','1', {COLUMN => 'info'} —> 列出 文章id 等於1 的 info 的頭(Head)內容
get 'blogtable','1', {COLUMN => 'text'} —> 列出 文章id 等於1 的 text 的具體(Body)內容
get 'blogtable','1', {COLUMN => ['text','info:author']} —> 列出 文章id 等於1 的內容和做者(Body/Author)內容
個人廢話2:
有人會問Java Web服務器中是Tomcat快仍是GlassFish快?小型數據庫中是MySQL效率高仍是MS-SQL效率高?我看是關鍵用在什麼場景和怎麼使用這 個產品(技術),因此我漸漸的認爲是須要對產品、技術自己深刻的瞭解,而並不是一項新的技術就是絕佳的選擇。試問:Tomcat的默認的運行參數能和咱們線 上正在使用的GlassFish性能相提並論嗎?我不相信GlassFishv2和GlassFishv3在默認的配置參數下有顯著的差異。咱們須要對產 品自己作到深刻的瞭解才能發揮他最高的性能,而並不是感觀遵從廠家的廣告和本身的感性認識 迷信哪一個產品的優越性。
個人廢話3:
對於NOSQL這樣的新技術,的的確確是能夠解決過去咱們所須要面對的問題,但也並不是適合每一個應用場景,因此在使用新產品的同時須要切合當前的產品須要, 是需求在引導新技術的投入,而並不是爲了趕時髦去使用他。你的產品是否過硬不是你使用了什麼新技術,用戶關心的是速度和穩定性,不會關心你是否使用了 NOSQL。相反Google有着超大的數據量,能給全世界用戶帶來了驚人的速度和準確性,你們纔會回過頭來好奇Google究竟是怎麼作到的。因此根據 本身的須要千萬別太勉強本身使用了某項新技術。
個人廢話4:
總之一句話,用什麼不是最關鍵,最關鍵是怎麼去使用!
個人廢話:
大年三十夜,看春晚實在是太無聊了,整個《新聞聯播》的電視劇版本,還不如上上網,看看資料,喝喝老酒,寫點東西來的快活。
近2年來雲計算的話題到目前爲止風風火火歷來沒有平靜過,一直是你們嘴邊討論的熱門話題,人們指望運用雲計算提供可靠、穩定、高速的計算,在雲計算中Google是目前最大的雲計算供應商,例如:Google GAE(Google App Engine)和Google的Docs在線文章服務,這些SaaS上線產品的數據存儲(datastore)是由BigTable提供存儲服務的,在次以前我提到過Yahoo貢獻給Apache的那些山寨版本(Google與Yahoo的那些利器),其中Apache的HBase就是山寨了Google的BigTable。
咱們知道在雲計算的技術話題中Apache的Hadoop項目是一塊基石,利用Hadoop項目中的產品能夠創建雲計算平臺和超大型的計算。不知道你是否有想過若是將HBase做爲Google GAE上的數據存儲(datastore),那麼每一個用戶之間的數據訪問權限怎麼辦?若是使用HBase提供對大客戶提供「私有云」(private cloud)或者另外一種可能一個公司內部的集羣上運行HBase,公司的內部可能有幾個部門,某幾個部門之間的數據都是獨立分離但又運行在一個平臺上,那麼你就會發現HBase不具有這樣的功能,貌似目前HBase的最高版本0.90.0尚未這樣的功能對用戶的表、Row、Cell的訪問權限。可是咱們知道Google的GAE上每一個用戶訪問的數據確定是有權限劃分的,否則我只要有權限登陸GEA就能看見全部用戶存放的數據了。這樣的問題你有可能沒有想過,但趨勢公司的工程師們卻爲此想到了這點,而且把他們的設想和設計提交了HBase項目組,而且提出瞭如下主要的設計思想:
Client access to HBase is authenticated
User data is private unless access has been granted
Access to data can be granted at a table or per column family basis.
對HBase中的表和數據劃分權限等級和身份驗證後,操做權限被分爲3大類,每類中包含的操做權限以下所示:
對於方案中涉及到存儲的權限的是指整個表或表中的列族,也就是說只考慮在表這個級別的權限,表與表之間的所屬關係是存放在 .META. 系統表中,以regioninfo:owner 的格式進行存放,例如:系統中table1這個表是有權限的,這個表權限的存根保存在3個地方 :
The row in .META. for the first region of table1
The node /hbase/acl/table1 of Zookeeper
The in-memory Permissions Mirror of every regionserver that serves table1
如圖所示,圖中的箭頭表示了數據流向的順序:
方案中HBase在分佈式、集羣環境下,而權限一致性的問題交給了Zookeeper來處理,在多個regionservers中,每一個服務器的HRegion中存放着多個表,而且實現了(implement)ZKPermissionWatcher接口的nodeCreated() 和 nodeChanged() 方法,這2個方法對Zookeeper 的節點進行監控, 節點的狀態發生相應的變化時會ZooKeeper刷新鏡像中的權限。
如圖所示:
HBase的這一關於權限的功能正在設計和研討當中,讓咱們繼續對他保持關注,看看從此將會發生的變化能給咱們帶來什麼樣的效果,很是期待這個功能早日正式發佈。