HBase是什么? HBase是Apache Hadoop中的一個(gè)子項(xiàng)目,Hbase依托于Hadoop的HDFS作為最基本存儲(chǔ)基礎(chǔ)單元,通過(guò)使用hadoop的DFS工具就可以看到這些這些數(shù)據(jù) 存儲(chǔ)文件夾的結(jié)構(gòu),還可以通過(guò)Map/Reduce的框架(算法)對(duì)HBase進(jìn)行操作,如右側(cè)的圖所示:
HBase在產(chǎn)品中還包含了Jetty,在HBase啟動(dòng)時(shí)采用嵌入式的方式來(lái)啟動(dòng)Jetty,因此可以通過(guò)web界面對(duì)HBase進(jìn)行管理和查看當(dāng)前運(yùn)行的一些狀態(tài),非常輕巧。 為什么采用HBase? HBase 不同于一般的關(guān)系數(shù)據(jù)庫(kù),它是一個(gè)適合于非結(jié)構(gòu)化數(shù)據(jù)存儲(chǔ)的數(shù)據(jù)庫(kù).所謂非結(jié)構(gòu)化數(shù)據(jù)存儲(chǔ)就是說(shuō)HBase是基于列的而不是基于行的模式,這樣方面讀寫你的大數(shù)據(jù)內(nèi)容。 HBase是介于Map Entry(key & value)和DB Row之間的一種數(shù)據(jù)存儲(chǔ)方式。就點(diǎn)有點(diǎn)類似于現(xiàn)在流行的Memcache,但不僅僅是簡(jiǎn)單的一個(gè)key對(duì)應(yīng)一個(gè) value,你很可能需要存儲(chǔ)多個(gè)屬性的數(shù)據(jù)結(jié)構(gòu),但沒有傳統(tǒng)數(shù)據(jù)庫(kù)表中那么多的關(guān)聯(lián)關(guān)系,這就是所謂的松散數(shù)據(jù)。 簡(jiǎn)單來(lái)說(shuō),你在HBase中的表創(chuàng)建的可以看做是一張很大的表,而這個(gè)表的屬性可以根據(jù)需求去動(dòng)態(tài)增加,在HBase中沒有表與表之間關(guān)聯(lián)查詢。你只需要 告訴你的數(shù)據(jù)存儲(chǔ)到Hbase的那個(gè)column families 就可以了,不需要指定它的具體類型:char,varchar,int,tinyint,text等等。但是你需要注意HBase中不包含事務(wù)此類的功 能。 Apache HBase 和Google Bigtable 有非常相似的地方,一個(gè)數(shù)據(jù)行擁有一個(gè)可選擇的鍵和任意數(shù)量的列。表是疏松的存儲(chǔ)的,因此用戶可以給行定義各種不同的列,對(duì)于這樣的功能在大項(xiàng)目中非常實(shí)用,可以簡(jiǎn)化設(shè)計(jì)和升級(jí)的成本。 如何運(yùn)行HBase? 從 Apache的HBase的鏡像網(wǎng)站上下載一個(gè)穩(wěn)定版本的HBase http://mirrors./apache/hbase/stable/hbase-0.20.6.tar.gz, 下載完成后,對(duì)其進(jìn)行解壓縮。確定你的機(jī)器中已經(jīng)正確的安裝了Java SDK、SSH,否則將無(wú)法正常運(yùn)行。 $ cd /work/hbase 進(jìn)入此目錄 $ vim conf/hbase-env.sh export JAVA_HOME=/JDK_PATH 編輯 conf/hbase-env.sh 文件,將JAVA_HOME修改為你的JDK安裝目錄 $ vim conf/regionservers 輸入你的所有HBase服務(wù)器名,localhost,或者是ip地址 $ bin/start-hbase.sh 啟動(dòng)hbase, 中間需要你輸入兩次密碼,也可以進(jìn)行設(shè)置不需要輸入密碼,啟動(dòng)成功,如圖所示:
$ bin/hbase rest start 啟動(dòng)hbase REST服務(wù)后就可以通過(guò)對(duì)uri: http://localhost:60050/api/ 的通用REST操作(GET/POST/PUT/DELETE)實(shí)現(xiàn)對(duì)hbase的REST形式數(shù)據(jù)操作. 也可以輸入以下指令進(jìn)入HQL指令模式 $ bin/hbase shell $ bin/stop-hbase.sh 關(guān)閉HBase服務(wù) 啟動(dòng)時(shí)存在的問(wèn)題 由于linux系統(tǒng)的主機(jī)名配置不正確,在運(yùn)行HBase服務(wù)器中可能存在的問(wèn)題,如圖所示:
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 表示你的主機(jī)名不正確,你可以先查看一下 /etc/hosts/中名稱是什么,再用 hostname 命令進(jìn)行修改, hostname you_server_name 查看運(yùn)行狀態(tài)
擴(kuò)展閱讀1: Apach 的 Hadoop的項(xiàng)目中包含了那些產(chǎn)品,如圖所示:
Pig 是在MapReduce上構(gòu)建的查詢語(yǔ)言(SQL-like),適用于大量并行計(jì)算。 Chukwa 是基于Hadoop集群中監(jiān)控系統(tǒng),簡(jiǎn)單來(lái)說(shuō)就是一個(gè)“看門狗” (WatchDog) Hive 是DataWareHouse 和 Map Reduce交集,適用于ETL方面的工作。 HBase 是一個(gè)面向列的分布式數(shù)據(jù)庫(kù)。 Map Reduce 是Google提出的一種算法,用于超大型數(shù)據(jù)集的并行運(yùn)算。 HDFS 可以支持千萬(wàn)級(jí)的大型分布式文件系統(tǒng)。 Zookeeper 提供的功能包括:配置維護(hù)、名字服務(wù)、分布式同步、組服務(wù)等,用于分布式系統(tǒng)的可靠協(xié)調(diào)系統(tǒng)。 Avro 是一個(gè)數(shù)據(jù)序列化系統(tǒng),設(shè)計(jì)用于支持大批量數(shù)據(jù)交換的應(yīng)用。 擴(kuò)展閱讀2: 什么是列存儲(chǔ)?列存儲(chǔ)不同于傳統(tǒng)的關(guān)系型數(shù)據(jù)庫(kù),其數(shù)據(jù)在表中是按行存儲(chǔ)的,列方式所帶來(lái)的重要好處之一就是,由于查詢中的選擇規(guī)則是通過(guò)列來(lái)定義的,因 此整個(gè)數(shù)據(jù)庫(kù)是自動(dòng)索引化的。按列存儲(chǔ)每個(gè)字段的數(shù)據(jù)聚集存儲(chǔ),在查詢只需要少數(shù)幾個(gè)字段的時(shí)候,能大大減少讀取的數(shù)據(jù)量,一個(gè)字段的數(shù)據(jù)聚集存儲(chǔ),那就 更容易為這種聚集存儲(chǔ)設(shè)計(jì)更好的壓縮/解壓算法。這張圖講述了傳統(tǒng)的行存儲(chǔ)和列存儲(chǔ)的區(qū)別:
擴(kuò)展閱讀3:
對(duì)系統(tǒng)海量的Log4J日志可以存放在一個(gè)集中式的機(jī)器上,在此機(jī)器上安裝 splunk 可以方便對(duì)所有日志查看,安裝方法可以參考: 本篇文章講述用HBase Shell命令 和 HBase Java API 對(duì)HBase 服務(wù)器 進(jìn)行操作。在此之前需要對(duì)HBase的總體上有個(gè)大概的了解。比如說(shuō)HBase服務(wù)器內(nèi)部由哪些主要部件構(gòu)成?HBase的內(nèi)部工作原理是什么?我想學(xué)習(xí)任何一項(xiàng)知識(shí)、技術(shù)的態(tài)度不能只是知道如何使用,對(duì)產(chǎn)品的內(nèi)部構(gòu)建一點(diǎn)都不去關(guān)心,那樣出了問(wèn)題,很難讓你很快的找到答案,甚至我們希望最后能對(duì)該項(xiàng)技術(shù)的領(lǐng)悟出自己的心得,為我所用,借鑒該項(xiàng)技術(shù)其中的設(shè)計(jì)思想創(chuàng)造出自己的解決方案,更靈活的去應(yīng)對(duì)多變的計(jì)算場(chǎng)景與架構(gòu)設(shè)計(jì)。以我目前的對(duì)HBase的了解還不夠深入,將來(lái)不斷的學(xué)習(xí),我會(huì)把我所知道的點(diǎn)滴分享到這個(gè)Blog上。 先來(lái)看一下讀取一行記錄HBase是如何進(jìn)行工作的,首先HBase Client端會(huì)連接Zookeeper Qurom(從下面的代碼也能看出來(lái),例如:HBASE_CONFIG.set('hbase.zookeeper.quorum', '192.168.50.216') )。通過(guò)Zookeeper組件Client能獲知哪個(gè)Server管理-ROOT- Region。那么Client就去訪問(wèn)管理-ROOT-的Server,在META中記錄了HBase中所有表信息,(你可以使用 scan '.META.' 命令列出你創(chuàng)建的所有表的詳細(xì)信息),從而獲取Region分布的信息。一旦Client獲取了這一行的位置信息,比如這一行屬于哪個(gè)Region,Client將會(huì)緩存這個(gè)信息并直接訪問(wèn)HRegionServer。久而久之Client緩存的信息漸漸增多,即使不訪問(wèn).META.表也能知道去訪問(wèn)哪個(gè)HRegionServer。HBase中包含兩種基本類型的文件,一種用于存儲(chǔ)WAL的log,另一種用于存儲(chǔ)具體的數(shù)據(jù),這些數(shù)據(jù)都通過(guò)DFS Client和分布式的文件系統(tǒng)HDFS進(jìn)行交互實(shí)現(xiàn)存儲(chǔ)。 如圖所示:
再來(lái)看看HBase的一些內(nèi)存實(shí)現(xiàn)原理:
HBase基本命令 下面我們?cè)倏纯纯碒Base的一些基本操作命令,我列出了幾個(gè)常用的HBase Shell命令,如下:
如果你是一個(gè)新手隊(duì)HBase的一些命令還不算非常熟悉的話,你可以進(jìn)入 hbase 的shell 模式中你可以輸入 help 命令查看到你可以執(zhí)行的命令和對(duì)該命令的說(shuō)明,例如對(duì)scan這個(gè)命令,help中不僅僅提到有這個(gè)命令,還詳細(xì)的說(shuō)明了scan命令中可以使用的參數(shù)和作用,例如,根據(jù)列名稱查詢的方法和帶LIMIT 、STARTROW的使用方法:
使用Java API對(duì)HBase服務(wù)器進(jìn)行操作 需要下列jar包
這篇文章淺顯的從幾個(gè)方面談?wù)凥Base的一些優(yōu)化技巧,只能作為我學(xué)習(xí)筆記的一部分,因?yàn)閷W(xué)多了怕忘,留給自己以后看看。 1 修改 linux 系統(tǒng)參數(shù) Linux系統(tǒng)最大可打開文件數(shù)一般默認(rèn)的參數(shù)值是1024,如果你不進(jìn)行修改并發(fā)量上來(lái)的時(shí)候會(huì)出現(xiàn)“Too Many Open Files”的錯(cuò)誤,導(dǎo)致整個(gè)HBase不可運(yùn)行,你可以用ulimit -n 命令進(jìn)行修改,或者修改/etc/security/limits.conf 和/proc/sys/fs/file-max 的參數(shù),具體如何修改可以去Google 關(guān)鍵字 “l(fā)inux limits.conf ” 2 JVM 配置 修改 hbase-env.sh 文件中的配置參數(shù),根據(jù)你的機(jī)器硬件和當(dāng)前操作系統(tǒng)的JVM(32/64位)配置適當(dāng)?shù)膮?shù) HBASE_HEAPSIZE 4000 HBase使用的 JVM 堆的大小 HBASE_OPTS '‐server ‐XX: UseConcMarkSweepGC'JVM GC 選項(xiàng) HBASE_MANAGES_ZKfalse 是否使用Zookeeper進(jìn)行分布式管理 3 HBase持久化 重啟操作系統(tǒng)后HBase中數(shù)據(jù)全無(wú),你可以不做任何修改的情況下,創(chuàng)建一張表,寫一條數(shù)據(jù)進(jìn)行,然后將機(jī)器重啟,重啟后你再進(jìn)入HBase的shell中使用 list 命令查看當(dāng)前所存在的表,一個(gè)都沒有了。是不是很杯具?沒有關(guān)系你可以在hbase/conf/hbase-default.xml中設(shè)置hbase.rootdir的值,來(lái)設(shè)置文件的保存位置指定一個(gè)文件夾 ,例如:<value>file:///you/hbase-data/path</value>,你建立的HBase中的表和數(shù)據(jù)就直接寫到了你的磁盤上,如圖所示:
同樣你也可以指定你的分布式文件系統(tǒng)HDFS的路徑例如: hdfs://NAMENODE_SERVER:PORT/HBASE_ROOTDIR,這樣就寫到了你的分布式文件系統(tǒng)上了。 4 配置HBase運(yùn)行參數(shù) 其次就需要對(duì)hbase/conf/hbase-default.xml 文件進(jìn)行配置,以下是我認(rèn)為比較重要的配置參數(shù) hbase.client.write.buffer 描述:這個(gè)參數(shù)可以設(shè)置寫入數(shù)據(jù)緩沖區(qū)的大小,當(dāng)客戶端和服務(wù)器端傳輸數(shù)據(jù),服務(wù)器為了提高系統(tǒng)運(yùn)行性能開辟一個(gè)寫的緩沖區(qū)來(lái)處理它, 這個(gè)參數(shù)設(shè)置如果設(shè)置的大了,將會(huì)對(duì)系統(tǒng)的內(nèi)存有一定的要求,直接影響系統(tǒng)的性能。 hbase.master.meta.thread.rescanfrequency 描述:多長(zhǎng)時(shí)間 HMaster對(duì)系統(tǒng)表 root 和 meta 掃描一次,這個(gè)參數(shù)可以設(shè)置的長(zhǎng)一些,降低系統(tǒng)的能耗。 hbase.regionserver.handler.count 描述:由于HBase/Hadoop的Server是采用Multiplexed, non-blocking I/O方式而設(shè)計(jì)的,所以它可以透過(guò)一個(gè)Thread來(lái)完成處理,但是由于處理Client端所呼叫的方法是Blocking I/O,所以它的設(shè)計(jì)會(huì)將Client所傳遞過(guò)來(lái)的物件先放置在Queue,并在啟動(dòng)Server時(shí)就先產(chǎn)生一堆Handler(Thread),該Handler會(huì)透過(guò)Polling的方式來(lái)取得該物件并執(zhí)行對(duì)應(yīng)的方法,默認(rèn)為25,根據(jù)實(shí)際場(chǎng)景可以設(shè)置大一些。 hbase.regionserver.thread.splitcompactcheckfrequency 描述:這個(gè)參數(shù)是表示多久去RegionServer服務(wù)器運(yùn)行一次split/compaction的時(shí)間間隔,當(dāng)然split之前會(huì)先進(jìn)行一個(gè)compact操作.這個(gè)compact操作可能是minor compact也可能是major compact.compact后,會(huì)從所有的Store下的所有StoreFile文件最大的那個(gè)取midkey.這個(gè)midkey可能并不處于全部數(shù)據(jù)的mid中.一個(gè)row-key的下面的數(shù)據(jù)可能會(huì)跨不同的HRegion。 hbase.hregion.max.filesize 描述:HRegion中的HStoreFile最大值,任何表中的列族一旦超過(guò)這個(gè)大小將會(huì)被切分,而HStroeFile的默認(rèn)大小是256M。 hfile.block.cache.size 描述:指定 HFile/StoreFile 緩存在JVM堆中分配的百分比,默認(rèn)值是0.2,意思就是20%,而如果你設(shè)置成0,就表示對(duì)該選項(xiàng)屏蔽。 hbase.zookeeper.property.maxClientCnxns 描述: 這項(xiàng)配置的選項(xiàng)就是從zookeeper中來(lái)的,表示ZooKeeper客戶端同時(shí)訪問(wèn)的并發(fā)連接數(shù),ZooKeeper對(duì)于HBase來(lái)說(shuō)就是一個(gè)入口這個(gè)參數(shù)的值可以適當(dāng)放大些。 hbase.regionserver.global.memstore.upperLimit 描述:在Region Server中所有memstores占用堆的大小參數(shù)配置,默認(rèn)值是0.4,表示40%,如果設(shè)置為0,就是對(duì)選項(xiàng)進(jìn)行屏蔽。 hbase.hregion.memstore.flush.size 描述:Memstore中緩存的內(nèi)容超過(guò)配置的范圍后將會(huì)寫到磁盤上,例如:刪除操作是先寫入MemStore里做個(gè)標(biāo)記,指示那個(gè)value, column 或 family等下是要?jiǎng)h除的,HBase會(huì)定期對(duì)存儲(chǔ)文件做一個(gè)major compaction,在那時(shí)HBase會(huì)把MemStore刷入一個(gè)新的HFile存儲(chǔ)文件中。如果在一定時(shí)間范圍內(nèi)沒有做major compaction,而Memstore中超出的范圍就寫入磁盤上了。 5 HBase中l(wèi)og4j的日志 HBase中日志輸出等級(jí)默認(rèn)狀態(tài)下是把debug、 info 級(jí)別的日志打開的,可以根據(jù)自己的需要調(diào)整log級(jí)別,HBase的log4j日志配置文件在 hbase\conf\log4j.properties 目錄下。
在HBase中創(chuàng)建的一張表可以分布在多個(gè)Hregion,也就說(shuō)一張表可以被拆分成多塊,每一塊稱我們呼為一個(gè)Hregion。每個(gè)Hregion會(huì)保 存一個(gè)表里面某段連續(xù)的數(shù)據(jù),用戶創(chuàng)建的那個(gè)大表中的每個(gè)Hregion塊是由Hregion服務(wù)器提供維護(hù),訪問(wèn)Hregion塊是要通過(guò) Hregion服務(wù)器,而一個(gè)Hregion塊對(duì)應(yīng)一個(gè)Hregion服務(wù)器,一張完整的表可以保存在多個(gè)Hregion 上。HRegion Server 與Region的對(duì)應(yīng)關(guān)系是一對(duì)多的關(guān)系。每一個(gè)HRegion在物理上會(huì)被分為三個(gè)部分:Hmemcache(緩存)、Hlog(日志)、HStore(持久層)。 1.HRegionServer、HRegion、Hmemcache、Hlog、HStore之間的關(guān)系,如圖所示:
2.HBase表中的數(shù)據(jù)與HRegionServer的分布關(guān)系,如圖所示:
HBase讀數(shù)據(jù) HBase讀取數(shù)據(jù)優(yōu)先讀取HMemcache中的內(nèi)容,如果未取到再去讀取Hstore中的數(shù)據(jù),提高數(shù)據(jù)讀取的性能。 HBase寫數(shù)據(jù) HBase寫入數(shù)據(jù)會(huì)寫到HMemcache和Hlog中,HMemcache建立緩存,Hlog同步Hmemcache和Hstore的事務(wù)日志,發(fā)起Flush Cache時(shí),數(shù)據(jù)持久化到Hstore中,并清空HMemecache。 客戶端訪問(wèn)這些數(shù)據(jù)的時(shí)候通過(guò)Hmaster ,每個(gè) Hregion 服務(wù)器都會(huì)和Hmaster 服務(wù)器保持一個(gè)長(zhǎng)連接,Hmaster 是HBase分布式系統(tǒng)中的管理者,他的主要任務(wù)就是要告訴每個(gè)Hregion 服務(wù)器它要維護(hù)哪些Hregion。用戶的這些都數(shù)據(jù)可以保存在Hadoop 分布式文件系統(tǒng)上。 如果主服務(wù)器Hmaster死機(jī),那么整個(gè)系統(tǒng)都會(huì)無(wú)效。下面我會(huì)考慮如何解決Hmaster的SPFO的問(wèn)題,這個(gè)問(wèn)題有點(diǎn)類似Hadoop的SPFO 問(wèn)題一樣只有一個(gè)NameNode維護(hù)全局的DataNode,HDFS一旦死機(jī)全部掛了,也有人說(shuō)采用Heartbeat來(lái)解決這個(gè)問(wèn)題,但我總想找出 其他的解決方案,多點(diǎn)時(shí)間,總有辦法的。 昨天在hadoop-0.21.0、hbase-0.20.6的環(huán)境中折騰了很久,一直報(bào)錯(cuò),錯(cuò)誤信息如下:
死活連接不上HDFS,也無(wú)法連接HMaster,郁悶啊。 我想想啊,慢慢想,我眼前一亮 java.io.EOFException 這個(gè)異常,是不是有可能是RPC 協(xié)定格式不一致導(dǎo)致的?也就是說(shuō)服務(wù)器端和客戶端的版本不一致的問(wèn)題?換了一個(gè)HDFS的服務(wù)器端以后,一切都好了,果然是版本的問(wèn)題,最后采用 hadoop-0.20.2 搭配hbase-0.20.6 比較穩(wěn)當(dāng)。 最后的效果如圖所示:
上圖的一些文字說(shuō)明:
在上一篇關(guān)于HBase的文章中曾經(jīng)講述過(guò)HBase在分布式中的架構(gòu),這篇文章將會(huì)講述HBase在分布式環(huán)境中是如何排除單點(diǎn)故障的(SPFO),做一個(gè)小實(shí)驗(yàn)講述HBase在分布式環(huán)境中的高可用性,親眼看到一些現(xiàn)象,延伸一些思考的話題。 先來(lái)回顧一下HBase主要部件:
HBaseMaster HMaster 負(fù)責(zé)給HRegionServer分配區(qū)域,并且負(fù)責(zé)對(duì)集群環(huán)境中的HReginServer進(jìn)行負(fù)載均衡,HMaster還負(fù)責(zé)監(jiān)控集群環(huán)境中的HReginServer的運(yùn)行狀況,如果某一臺(tái)HReginServer down機(jī),HBaseMaster將會(huì)把不可用的HReginServer來(lái)提供服務(wù)的HLog和表進(jìn)行重新分配轉(zhuǎn)交給其他HReginServer來(lái)提供,HBaseMaster還負(fù)責(zé)對(duì)數(shù)據(jù)和表進(jìn)行管理,處理表結(jié)構(gòu)和表中數(shù)據(jù)的變更,因?yàn)樵?META 系統(tǒng)表中存儲(chǔ)了所有的相關(guān)表信息。并且HMaster實(shí)現(xiàn)了ZooKeeper的Watcher接口可以和zookeeper集群交互。 HRegionServer HReginServer負(fù)責(zé)處理用戶的讀和寫的操作。HReginServer通過(guò)與HBaseMaster通信獲取自己需要服務(wù)的數(shù)據(jù)表,并向HMaster反饋?zhàn)约旱倪\(yùn)行狀況。當(dāng)一個(gè)寫的請(qǐng)求到來(lái)的時(shí)候,它首先會(huì)寫到一個(gè)叫做HLog的write-ahead log中。HLog被緩存在內(nèi)存中,稱為Memcache,每一個(gè)HStore只能有一個(gè)Memcache。當(dāng)Memcache到達(dá)配置的大小以后,將會(huì)創(chuàng)建一個(gè)MapFile,將其寫到磁盤中去。這將減少HReginServer的內(nèi)存壓力。當(dāng)一起讀取的請(qǐng)求到來(lái)的時(shí)候,HReginServer會(huì)先在Memcache中尋找該數(shù)據(jù),當(dāng)找不到的時(shí)候,才會(huì)去在MapFiles 中尋找。 HBase Client HBase Client負(fù)責(zé)尋找提供需求數(shù)據(jù)的HReginServer。在這個(gè)過(guò)程中,HBase Client將首先與HMaster通信,找到ROOT區(qū)域。這個(gè)操作是Client和Master之間僅有的通信操作。一旦ROOT區(qū)域被找到以后,Client就可以通過(guò)掃描ROOT區(qū)域找到相應(yīng)的META區(qū)域去定位實(shí)際提供數(shù)據(jù)的HReginServer。當(dāng)定位到提供數(shù)據(jù)的HReginServer以后,Client就可以通過(guò)這個(gè)HReginServer找到需要的數(shù)據(jù)了。這些信息將會(huì)被Client緩存起來(lái),當(dāng)下次請(qǐng)求的時(shí)候,就不需要走上面的這個(gè)流程了。 HBase服務(wù)接口 HBase Thrift Server和HBase REST Server是通過(guò)非Java程序?qū)Base進(jìn)行訪問(wèn)的一種途徑。 進(jìn)入正題
先來(lái)看一個(gè)HBase集群的模擬環(huán)境,此環(huán)境中一共有4臺(tái)機(jī)器,分別包含 zookeeper、HBaseMaster、HReginServer、HDSF 4個(gè)服務(wù),為了展示失效轉(zhuǎn)發(fā)的效果HBaseMaster、HReginServer各有2臺(tái),只是在一臺(tái)機(jī)器上即運(yùn)行了HBaseMaster,也運(yùn)行了HReginServer。 服務(wù)器清單如下:
整個(gè)模擬環(huán)境的架構(gòu)如圖所示:
注意,這里只是做了一個(gè)模擬環(huán)境,因?yàn)檫@個(gè)環(huán)境的重點(diǎn)是HBase,所以zookeeper和HDFS服務(wù)都是單臺(tái)。 雖然說(shuō)在整個(gè)HBase的集群環(huán)境中只能有一個(gè)HMaster,可是在集群環(huán)境中HMaster可以啟動(dòng)多個(gè),但真正使用到的HMaster Server只有一個(gè),他不down掉的時(shí)候,其他啟動(dòng)的HMaster Server并不會(huì)工作,直到與ZooKeeper服務(wù)器判斷與當(dāng)前運(yùn)行的HMaster通訊超時(shí),認(rèn)為這個(gè)正在運(yùn)行的HMaster服務(wù)器down掉了,Zookeeper才會(huì)去連接下一臺(tái)HMaster Server。 簡(jiǎn)單來(lái)說(shuō),如果運(yùn)行中HMaster服務(wù)器down掉了,那么zookeeper會(huì)從列表中選擇下一個(gè)HMaster 服務(wù)器進(jìn)行訪問(wèn),讓他接管down掉的HMaster任務(wù),換而言之,用Java客戶端對(duì)HBase進(jìn)行操作是通過(guò)ZooKeeper的,也就是說(shuō)如果zookeeper集群中的節(jié)點(diǎn)全掛了 那么HBase的集群也掛了。本身HBase并不存儲(chǔ)中的任何數(shù)據(jù) 真正的數(shù)據(jù)是保存在HDFS上,所以HBase的數(shù)據(jù)是一致的,但是HDFS文件系統(tǒng)掛了,HBase的集群也掛。 在一臺(tái)HMaster失敗后,客戶端對(duì)HBase集群環(huán)境訪問(wèn)時(shí),客戶端先會(huì)通過(guò)zookeeper識(shí)別到HMaster運(yùn)行異常,直到確認(rèn)多次后,才連接到下一個(gè)HMaster,此時(shí),備份的HMaster服務(wù)才生效,在IDE環(huán)境中的效果,如圖所示:
上圖中能看見拋出的一些異常和name:javahttp://www.和name:javahttp://www.1的結(jié)果集,因?yàn)槲以趕erv215機(jī)器上用killall java命令把 HMaster和HReginServer都關(guān)掉,并且立刻用Java客戶端對(duì)HBase的集群環(huán)境進(jìn)行訪問(wèn)有異常拋出,但是retry到一定次數(shù)后查詢出結(jié)果,前面已經(jīng)說(shuō)了訪問(wèn)HBase是通過(guò)zookeeper再和真正的數(shù)據(jù)打交道,也就是說(shuō)zookeeper接管了一個(gè)standby 的 HMaster,讓原先Standby的HMaster接替了失效的HMaster任務(wù),而被接管的HBaseMaster再對(duì)HReginServer的任務(wù)進(jìn)行分配,當(dāng) HReginServer失敗后zookeeper會(huì)通知 HMaster對(duì)HReginServer的任務(wù)進(jìn)行分配。這樣充分的說(shuō)明了HBase做到了實(shí)效轉(zhuǎn)發(fā)的功能。 如圖所示:
口水: 1、HBase的失效轉(zhuǎn)發(fā)的效率比較慢了,不指望能在1-2秒切換和恢復(fù)完畢,也許是我暫時(shí)沒有發(fā)現(xiàn)有什么參數(shù)可以提高失效轉(zhuǎn)發(fā)和恢復(fù)過(guò)程的速度,將來(lái)會(huì)繼續(xù)關(guān)注這個(gè)問(wèn)題。 2、在官方網(wǎng)站上看見HBase0.89.20100924的版本有篇講述關(guān)于數(shù)據(jù)同步的文章,我嘗試了一下在一臺(tái)機(jī)器上可以運(yùn)行所謂的HBase虛擬集群環(huán)境,但是切換到多臺(tái)機(jī)器的分布式環(huán)境中,單點(diǎn)失效轉(zhuǎn)發(fā)的速度很慢比HBase0.20.6還要慢,我又檢查了是否存在網(wǎng)絡(luò)的問(wèn)題,目前尚未找到正確的答案,對(duì)與HBase0.89.20100924 新版中的數(shù)據(jù)同步的原理,如圖所示:(更多信息)
我的廢話1: 任何一項(xiàng)新技術(shù)并非救命稻草,一抹一擦立馬藥到病除的百寶箱,并非使用Spring或者NOSQL的產(chǎn)品就神乎其神 五光十色,如果那樣基本是扯淡。同類 型產(chǎn)品中不管那種技術(shù)最終要達(dá)到的目的是一樣的,通過(guò)新的技術(shù)手段你往往可能避諱了當(dāng)前你所需要面對(duì)的問(wèn)題,但過(guò)后新的問(wèn)題又來(lái)了。也許回過(guò)頭來(lái)看看還不 如在原來(lái)的基礎(chǔ)上多動(dòng)動(dòng)腦筋 想想辦法 做些改良可以得到更高的回報(bào)。 傳統(tǒng)數(shù)據(jù)庫(kù)是以數(shù)據(jù)塊來(lái)存儲(chǔ)數(shù)據(jù),簡(jiǎn)單來(lái)說(shuō),你的表字段越多,占用的數(shù)據(jù)空間就越多,那么查詢有可能就要跨數(shù)據(jù)塊,將會(huì)導(dǎo)致查詢的速度變慢。在大型系統(tǒng)中一張表上百個(gè)字段,并且表中的數(shù)據(jù)上億條這是完全是有可能的。因此會(huì)帶來(lái)數(shù)據(jù)庫(kù)查詢的瓶頸。我們都知道一個(gè)常識(shí)數(shù)據(jù)庫(kù)中表記錄的多少對(duì)查詢的性能有非常大的影響,此時(shí)你很有可能想到分表、分庫(kù)的做法來(lái)分載數(shù)據(jù)庫(kù)運(yùn)算的壓力,那么又會(huì)帶來(lái)新的問(wèn)題,例如:分布式事務(wù)、全局唯一ID的生成、跨數(shù)據(jù)庫(kù)查詢 等,依舊會(huì)讓你面對(duì)棘手的問(wèn)題。如果打破這種按照行存儲(chǔ)的模式,采用一種基于列存儲(chǔ)的模式,對(duì)于大規(guī)模數(shù)據(jù)場(chǎng)景這樣情況有可能發(fā)生一些好轉(zhuǎn)。由于查詢中的選擇規(guī)則是通過(guò)列來(lái)定義的,因此整個(gè)數(shù)據(jù)庫(kù)是自動(dòng)索引化的。按列存儲(chǔ)每個(gè)字段的數(shù)據(jù)聚集存儲(chǔ), 可以動(dòng)態(tài)增加,并且列為空就不存儲(chǔ)數(shù)據(jù),節(jié)省存儲(chǔ)空間。 每個(gè)字段的數(shù)據(jù)按照聚集存儲(chǔ),能大大減少讀取的數(shù)據(jù)量,查詢時(shí)指哪打哪,來(lái)的更直接。無(wú)需考慮分庫(kù)、分表 Hbase將對(duì)存儲(chǔ)的數(shù)據(jù)自動(dòng)切分?jǐn)?shù)據(jù),并支持高并發(fā)讀寫操作,使得海量數(shù)據(jù)存儲(chǔ)自動(dòng)具有更強(qiáng)的擴(kuò)展性。 Java中的HashMap是Key/Value的結(jié)構(gòu),你也可以把HBase的數(shù)據(jù)結(jié)構(gòu)看做是一個(gè)Key/Value的體系,話說(shuō)HBase的區(qū)域由表名和行界定的。在HBase區(qū)域每一個(gè)'列族'都由一個(gè)名為HStore的對(duì)象管理。每個(gè)HStore由一個(gè)或多個(gè)MapFiles(Hadoop中的一個(gè)文件類型)組成。MapFiles的概念類似于Google的SSTable。 在Hbase里面有以下兩個(gè)主要的概念,Row key 和 Column Family,其次是Cell qualifier和Timestamp tuple,Column family我們通常稱之為“列族”,訪問(wèn)控制、磁盤和內(nèi)存的使用統(tǒng)計(jì)都是在列族層面進(jìn)行的。列族Column family是之前預(yù)先定義好的數(shù)據(jù)模型,每一個(gè)Column Family都可以根據(jù)“限定符”有多個(gè)column。在HBase每個(gè)cell存儲(chǔ)單元對(duì)同一份數(shù)據(jù)有多個(gè)版本,根據(jù)唯一的時(shí)間戳來(lái)區(qū)分每個(gè)版本之間的差異,最新的數(shù)據(jù)版本排在最前面 。 口水:Hbase將table水平劃分成N個(gè)Region,region按column family劃分成Store,每個(gè)store包括內(nèi)存中的memstore和持久化到disk上的HFile。
上述可能我表達(dá)的還不夠到位,下面來(lái)看一個(gè)實(shí)踐中的場(chǎng)景,將原來(lái)是存放在MySQL中Blog中的數(shù)據(jù)遷移到HBase中的過(guò)程:
遷移HBase中的表結(jié)構(gòu):
原來(lái)系統(tǒng)中有2張表blogtable和comment表,采用HBase后只有一張blogtable表,如果按照傳統(tǒng)的RDBMS的話,blogtable表中的列是固定的,比如schema 定義了Author,Title,URL,text等屬性,上線后表字段是不能動(dòng)態(tài)增加的。但是如果采用列存儲(chǔ)系統(tǒng),比如Hbase,那么我們可以定義blogtable表,然后定義info 列族,User的數(shù)據(jù)可以分為:info:title ,info:author ,info:url 等,如果后來(lái)你又想增加另外的屬性,這樣很方便只需要 info:xxx 就可以了。 對(duì)于Row key你可以理解row key為傳統(tǒng)RDBMS中的某一個(gè)行的主鍵,Hbase是不支持條件查詢以及Order by等查詢,因此Row key的設(shè)計(jì)就要根據(jù)你系統(tǒng)的查詢需求來(lái)設(shè)計(jì)了額。 Hbase中的記錄是按照rowkey來(lái)排序的,這樣就使得查詢變得非???。 具體操作過(guò)程如下:
HBase的數(shù)據(jù)查詢\讀取,可以通過(guò)單個(gè)row key訪問(wèn),row key的range和全表掃描,大致如下: scan 'blogtable' ,{COLUMNS => ['text:','info:title'] } —> 列出 文章的內(nèi)容和標(biāo)題 scan 'blogtable' , {COLUMNS => 'info:url' , STARTROW => '2'} —> 根據(jù)范圍列出 文章的內(nèi)容和標(biāo)題 get 'blogtable','1' —> 列出 文章id 等于1的數(shù)據(jù) get 'blogtable','1', {COLUMN => 'info'} —> 列出 文章id 等于1 的 info 的頭(Head)內(nèi)容 get 'blogtable','1', {COLUMN => 'text'} —> 列出 文章id 等于1 的 text 的具體(Body)內(nèi)容 get 'blogtable','1', {COLUMN => ['text','info:author']} —> 列出 文章id 等于1 的內(nèi)容和作者(Body/Author)內(nèi)容 我的廢話2: 有人會(huì)問(wèn)Java Web服務(wù)器中是Tomcat快還是GlassFish快?小型數(shù)據(jù)庫(kù)中是MySQL效率高還是MS-SQL效率高?我看是關(guān)鍵用在什么場(chǎng)景和怎么使用這 個(gè)產(chǎn)品(技術(shù)),所以我漸漸的認(rèn)為是需要對(duì)產(chǎn)品、技術(shù)本身深入的了解,而并非一項(xiàng)新的技術(shù)就是絕佳的選擇。試問(wèn):Tomcat的默認(rèn)的運(yùn)行參數(shù)能和我們線 上正在使用的GlassFish性能相提并論嗎?我不相信GlassFishv2和GlassFishv3在默認(rèn)的配置參數(shù)下有顯著的差別。我們需要對(duì)產(chǎn) 品本身做到深入的了解才能發(fā)揮他最高的性能,而并非感觀聽從廠家的廣告和自己的感性認(rèn)識(shí) 迷信哪個(gè)產(chǎn)品的優(yōu)越性。 我的廢話3: 對(duì)于NOSQL這樣的新技術(shù),的的確確是可以解決過(guò)去我們所需要面對(duì)的問(wèn)題,但也并非適合每個(gè)應(yīng)用場(chǎng)景,所以在使用新產(chǎn)品的同時(shí)需要切合當(dāng)前的產(chǎn)品需要, 是需求在引導(dǎo)新技術(shù)的投入,而并非為了趕時(shí)髦去使用他。你的產(chǎn)品是否過(guò)硬不是你使用了什么新技術(shù),用戶關(guān)心的是速度和穩(wěn)定性,不會(huì)關(guān)心你是否使用了 NOSQL。相反Google有著超大的數(shù)據(jù)量,能給全世界用戶帶來(lái)了驚人的速度和準(zhǔn)確性,大家才會(huì)回過(guò)頭來(lái)好奇Google到底是怎么做到的。所以根據(jù) 自己的需要千萬(wàn)別太勉強(qiáng)自己使用了某項(xiàng)新技術(shù)。 我的廢話4: 總之一句話,用什么不是最關(guān)鍵,最關(guān)鍵是怎么去使用! 我的廢話: 大年三十夜,看春晚實(shí)在是太無(wú)聊了,整個(gè)《新聞聯(lián)播》的電視劇版本,還不如上上網(wǎng),看看資料,喝喝老酒,寫點(diǎn)東西來(lái)的快活。 近2年來(lái)云計(jì)算的話題到目前為止風(fēng)風(fēng)火火從來(lái)沒有平靜過(guò),一直是大家嘴邊討論的熱門話題,人們期望運(yùn)用云計(jì)算提供可靠、穩(wěn)定、高速的計(jì)算,在云計(jì)算中Google是目前最大的云計(jì)算供應(yīng)商,例如:Google GAE(Google App Engine)和Google的Docs在線文章服務(wù),這些SaaS上線產(chǎn)品的數(shù)據(jù)存儲(chǔ)(datastore)是由BigTable提供存儲(chǔ)服務(wù)的,在次之前我提到過(guò)Yahoo貢獻(xiàn)給Apache的那些山寨版本(Google與Yahoo的那些利器),其中Apache的HBase就是山寨了Google的BigTable。 我們知道在云計(jì)算的技術(shù)話題中Apache的Hadoop項(xiàng)目是一塊基石,利用Hadoop項(xiàng)目中的產(chǎn)品可以建立云計(jì)算平臺(tái)和超大型的計(jì)算。不知道你是否有想過(guò)如果將HBase作為Google GAE上的數(shù)據(jù)存儲(chǔ)(datastore),那么每個(gè)用戶之間的數(shù)據(jù)訪問(wèn)權(quán)限怎么辦?如果使用HBase提供對(duì)大客戶提供“私有云”(private cloud)或者另一種可能一個(gè)公司內(nèi)部的集群上運(yùn)行HBase,公司的內(nèi)部可能有幾個(gè)部門,某幾個(gè)部門之間的數(shù)據(jù)都是獨(dú)立分離但又運(yùn)行在一個(gè)平臺(tái)上,那么你就會(huì)發(fā)現(xiàn)HBase不具備這樣的功能,貌似目前HBase的最高版本0.90.0還沒有這樣的功能對(duì)用戶的表、Row、Cell的訪問(wèn)權(quán)限。但是我們知道Google的GAE上每個(gè)用戶訪問(wèn)的數(shù)據(jù)肯定是有權(quán)限劃分的,不然我只要有權(quán)限登錄GEA就能看見所有用戶存放的數(shù)據(jù)了。這樣的問(wèn)題你有可能沒有想過(guò),但趨勢(shì)公司的工程師們卻為此想到了這點(diǎn),并且把他們的設(shè)想和設(shè)計(jì)提交了HBase項(xiàng)目組,并且提出了以下主要的設(shè)計(jì)思想:
對(duì)HBase中的表和數(shù)據(jù)劃分權(quán)限等級(jí)和身份驗(yàn)證后,操作權(quán)限被分為3大類,每類中包含的操作權(quán)限如下所示:
對(duì)于方案中涉及到存儲(chǔ)的權(quán)限的是指整個(gè)表或表中的列族,也就是說(shuō)只考慮在表這個(gè)級(jí)別的權(quán)限,表與表之間的所屬關(guān)系是存放在 .META. 系統(tǒng)表中,以regioninfo:owner 的格式進(jìn)行存放,例如:系統(tǒng)中table1這個(gè)表是有權(quán)限的,這個(gè)表權(quán)限的存根保存在3個(gè)地方 :
如圖所示,圖中的箭頭表示了數(shù)據(jù)流向的順序:
方案中HBase在分布式、集群環(huán)境下,而權(quán)限一致性的問(wèn)題交給了Zookeeper來(lái)處理,在多個(gè)regionservers中,每個(gè)服務(wù)器的HRegion中存放著多個(gè)表,并且實(shí)現(xiàn)了(implement)ZKPermissionWatcher接口的nodeCreated() 和 nodeChanged() 方法,這2個(gè)方法對(duì)Zookeeper 的節(jié)點(diǎn)進(jìn)行監(jiān)控, 節(jié)點(diǎn)的狀態(tài)發(fā)生相應(yīng)的變化時(shí)會(huì)ZooKeeper刷新鏡像中的權(quán)限。 如圖所示:
HBase的這一關(guān)于權(quán)限的功能正在設(shè)計(jì)和研討當(dāng)中,讓我們繼續(xù)對(duì)他保持關(guān)注,看看今后將會(huì)發(fā)生的變化能給我們帶來(lái)什么樣的效果,非常期待這個(gè)功能早日正式發(fā)布。
轉(zhuǎn)自:作者:奧特man,發(fā)布于2012-12-14,來(lái)源:CSDN |
|
來(lái)自: Levy_X > 《JAVAWEB學(xué)習(xí)資料》