hbase如何存儲
① 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"
② hbase與關系型資料庫的存儲方式有哪些不同
HBase與傳統關系資料庫的區別主要體現在以下幾個方面:1.數據類型。關系資料庫採用關系模型,具有豐富的數據類型和儲存方式。HBase則採用了更加簡單的數據模型,它把數據儲存為未經解釋的字元串,用戶可以把不同格式的結構化數據和非結構化數據都序列化成字元串保存到HBase中,用戶需要自己編寫程序把字元串解析成不同的數據類型。 2.數據操作。關系資料庫中包含了豐富的操作,如插入、刪除、更新、查詢等,其中會涉及復雜的多表連接,通常是藉助多個表之間的主外鍵關聯來實現的。HBase操作則不存在復雜的表與表之間的關系,只有簡單的插入、查詢、刪除、清空等,因為HBase在設計上就避免了復雜的表與表之。
列存儲不同於傳統的關系型資料庫,其數據在表中是按行存儲的,列方式所帶來的重要好處之一就是,由於查詢中的選擇規則是通過列來定義的,因此整個資料庫是自動索引化的。
按列存儲每個欄位的數據聚集存儲,在查詢只需要少數幾個欄位的時候,能大大減少讀取的數據量,一個欄位的數據聚集存儲,那就更容易為這種聚集存儲設計更好的壓縮/解壓演算法。
傳統的(Oracle)行存儲和(Hbase)列存儲的區別。
主要體現在以下幾個方面:1.數據類型。關系資料庫採用關系模型,具有豐富的數據類型和儲存方式。HBase則採用了更加簡單的數據模型,它把數據儲存為未經解釋的字元串,用戶可以把不同格式的結構化數據和非結構化數據都序列化成字元串保存到HBase中,用戶需要自己編寫程序把字元串解析成不同的數據類型。 2.數據操作。關系資料庫中包含了豐富的操作,如插入、刪除、更新、查詢等,其中會涉及復雜的多表連接,通常是藉助多個表之間的主外鍵關聯來實現的。HBase操作則不存在復雜的表與表之間的關系,只有簡單的插入、查詢、刪除、清空等,因為HBase在設計上就避免了復雜的表與表之間的關系,通常只採用單表的主鍵查詢。
③ hbase 如何存儲數據
HBASE中的表示按column family來存儲的
建立一個有3個column family的表
create 't1', {NAME => 'f1', VERSIONS => 1}, {NAME => 'f2', VERSIONS => 1}, {NAME => 'f3', VERSIONS => 1}
定義表的時候只需要指定column family的名字,列名在put的時候動態指定
插入數據
下面插入沒有指定column的名字
put 't1', 'r1', 'f1', 'v1'
put 't1', 'r2', 'f2', 'v2'
put 't1', 'r3', 'f3', 'v3'
下面插入指定column的名字
put 't1', 'r4', 'f1:c1', 'v1'
put 't1', 'r5', 'f2:c2', 'v2'
put 't1', 'r6', 'f3:c3', 'v3'
hbase(main):245:0> scan 't1'
ROW COLUMN+CELL
r1 column=f1:, timestamp=1335407967324, value=v1
r2 column=f2:, timestamp=1335408004559, value=v2
r4 column=f1:c1, timestamp=1335408640777, value=v1
r5 column=f2:c1, timestamp=1335408640822, value=v2
r6 column=f1:c6, timestamp=1335412392258, value=v3
r6 column=f2:c1, timestamp=1335412384739, value=v3
r6 column=f2:c2, timestamp=1335412374797, value=v3
插入多列的數據
put 't1', 'r7', 'f1:c4', 'v9'
put 't1', 'r7', 'f2:c3', 'v9'
put 't1', 'r7', 'f3:c2', 'v9'
手工把memstore寫到Hfile中
flush 't1'
刪除所有CF3的數據
deleteall 't1','r7'
flush 't1'
每次flash都會建一個新的hfile
$ ../bin/hadoop dfs -lsr /hbase/t1
數據時直接存到CF目錄下的,每個CF目錄下有3到4個Hfile
f1
f1/
f1/321c683f48dd91e058179486587e
f1/
f2
f2/
f2/
f2/
f3
f3/
f3/
f3/
f3/
f3都數據雖然都被刪除了,由於沒有合並文件都存在
手工合並hfile
hbase(main):244:0> compact 't1'
0 row(s) in 0.0550 seconds
$ ../bin/hadoop dfs -lsr /hbase/t1
f1
f1/
f2
f2/
/f3
f1和f2下就只有一個hfile,f3下面沒有hfile因為數據都被刪除了
一次只能put一個column
一次只能delete一個column
刪除整行,用deleteall
deleteall 't1', 'r1'
了解更多開源相關,去LUPA社區看看吧。