1. 如果有幾百億條數據,如何在hbase表中存放
1、首先你有沒有那麼多台伺服器的集群,如果只是幾台,你要想夠不夠,你的hbase 有幾百億,那麼你hdfs上的數據可能要有兩個備份,你這幾百億條是如何生成的,肯定是maprece跑出來導入到hbase中把,那麼原始數據你要不要留,如果留,加上備份就要三份,所以節點的多少要確定。
2、幾百億其實挺多的,hbase 的設計一定要跟你的業務相關,hbase他不能完全像關系型資料庫那樣去隨意查詢,到達一定量級,如果設計的不好也是非常之慢的,甚至將hbase搞到崩潰。所以你先去網上看看rowkey的設計原則,比如長度原則等等,然後根據自己業務,哪些查詢經常用到,哪些不會用到,想要用hbase實現那種非常靈活的類似關系資料庫的查詢是不理智的。
3、樓上的兄弟說得對,還有region熱點的問題,如果你的hbase數據不是那種每天增量的數據,建議跑個maprece對你的數據進行各評判,看看如何能將數據盡可能均勻的分配到每個region中,當然這需要預先分配region
4、幾百億條數據,如果對rowkey進行模糊過濾一定非常非常之慢,所以可以考慮二級索引或者協處理器
2. hbase資料庫是關系型資料庫嗎
Hive 存儲格式和關系型資料庫之間進行導入導出
最近更新時間:2020-09-29 15:54:18
前往 GitHub 編輯
1. 開發准備
2. 將關系型資料庫導入到 Hive 中
3. 將 Hive 導入到關系型資料庫中
使用 HDFS 中的 Hive 數據
使用 Hcatalog 進行導入
4. 將 orc 格式的 Hive 表格導入到關系型資料庫中
確認已開通騰訊雲,並且創建了一個 EMR 集群。在創建 EMR 集群的時候需要在軟體配置界面選擇 Sqoop,Hive 組件。
Sqoop 等相關軟體安裝在路徑 EMR 雲伺服器的/usr/local/service/路徑下。
- [root@172 ~]# su hadoop[hadoop@172 ~]# cd /usr/local/service/hive
- [hadoop@172 hive]$ hive
- hive> create database hive_from_sqoop;
- OK
- Time taken: 0.167 seconds
- [hadoop@172 hive]# cd /usr/local/service/sqoop
- [hadoop@172 sqoop]$ bin/sqoop-import --connect jdbc:mysql://$mysqlIP/test --username root -P --table sqoop_test_back --hive-database hive_from_sqoop --hive-import --hive-table hive_from_sqoop
$mysqlIP:騰訊雲關系型資料庫(CDB)的內網地址。
test:MySQL 資料庫名稱。
--table:要導出的 MySQL 表名。
--hive-database:Hive 資料庫名。
--hive-table:導入的 Hive 表名。
- hive> select * from hive_from_sqoop;OK1 first 2018-07-03 16:07:46.0 spark2 second 2018-07-03 15:30:57.0 mr3 third 2018-07-03 15:31:07.0 yarn4 forth 2018-07-03 15:39:38.0 hbase5 fifth 2018-07-03 16:02:29.0 hive6 sixth 2018-07-03 16:09:58.0 sqoopTime taken: 1.245 seconds, Fetched: 6 row(s)
- [root@172 ~]# su hadoop[hadoop@172 ~]# cd /usr/local/service/hive
- #!/bin/bashMAXROW=1000000 #指定生成數據行數for((i = 0; i < $MAXROW; i++))doecho $RANDOM, "$RANDOM"done
- [hadoop@172 hive]$ ./gen_data.sh > hive_test.data
- [hadoop@172 hive]$ hdfs dfs -put ./hive_test.data /$hdfspath
- [hadoop@172 hive]$ bin/hivehive> create database hive_to_sqoop; #創建資料庫 hive_to_sqoopOK
- Time taken: 0.176 secondshive> use hive_to_sqoop; #切換資料庫OK
- Time taken: 0.176 secondshive> create table hive_test (a int, b string)hive> ROW FORMAT DELIMITED FIELDS TERMINATED BY ',';#創建數據表 hive_test, 並指定列分割符為』,』
- OK
- Time taken: 0.204 secondshive> load data inpath "/$hdfspath/hive_test.data" into table hive_test; #導入數據
- [hadoop@172 hive]$ mysql -h $mysqlIP –p
- Enter password:
- mysql> create table table_from_hive (a int,b varchar(255));
- [hadoop@172 hive]$ cd ../sqoop/bin
- [hadoop@172 bin]$ ./sqoop-export --connect jdbc:mysql://$mysqlIP/test --username root -P
- --table table_from_hive --export-dir /usr/hive/warehouse/hive_to_sqoop.db/hive_test
- [hadoop@172 hive]$ cd ../sqoop/bin
- [hadoop@172 bin]$ ./sqoop-export --connect jdbc:mysql://$mysqlIP/test --username root -P
- --table table_from_hive --hcatalog-database hive_to_sqoop --hcatalog-table hive_test
- [hadoop@172 hive]$ mysql -h $mysqlIP –p #連接 MySQLEnter password:mysql> use test;
- Database changed
- mysql> select count(*) from table_from_hive; #現在表中有1000000條數據+----------+| count(*) |+----------+| 1000000 |+----------+1 row in set (0.03 sec)
- mysql> select * from table_from_hive limit 10; #查看錶中前10條記錄+-------+----------+| a | b |
- +-------+----------+
- | 28523 | "3394" || 31065 | "24583" |
- | 399 | "23629" || 18779 | "8377" |
- | 25376 | "30798" || 20234 | "22048" |
- | 30744 | "32753" || 21423 | "6117" |
- | 26867 | "16787" || 18526 | "5856" |
- +-------+----------+
- 10 rows in set (0.00 sec)
- [hadoop@172 bin]$ ./sqoop-export --help
我的收藏
本頁目錄:
本文介紹了使用騰訊雲 Sqoop 服務將數據在 Mysql 和 Hive 之間相互導入導出的方法。
1. 開發准備
2. 將關系型資料庫導入到 Hive 中
本節將繼續使用上一節的用例。
進入 EMR 控制台,復制目標集群的實例 ID,即集群的名字。再進入關系型資料庫控制台,使用 Ctrl+F 進行搜索,找到集群對應的 MySQL 資料庫,查看該資料庫的內網地址 $mysqlIP。
登錄 EMR 集群中的任意機器,最好是登錄到 Master 節點。登錄 EMR 的方式請參考登錄 Linux 實例。這里我們可以選擇使用 WebShell 登錄。單擊對應雲伺服器右側的登錄,進入登錄界面,用戶名默認為 root,密碼為創建 EMR 時用戶自己輸入的密碼。輸入正確後,即可進入命令行界面。
在 EMR 命令行先使用以下指令切換到 Hadoop 用戶,並進入 Hive 文件夾:
新建一個 Hive 資料庫:
使用 sqoop-import 命令把上一節中創建的 MySQL 資料庫導入到 Hive 中:
執行指令需要輸入您的 MySQL 密碼,默認為您創建 EMR 集群時設置的密碼。執行成功後,可以在 Hive 中查看導入的資料庫:
3. 將 Hive 導入到關系型資料庫中
Sqoop 支持將 Hive 表中的數據導入到關系型資料庫中。先在 Hive 中創建新表並導入數據。
登錄 EMR 集群中的任意機器,最好是登錄到 Master 節點。在 EMR 命令行先使用以下指令切換到 Hadoop 用戶,並進入 Hive 文件夾:
新建一個 bash 腳本文件 gen_data.sh,在其中添加以下代碼:
並按如下方式執行:
這個腳本文件會生成1,000,000個隨機數對,並且保存到文件 hive_test.data 中。
使用如下指令把生成的測試數據先上傳到 HDFS 中:
其中 $hdfspath 為 HDFS 上的您存放文件的路徑。
連接 Hive 並創建測試表:
$hdfspath 為 HDFS 上的您存放文件的路徑。
成功後可使用quit命令退出 Hive 數據倉庫。連接關系型資料庫並創建對應的表格:
其中 $mysqlIP 為該資料庫的內網地址,密碼為您創建集群時設置的密碼。
在 MySQL 中創建一個名為 test 的表格,MySQL 中的表欄位名字和 Hive 中的表欄位名字必須完全一致:
成功創建表格後即可退出 MySQL。
使用 Sqoop 把 Hive 數據倉庫中的數據導入到關系型資料庫中有兩種方法,可以直接使用 HDFS 存儲的 Hive 數據,也可以使用 Hcatalog 來進行數據的導入。
使用 HDFS 中的 Hive 數據
切換進入 Sqoop 文件夾,然後使用以下指令把 Hive 資料庫中的數據導出到關系型資料庫中:
其中 $mysqlIP 為您的關系型資料庫的內網 IP 地址,test 為關系型資料庫中的資料庫名,--table 後跟的參數為您的關系型資料庫的表名,--export-dir 後跟的參數為 Hive 表中的數據在 HDFS 中存儲的位置。
使用 Hcatalog 進行導入
切換進入 Sqoop 文件夾,然後使用以下指令把 Hive 資料庫中的數據導出到關系型資料庫中:
其中 $mysqlIP 為您的關系型資料庫的內網 IP 地址,test 為關系型資料庫中的資料庫名,--table 後跟的參數為您的關系型資料庫的表名,--hcatalog-database 後面跟的參數是要導出的 Hive 表所在的資料庫的名稱,--hcatalog-table 後面跟的參數是要 Hive 中要導出的表的名稱。
操作完成後可以進入關系型資料庫查看是否導入成功:
更多關於 sqoop-export 命令的參數可以通過如下命令查看:
4. 將 orc 格式的 Hive 表格導入到關系型資料庫中
3. 北大青鳥java培訓:Hbase知識點總結
hbase概念:非結構化的分布式的面向列存儲非關系型的慧羨開源的資料庫,根據谷歌的三大論文之一的bigtable高寬厚表作用:為了解決大規模數據集合多重數據種類帶來的挑戰,尤其是大數據應用難題。
能幹什麼:存儲大量結果集數據,低延遲的隨機查詢。
sql:結構化查詢語言nosql:非關系型資料庫,列存儲和文檔存儲(查詢低延遲),hbase是nosql的一個種類,其特點是列式存儲。
非關系型資料庫--列存儲(hbase)非關系型資料庫--文檔存儲(MongoDB)非關系型資料庫--內存式存儲(redis)非關系型資料庫--圖形模型(graph)hive和hbase區別?Hive的定位是數據倉庫,雖然也有增刪改查,但其刪改查對應的是整張表而不是單行數據,查詢的延遲較高。
其本質是更加方便的使用mr的威力來進行離線分析的一個數據分析工具。
HBase的定位是hadoop的資料庫,電腦培訓http://www.kmbdqn.cn/發現是一個典型的Nosql,所以HBase是用來在大量數據中進行低延遲的隨機查詢的。
hbase運行方式:standalonedistrubited單節點和偽分布式?單節點:單獨的進程運行在同一台機器前慧拍上hbase應用場景:碧首存儲海量數據低延遲查詢數據hbase表由多行組成hbase行一行在hbase中由行健和一個或多個列的值組成,按行健字母順序排序的存儲。
4. HBase從入門到精通11:HBase數據保存過程和Region分裂
本節來介紹一下HBase的數據保存過程和Region分裂過程的相關知識。
HBase中表的數據是存儲在RegionServer上的一個個Region中的,表的一個列族對應於一個Region。Region是按照數據行鍵Rowkey的字典序來存儲數據的。假如我們有一張表Bigdata,該表有一個列族Info,該列族下有一個列Name,且為了便於說明,假設行鍵和Name相同,按照行鍵字典序保存數據的過程如下圖所示:
HBase保存數據的流程有以下幾個步驟:
HBase表的列族在創建之初只有一個Region,隨著插入數據的增多Region變得越來越大。過大的Region使得查詢效率降低,因此當Region的大小超過某一閾值時,HBase將執行Region的分裂操作:即將一個大Region拆分成兩個相等規模的小Region。具體的Region分裂過程如下圖所示:
HBase的Region分裂過程需要注意以下幾個問題:
雖然Region分裂後可以提高HBase的讀寫性能,但是Region分裂過程會對集群網路造成很大的壓力,尤其是要分裂的Region尺寸過大、數目過多時,甚至可以使整個集群癱瘓。例如,當年京東的Region分裂事件,造成整個集群癱瘓9個小時以上,無法對外提供服務,經濟損失可想而知。
因此,應該根據實際需求將Region分裂的閾值設置的合理一些,太小會頻繁觸發分裂,太大分裂時會對網路傳輸造成一定的壓力。
5. hbase的作用
HBase 是典型的 NoSQL 資料庫,通常被描述成稀疏的、分布式的、持久化的,由行鍵、列鍵和時間戳進行索引的多維有序映射資料庫,主要用來存儲非結構化和半結構化的數據。因為 HBase 基於 Hadoop 的 HDFS 完成分布式存儲,以及 MapRece 完成分布式並行計算,所以它的一些特點與 Hadoop 相同,依靠橫向擴展,通過不斷增加性價比高的商業伺服器來增加計算和存儲能力。
HBase 雖然基於 Bigtable 的開源實現,但它們之間還是有很多差別的,Bigtable 經常被描述成鍵值資料庫,而 HBase 則是面向列存儲的分布式資料庫。
下面介紹 HBase 具備的顯著特性,這些特性讓 HBase 成為當前和未來最實用的資料庫之一。
容量巨大
HBase 的單表可以有百億行、百萬列,可以在橫向和縱向兩個維度插入數據,具有很大的彈性。
當關系型資料庫的單個表的記錄在億級時,查詢和寫入的性能都會呈現指數級下降,這種龐大的數據量對傳統資料庫來說是一種災難,而 HBase 在限定某個列的情況下對於單表存儲百億甚至更多的數據都沒有性能問題。
HBase 採用 LSM 樹作為內部數據存儲結構,這種結構會周期性地將較小文件合並成大文件,以減少對磁碟的訪問。
擴展性強
HBase 工作在 HDFS 之上,理所當然地支持分布式表,也繼承了 HDFS 的可擴展性。HBase 的擴展是橫向的,橫向擴展是指在擴展時不需要提升伺服器本身的性能,只需添加伺服器到現有集群即可。
HBase 表根據 Region 大小進行分區,分別存在集群中不同的節點上,當添加新的節點時,集群就重新調整,在新的節點啟動 HBase 伺服器,動態地實現擴展。這里需要指出,HBase 的擴展是熱擴展,即在不停止現有服務的前提下,可以隨時添加或者減少節點。
高可靠性
HBase 運行在 HDFS 上,HDFS 的多副本存儲可以讓它在岀現故障時自動恢復,同時 HBase 內部也提供 WAL 和 Replication 機制。
WAL(Write-Ahead-Log)預寫日誌是在 HBase 伺服器處理數據插入和刪除的過程中用來記錄操作內容的日誌,保證了數據寫入時不會因集群異常而導致寫入數據的丟失;而 Replication 機制是基於日誌操作來做數據同步的。
6. 計算機裡面Hbase作用是什麼
HBase是一個分布式的、面向列的開源資料庫,該技術來源於 Fay Chang 所撰寫的Google論文「Bigtable:一個結構化數據的分布式存儲系統」。就像Bigtable利用了Google文件系統(File System)所提供的分布式數據存儲一樣,HBase在Hadoop之上提供了類似於Bigtable的能力。HBase是Apache的Hadoop項目的子項目。HBase不同於一般的關系資料庫,它是一個適合於非結構化數據存儲的資料庫。另一個不同的是HBase基於列的而不是基於行的模式。
HBase – Hadoop Database,是一個高可靠性、高性能、面向列、可伸縮的分布式存儲系統,利用HBase技術可在廉價PC Server上搭建起大規模結構化存儲集群。
模型
主要討論邏輯模型和物理模型
(1)邏輯模型
Hbase的名字的來源是Hadoop database,即hadoop資料庫。
主要是從用戶角度來考慮,即如何使用Hbase。
(2)物理模型
主要從實現Hbase的角度來討論
HBase數據模型
邏輯結構
邏輯上,HBase 的數據模型同關系型資料庫很類似,數據存儲在一張表中,有行有列。但從 HBase 的底層物理存儲結構(K-V)來看,HBase 更像是一個 multi-dimensional map
7. hbase和關系型資料庫的區別
Mongodb用於存儲非結構化數據,尤其擅長存儲json格式的數據。存儲的量大概在10億級別,再往上性能就下降了,除非另外分庫。
Hbase是架構在hdfs上的列式存儲,擅長rowkey的快速查詢,但模糊匹配查詢(其實是前模糊或全模糊)不擅長,但存儲的量可以達到百億甚至以上,比mongodb的存儲量大多了。
8. 怎樣將關系型數據表轉換至hbase數據表
首先需要把關系型資料庫的數據表的數據增加由 「縱向延伸」,轉變為HBase數據表的「橫向延伸」
一、Hbase的存儲結構
a) HBase以表(HTable)的形式存儲數據
b) HTable包括很多行,每行通過RowKey唯一標記,行按照RowKey的字典序排列,表在行的方向上分割為多個HRegion
c) 每行包括一個RowKey和多個Column Family,數據按照Column Family進行物理切割,即不同Column Family的數據放在不同的Store中,一個Column Family放在一個Strore中
d) HRegion由多個Store組成。一個Store由物理上存在的一個MemStrore(內存中)和多個StoreFile(HFile)中
二、設計原則:
(1)rowkey
a) rowkey是hbase的key-value存儲中的key,通常使用用戶要查詢的欄位作為rowkey ,查詢結果作為value ,HBase中RowKey是按照字典序排列的
(2)Column Family的設計需遵循:
a) 不同Column Family的數據,在物理上是分開的,盡量避免一次請求需要拿到的Column分布在不同的Column Family中;
b) CF的數量盡量要少,原因是過多的columnfamily之間會互相影響
(3) column
對於column需要擴展的應用,column可以按普通的方式設計,但是對於列相對固定的應用,最好採用將一行記錄封裝到一個column中的方式,這樣能夠節省存儲空間。封裝的方式推薦protocolbuffer。
9. hbase 的數據存儲及Region變化(flush compaction spilt)和性能調優
1. 對表做預分區處理(即在建表時指定Region數量和拆分邊界);
2.配置hbase.hregion.max.filesize為50GB
以fileServer為例,在使用默認的split策略-- 的情況下,16個預分區Region, 則單個Resion容量達到 min(32,50),即32GB時分裂。
3.修改Linux最大文件句柄數
因為hbase是以文件的形式存儲數據,最大文件句柄數影響著hbase的並發量。
用root許可權修改/etc/security/limits.conf文件,增加以下內容(前面的*不能忽略):
* soft nproc 10240
* hard nproc 10240
* soft nofile 10240
* hard nofile 10240
編輯/etc/pam.d/common-session,加入一行
session required pam_limits.so
編輯/etc/profile,加入
ulimit -SHn 51200
重新登陸,生效
4.HRegionServer掛掉異常和解決:
is not online on......
常規解決方案:
刪除zk中hbase的緩存
重啟hbase
使用上述解決方案後本次異常依舊存在,並且HMaster和HRegionServer都不斷的自動掛掉。
HMaster報錯:
解決方案:
新增配置(看情況決定使用不使用,建議在HMaster不能啟動時排除錯誤使用)(讓啟動hbase時只讓HMaster去進行日誌split,缺點是恢復數據時候速度慢):
<property>
<name>hbase.master.distributed.log.splitting</name>
<value>false</value>
</property>
刪除WAL文件(會丟數據):
6. RPC請求的最大線程數
hbase.regionserver.handler.count 默認是10,在伺服器測試時建議設置到50(經測試在單個Region Server時無用,單個RegionServer 最多在6個線程put時保持穩定)
7.日誌分割(hbase出錯後恢復數據)
MemStore中大量更新丟失時,對數據進行恢復時會做日誌分割
hbase.regionserver.hlog.splitlog.writer.threads 日誌分割的線程數, 默認為3 ,建議設定為10
8.Region Server頻繁掉線
出現Hbase Region Server頻繁掉線的情況,表現為在多線程put的情況下,忽然Hbase Region Server掉線
猜測是GC或者split過程中沒有及時和ZK通信,導致與ZK連接時間超時,zk返回dead region到master,當Hbase Region恢復正常後,找不到wal,產生如下報錯。
zookeeper.session.timeout :默認值是3分鍾
但是 hbase regionserver和zookeeper的timeout不是單方面決定的,是取決於hbase的zookeeper.session.timeout和zookeeper的MaxSessionTimeout中的最小值
配置hbase:
zookeeper.session.timeout
600000
配置zookeeper:
tickTime=30000
9.內存及GC優化
在測試的過程中依舊出現Hbase Region Server掉線的情況,報錯如下
2021-02-0318:49:14,091INFO[sync.0]wal.FSHLog: Slow sync cost:1955ms, current pipeline: []
2021-02-0318:49:14,091WARN[regionserver/botsc/192.168.0.107:16020.append-pool5-t1]wal.MetricsWAL: regionserver/botsc/192.168.0.107:16020.append-pool5-t1 took1953ms appending an edit to wal; len~=109
2021-02-0318:49:14,106ERROR[sync.3]wal.FSHLog:Errorsyncing, request close of WAL
java.io .IOException:io.grpc.StatusRuntimeException: CANCELLED: Failed to stream message
at seaweed.hdfs.SeaweedOutputStream.(SeaweedOutputStream.java:78)
at seaweed.hdfs.SeaweedOutputStream.(SeaweedOutputStream.java:263)
at seaweed.hdfs.SeaweedOutputStream.flushInternalAsync(SeaweedOutputStream.java:243)
at seaweed.hdfs.SeaweedOutputStream.flush(SeaweedOutputStream.java:129)
at java.io .FilterOutputStream.flush(FilterOutputStream.java:140)
at java.io .DataOutputStream.flush(DataOutputStream.java:123)
at org.apache.hadoop.hbase.regionserver.wal.ProtobufLogWriter.sync(ProtobufLogWriter.java:170)
at org.apache.hadoop.hbase.regionserver.wal.FSHLog$SyncRunner.run(FSHLog.java:1286)
at java.lang.Thread.run(Thread.java:748)
修改hbase的配置文件hbase-env.sh,GC優化如下:
export HBASE_HEAPSIZE=21384
export master_heapsize=8292
export regionserver_heapsize=21384
export HBASE_OPTS="$HBASE_OPTS -XX:+UseConcMarkSweepGC -XX:=60 -XX:+UseParNewGC -XX:ParallelGCThreads=6"
export HBASE_MASTER_OPTS="$HBASE_MASTER_OPTS $HBASE_JMX_BASE -Xmx8g -Xms8g -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:=70"
export HBASE_REGIONSERVER_OPTS="$HBASE_REGIONSERVER_OPTS $HBASE_JMX_BASE -Xmx20g -Xms20g -Xmn1g -XX:+UseParNewGC
-XX:+UseConcMarkSweepGC -XX:=70"
10. HBase存儲架構
上圖是HBase的存儲架構圖。
由上圖可以知道,客戶端是通過Zookeeper找到HMaster,然後再與具體的Hregionserver進行溝通讀寫數據的。
具體到物理實現,細節包括以下這些:
首先要清楚HBase在hdfs中的存儲路徑,以及各個目錄的作用。在hbase-site.xml 文件中,配置項 <name> hbase.rootdir</name> 默認 「/hbase」,就是hbase在hdfs中的存儲根路徑。以下是hbase0.96版本的個路徑作用。1.0以後的版本請參考這里: https://blog.bcmeng.com/post/hbase-hdfs.html
1、 /hbase/.archive
HBase 在做 Split或者 compact 操作完成之後,會將 HFile 移到.archive 目錄中,然後將之前的 hfile 刪除掉,該目錄由 HMaster 上的一個定時任務定期去清理。
2、 /hbase/.corrupt
存儲HBase損壞的日誌文件,一般都是為空的。
3、 /hbase/.hbck
HBase 運維過程中偶爾會遇到元數據不一致的情況,這時候會用到提供的 hbck 工具去修復,修復過程中會使用該目錄作為臨時過度緩沖。
4、 /hbase/logs
HBase 是支持 WAL(Write Ahead Log) 的,HBase 會在第一次啟動之初會給每一台 RegionServer 在.log 下創建一個目錄,若客戶端如果開啟WAL 模式,會先將數據寫入一份到.log 下,當 RegionServer crash 或者目錄達到一定大小,會開啟 replay 模式,類似 MySQL 的 binlog。
5、 /hbase/oldlogs
當.logs 文件夾中的 HLog 沒用之後會 move 到.oldlogs 中,HMaster 會定期去清理。
6、 /hbase/.snapshot
hbase若開啟了 snapshot 功能之後,對某一個用戶表建立一個 snapshot 之後,snapshot 都存儲在該目錄下,如對表test 做了一個 名為sp_test 的snapshot,就會在/hbase/.snapshot/目錄下創建一個sp_test 文件夾,snapshot 之後的所有寫入都是記錄在這個 snapshot 之上。
7、 /hbase/.tmp
當對表做創建或者刪除操作的時候,會將表move 到該 tmp 目錄下,然後再去做處理操作。
8、 /hbase/hbase.id
它是一個文件,存儲集群唯一的 cluster id 號,是一個 uuid。
9、 /hbase/hbase.version
同樣也是一個文件,存儲集群的版本號,貌似是加密的,看不到,只能通過web-ui 才能正確顯示出來
10、 -ROOT-
該表是一張的HBase表,只是它存儲的是.META.表的信息。通過HFile文件的解析腳本 hbase org.apache.hadoop.hbase.io.hfile.HFile -e -p -f 可以查看其存儲的內容,如下所示:
以上可以看出,-ROOT-表記錄的.META.表的所在機器是dchbase2,與web界面看到的一致:
11、 .META.
通過以上表能找到.META.表的信息,該表也是一張hbase表,通過以上命令,解析其中一個region:
以上可以看出,adt_app_channel表的數據記錄在dchbase3這台reginserver上,也與界面一致,如果有多個region,則會在表名後面加上rowkey的范圍:
通過以上描述,只要找到-ROOT-表的信息,就能根據rowkey找到對應的數據,那-ROOT-在哪裡找呢?從本文一開始的圖中可以知道,就是在zookeeper中找的。進入zookeeper命令行界面:
可以看出-ROOT-表存儲在 dchbase3 機器中,對應界面如下:
以上就是HBase客戶端根據指定的rowkey從zookeeper開始找到對應的數據的過程。
那在Region下HBase是如何存儲數據的呢?
以下就具體操作一張表,查詢對應的HFile文件,看HBase的數據存儲過程。
在HBase創建一張表 test7,並插入一些數據,如下命令:
查看wal日誌,通過 hbase org.apache.hadoop.hbase.regionserver.wal.HLog --mp -p 命令可以解析HLog文件,內容如下:
查看HFile文件,內容如下:
由此可見,HFile文件就是存儲HBase的KV對,其中Key的各個欄位包含了的信息如下:
由於hbase把cf和column都存儲在HFile中,所以在設計的時候,這兩個欄位應該盡量短,以減少存儲空間。
但刪除一條記錄的時候,HBase會怎麼操作呢?執行以下命令:
刪除了rowkey為200的記錄,查看hdfs,原來的HFile並沒有改變,而是生成了一個新的HFile,內容如下:
所以在HBase中,刪除一條記錄並不是修改HFile裡面的內容,而是寫新的文件,待HBase做合並的時候,把這些文件合並成一個HFile,用時間比較新的文件覆蓋舊的文件。HBase這樣做的根本原因是,HDFS不支持修改文件。