設(shè)計(jì)周關(guān)鍵詞優(yōu)化排名seo
在數(shù)據(jù)存儲(chǔ)和處理領(lǐng)域,HBase作為一種分布式、可擴(kuò)展的NoSQL數(shù)據(jù)庫(kù),被廣泛應(yīng)用于大規(guī)模數(shù)據(jù)的存儲(chǔ)和分析。然而,隨著業(yè)務(wù)需求的變化和技術(shù)發(fā)展的進(jìn)步,有時(shí)候我們需要將現(xiàn)有的HBase數(shù)據(jù)遷移到其他環(huán)境或存儲(chǔ)系統(tǒng)。HBase數(shù)據(jù)遷移是一個(gè)復(fù)雜而關(guān)鍵的任務(wù),它涉及到保證數(shù)據(jù)完整性、準(zhǔn)確性和安全性,同時(shí)還需要考慮版本兼容性、網(wǎng)絡(luò)帶寬、數(shù)據(jù)量等因素。從Hbase 本身的設(shè)計(jì)架構(gòu)上可以知道 hbase的表是基于 hadoop HDFS 構(gòu)建,所以一般在遷移Hbase 表數(shù)據(jù)的時(shí)候需要關(guān)注到兩個(gè)維度,hbase層和hdfs層,下圖包含常見(jiàn)的一些遷移工具和手段。?
在不同的適用場(chǎng)景下,對(duì)于hbase 的遷移是需要采用不同的方式的,下面推薦使用基于 Snapshot 遷移和利用hive外表關(guān)聯(lián)hbase遷移;
1.基于 Snapshot 遷移具體實(shí)施步驟
第一步:需要在源集群中執(zhí)行創(chuàng)建表的快照
snapshot 'poi_geohash','snapshot_poi_geohash'
此時(shí)生成的快照是存儲(chǔ)在hdfs上的,下面一步需要hbase 的快照同步工具,將表的快照同步到新的hbase集群中;
第二步:同步快照文件?
hbase org.apache.hadoop.hbase.snapshot.ExportSnapshot -snapshot snapshot_poi_geohash -copy-from hdfs://${old_namenoe_ip}:8020/hbase -copy-to hdfs://${new_namenoe_ip}:8020/hbase -mappers 30 -bandwidth 8192
參數(shù)說(shuō)明:
- -org.apache.hadoop.hbase.snapshot.ExportSnapshot:HBase 提供的快照導(dǎo)出工具類。
- -snapshot snapshot_poi_geohash:指定要導(dǎo)出的快照名稱。
- -copy-from hdfs://${old_namenoe_ip}:8020/hbase:指定要從哪個(gè) HDFS 路徑下的文件進(jìn)行導(dǎo)出,${old_namenode_ip} 是舊的 NameNode IP 地址。
- -copy-to hdfs://${new_namenoe_ip}:8020/hbase:指定導(dǎo)出的文件將被存儲(chǔ)到哪個(gè) HDFS 路徑下,${new_namenode_ip} 是新的 NameNode IP 地址。
- -mappers 30:指定并發(fā)執(zhí)行的 Mapper 數(shù)量,即同時(shí)處理的任務(wù)數(shù)。這里設(shè)置為 30。
- -bandwidth 8192:指定數(shù)據(jù)傳輸?shù)膸捪拗?#xff0c;單位為 KB/s。這里設(shè)置為 8192,即 8 MB/s。?
任務(wù)啟動(dòng)的截圖:
任務(wù)結(jié)束的截圖:
說(shuō)明:在使用這個(gè)工具的使用,操作的客戶端必須是Yarn集群的客戶端節(jié)點(diǎn),否則上面的程序默認(rèn)使用本地的資源,如果數(shù)據(jù)量很大,將會(huì)同步的很慢。
注意點(diǎn)1:提交的任務(wù)終端,不能手動(dòng)kill,否則任務(wù)雖然正常執(zhí)行,但是最終的數(shù)據(jù)會(huì)同步失敗。(執(zhí)行上面命令時(shí),建議配合nohup,放在后臺(tái)執(zhí)行)
注意點(diǎn)2:這里還有一個(gè)細(xì)節(jié)點(diǎn)需要注意,就是用來(lái)同步的用戶,如果是CDH版本的,就推薦使用hbase用戶,如果是其他非hbase用戶,在下面第三步中恢復(fù)數(shù)據(jù)的時(shí)候就會(huì)有權(quán)限上的報(bào)錯(cuò)。
例如下面截圖的報(bào)錯(cuò),當(dāng)時(shí)同步的時(shí)候是用的hdfs用戶,在第三步恢復(fù)表數(shù)據(jù)的時(shí)候就會(huì)有下面的(權(quán)限報(bào)錯(cuò));
如果誤操作出現(xiàn)上面的情況,我們?cè)趫?zhí)行第三步的時(shí)候,命令的狀態(tài)是會(huì)一直卡著的,此時(shí)在hbase 的master web 頁(yè)面上可以看到此時(shí)表是在一直上鎖的。
處理方式:此時(shí)因?yàn)槭菣?quán)限問(wèn)題導(dǎo)致的,所以處理的方式也就很簡(jiǎn)單,只需要參考master的報(bào)錯(cuò)信息(上面有截圖),添加對(duì)應(yīng)的目錄權(quán)限即可。
添加權(quán)限:
$ hdfs dfs -chown -R hbase:hbase /hbase/?
這中間不要做其他操作,權(quán)限更改完成之后,重啟master節(jié)點(diǎn)即可恢復(fù)正常。
第三步:快照恢復(fù)表結(jié)構(gòu)以及數(shù)據(jù)
hbase(main):001:0> clone_snapshot 'snapshot_poi_geohash','poi_geohash'
說(shuō)明:這里我們測(cè)試表的namespace是默認(rèn)的default,如果原表是在自定義的namespace下,此時(shí)在目標(biāo)數(shù)據(jù)庫(kù)還需要手動(dòng)創(chuàng)建namespace。
參考命令:
$ hbase shell
hbase(main):013:0> create_namespace 'namespace_name'
2.利用hive外表關(guān)聯(lián)hbase遷移
這個(gè)是基于hive可以通過(guò)外部表(External Table)的方式來(lái)訪問(wèn)HBase中的數(shù)據(jù)。這種在實(shí)施的過(guò)程操作上相對(duì)比較簡(jiǎn)便。
下面給大家演示一個(gè)案例;
在目標(biāo)hbase中已存在hbase表:poi_geohash
1.首先進(jìn)入到hive的客戶端,創(chuàng)建hive的外部表,關(guān)聯(lián)到hbase表。
# 建立hbase外表需要指定對(duì)應(yīng)的zk
set hbase.zookeeper.quorum=10.6.24.xxx:2181,10.6.24.xxx:2181,10.6.24.xxx:2181; ## 指定hbase 的zk信息CREATE EXTERNAL TABLE poi_geohash_hive1
(
rowkey string,
lat_lon_list string,
name_list string,
type_id_list string,
type_list string
)STORED BY "org.apache.hadoop.hive.hbase.HBaseStorageHandler" WITH
SERDEPROPERTIES ("hbase.columns.mapping"=":key,cf:lat_lon_list,cf:name_list,cf:type_id_list,cf:type_list") TBLPROPERTIES ("hbase.table.name" = "poi_geohash");
2.查詢hive表,看是否有數(shù)據(jù)來(lái)驗(yàn)證關(guān)聯(lián)成功
select * from poi_geohash_hive;
3.將poi_geohash_hive表的數(shù)據(jù)導(dǎo)入到另一張hive內(nèi)部表中。
CREATE TABLE poi_geohash_hive_new AS
SELECTrowkey,lat_lon_list,name_list,type_id_list,type_list
FROMpoi_geohash_hive1;
4.在新的hbase中創(chuàng)建新的表,表特性和源hbase表一致。
代碼略
5.重復(fù)1的操作,進(jìn)入到hive的客戶端,創(chuàng)建hive的外部表,關(guān)聯(lián)到hbase表。
# 建立hbase外表需要指定對(duì)應(yīng)的zk
set hbase.zookeeper.quorum=${new_zk_ip}; ## 此時(shí)需要set 新的hbase集群的zk的信息CREATE EXTERNAL TABLE poi_geohash_hive2
(
rowkey string,
lat_lon_list string,
name_list string,
type_id_list string,
type_list string
)STORED BY "org.apache.hadoop.hive.hbase.HBaseStorageHandler" WITH
SERDEPROPERTIES ("hbase.columns.mapping"=":key,cf:lat_lon_list,cf:name_list,cf:type_id_list,cf:type_list") TBLPROPERTIES ("hbase.table.name" = "poi_geohash");
注意:這個(gè)時(shí)候通過(guò)hive關(guān)聯(lián)的是需要遷移的,2.4步驟中新創(chuàng)建的hbase表;
任務(wù)結(jié)束,驗(yàn)證新hbase表中有數(shù)據(jù)且數(shù)據(jù)完整,及完成對(duì)hbase表數(shù)據(jù)的遷移;
小tips:通常在嚴(yán)重hbase表數(shù)據(jù)的完整性的時(shí)候,簡(jiǎn)單點(diǎn)的方式就是統(tǒng)計(jì)rowkey的數(shù)量。
常規(guī)的統(tǒng)計(jì)方式有 :
1.使用hbase-shell 自帶count命令
2.使用hbase.RowCounter工具跑MR任務(wù)
3.使用HBase協(xié)處理器Coprocessor
但是性能上第三種(Coprocessor)是最快的,下面簡(jiǎn)單介紹下HBase協(xié)處理器統(tǒng)計(jì)表的一個(gè)小案例;
package com.ds;import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.*;
import org.apache.hadoop.hbase.client.coprocessor.AggregationClient;
import org.apache.hadoop.hbase.client.coprocessor.LongColumnInterpreter;public class CoprocessorExampleHbase2 {public static void main(String[] args) {try {long start_t = System.currentTimeMillis();String zkQuorum = null;String tableName = null;for (int i = 0; i < args.length; i++) {if (args[i].equals("-zk")) {zkQuorum = args[i + 1];} else if (args[i].equals("-tb")) {tableName = args[i + 1];}}if (zkQuorum == null || tableName == null) {System.out.println("請(qǐng)指定正確的參數(shù): -zk [Zookeeper Quorum] -tb [Table Name]");return;}// 初始化HBase配置Configuration customConf = new Configuration();customConf.set("hbase.rootdir", "hdfs:///hbase");customConf.set("hbase.zookeeper.property.clientPort", "2181");customConf.setStrings("hbase.zookeeper.quorum", zkQuorum.split(","));customConf.setLong("hbase.rpc.timeout", 600000);customConf.setLong("hbase.client.scanner.caching", 1000);customConf.set("zookeeper.session.timeout", "180000");Configuration configuration = HBaseConfiguration.create(customConf);AggregationClient aggregationClient = new AggregationClient(configuration);Scan scan = new Scan();long rowCount = aggregationClient.rowCount(TableName.valueOf(tableName), new LongColumnInterpreter(), scan);System.out.println("******************統(tǒng)計(jì)結(jié)果***********************");System.out.println("統(tǒng)計(jì)總耗時(shí):" + (System.currentTimeMillis() - start_t) + "毫秒");System.out.println("表【" + tableName + "】統(tǒng)計(jì)總數(shù):" + rowCount);} catch (Exception e) {e.printStackTrace();} catch (Throwable e) {e.printStackTrace();}}
}
在hbase配置 hbase-site.xm ?中添加如下配置,并重啟hbase;
<property><name>hbase.coprocessor.user.region.classes</name><value>org.apache.hadoop.hbase.coprocessor.AggregateImplementation</value></property>
使用方式,直接在hbase 的客戶端節(jié)點(diǎn)執(zhí)行:
hadoop jar hbase2-1.0-SNAPSHOT-jar-with-dependencies.jar com.ds.CoprocessorExampleHbase2 -zk zk地址 -tb hbase表名
最終的輸出結(jié)果:
Hbase 遷移小結(jié):從實(shí)踐中總結(jié)出的最佳遷移策略