- Hbase定义
- 它基于Hadoop之上的、分布式的、面向列的开源数据库
- 它就是用来存储数据查询,查询数据。
- 海量数据的存储,海量数据的查询
- Hbase体系架构图
- Client:
- 整个集群的入口
- 与Master通信进行表的管理
- 通过Zookeeper找到对应的RegionServer进行表的数据的操作
- 维护Cache
- Zookeeper:
- 所有的RegionServer都需要注册到Zookeeper里,提供RegionServer的状态信息,是否存活,实时推送给Master
- 存储HBase的schema,table元数据
- 保证HBase集群里只有一个Master节点
- 存储所有RegionServer的寻址入口
- Master:
- 管理表
- 对RegionServer的负载均衡
- 调整Region的分布
- RegionServer宕机以后对改RegionServer上的Region数据进行迁徙
- RegionServer:
- 它是管理Region的。Hbase里的数据是分区域的,每个区与叫做一个Region。
- Hbase表结构
- colmunfamily(列簇):拥有一个名称,包含一个或者多个列
- column(列):术语某一个列簇,包含在某一列中
- tableNam(表名):表的名称
- rowkey(唯一标识):每条数据里的唯一标识,如关系型数据库里的主键
- cell(数据单元):rowkey + columnfamily + column01 + timestamp:value
- vsersion number(版本号):默认是时间戳,long类型
- Hbase的安装(Hadoop是CDH的,所以我们可以去CDH上下载对应的Hbase的CDH版本)
- 下载:http://archive.cloudera.com/cdh5/cdh/5/hbase-1.2.0-cdh5.7.0.tar.gz
- 上传到Linux服务器上
- 解压
- 启动Hadoop的NameNode,DataNode
配置
hbase.env.sh
环境变量
export JAVA_HOME=/usr/java/jdk1.8.0_131
export HBASE_MANAGES_ZK=true #如果想用Hbase自带的Zookeeper可以不用配置这个属性,默认值为true,false为不使用自带的zookeeper
配置
hbase-site.xml
<property> <name>hbase.rootdir</name> <value>hdfs://hadoop001:8020/hbase</value> </property> <property> <name>hbase.cluster.distributed</name> <value>true</value> </property> <property> <name>hbase.zookeeper.quorum</name> <value>hadoop001</value> </property>
配置RegionServer为
hadoop001
启动Habse,在$HBASE_HOME/bin下运行
./start-hbase.sh
- Hbase的Shell使用
- 进入hbase的命令行,在$HBASE_HOME/bin下运行:
habse shell
- 找到所有的shell操作,进入命令行以后运行:
hbase -help
#对表的管理与操作的shell明令,具体语法的使用为在shell命令行运行 help '具体的指令'
Group name: ddl
Commands:
alter #修改表的
alter_async #异步更新,与alter的作用相同。
alter_status #状态
create #创建表
describe #查看表的描述
disable #使表无效,删除一个表之前,必须把表disable
disable_all #使所有表无效,删除一个表之前,必须把表disable
drop #删除表,删除一个表之前,必须把表disable
drop_all #删除所有的表,删除一个表之前,必须把表disable
enable #使表有效,删除一个表之前,必须把表disable
enable_all #使所有表有效,删除一个表之前,必须把表disable
exists #查看表是否存在
get_table #查看一个表
is_disabled #查看一个表是否是无效的
is_enabled #查看一个表是否是有效的
list #查看所有的表
locate_region #
show_filters #
#对命名空间的管理与操作的shell明令 #具体语法的使用为在shell命令行运行 help '具体的指令'
Group name: namespace
Commands:
alter_namespace :修改命名空间的关键字
create_namespace :创建一个命名空间
describe_namespace #查看命名空间的描述
drop_namespace #删除一个命名空间
list_namespace #查看所有的命名空间
list_namespace_tables #查看命名空间里的所有表
#对表的数据管理与操作的shell明令,具体语法的使用为在shell命令行运行 help '具体的指令'
Group name: dml
Commands:
append #追加值
count #统计表有多少行数据
delete #删除数据
deleteall #一次性删除多个cell数据
get #得到某一列或cell的数据。
get_counter #
get_splits #
incr #
put #插入数据
scan #扫描数据
truncate_preserve:
#tool命令提供了一些工具命令,组名称为Tools,这些命令多用于HBase集群的管理与调优。这些命令涵盖合并、分裂、负载均衡、日志回滚、Region分配和移动以及zookeeper信息查看等方面,具体语法的使用为在shell命令行运行 help '具体的指令'
Group name: tool
assign #分配Region
balance_switch #启用或关闭负载均衡器,返回结果是当前均衡器状态
balancer #触发集群负载均衡器。如果成果运行则返回TRUE,很可能将所有Region重新分配。
如果FALSE,说明某些Region在rit状态,不会执行该命令
balancer_enabled #
catalogjanitor_enabled #
catalogjanitor_run #
catalogjanitor_switch #
close_region #关闭某个Region
compact #合并表或者Region
compact_mob #
compact_rs #
flush #flush表或Region
major_compact #大合并表或Region
major_compact_mob #
merge_region #
move #移动Region。如果没有目标regionserver,则随机选择一个节点
normalize #
normalizer_enabled #
normalizer_switch #
split #分裂表或Region
trace #
unassign #解除某个指定的Region
wal_roll #zk_dump
#对数据复制的一下管理命令,具体语法的使用为在shell命令行运行 help '具体的指令'
Group name: replication
Commands:
add_peer #为两个集群添加复制管理
append_peer_tableCFs #为两个集群添加复制管理
disable_peer #禁用复制关系
disable_table_replication #关闭表的复制关系
enable_peer #启用复制关系
enable_table_replication #启用表的复制关系
list_peers #显示当前集群的复制关系
list_replicated_tables #显示一个hbase集群下处于复制状态的表
remove_peer #禁用并删除复制关系
remove_peer_tableCFs #禁用并删除peer下的表、列族复制关系
set_peer_tableCFs #设置peer下的表、列族复制关系
show_peer_tableCFs #显示peer下表、列族复制关系
#HBase Snapshots允许你对一个表进行快照(即可用副本),它不会对Region Servers产生很大的影响,它进行复制和 恢复操作的时候不包括数据拷贝。导出快照到另外的集群也不会对Region Servers产生影响
Group name: snapshots
Commands:
clone_snapshot #克隆一个快照
delete_all_snapshot #删除所有快照
delete_snapshot #删除一个快照
list_snapshots #查看所有快照
restore_snapshot #恢复快照
snapshot
Group name: configuration
Commands:
update_all_config #更新所有配置
update_config #更新单个配置
#HBase中限流是通过Quota语句来操作的,限流的方式有两种,一种是针对用户进行限流;另一种是针对表来进行限流
Group name: quotas
Commands:
list_quotas #
set_quota #
##表权限管理,安全管理 ,包括授权,收回,查看权限等等
Group name: security
Commands:
grant #
list_security_capabilities #
revoke #
user_permission
Group name: procedures
Commands:
abort_procedure #
list_procedures:
Group name: visibility labels
Commands:
add_labels #
clear_auths #
get_auths #
list_labels #
set_auths #
set_visibility
- Hbase的物理模型
- Table中的所有行都按照
RowKey
的字典排序 - Table在行的方向上进行分割,分割成的每个区域为
Region
,Region是按照大小
进行分割的,每个表一开始只有一个Region
,随着Region的数据越来越大达到一定的阈值,那么Region就会被拆分两个Region。 - Region是Hbase中分布式存储和负载均衡中的最小单元,不同的Region分布在RegionServer上。
- Region由一个或者多个
Store
组成,每个Store只保存一个Columns family
,每个Store由两部分组成,第一个是一个MemStore
,存储在内存中,第二个是多个StoreFile
,存储在HDFS
上。
- Hbase数据的写入流程:
- 首先先写入日志文件(
Hlog
)里,防止写入数据的时候机器宕机造成数据的丢失。 - 第二步写入内存中(
MemStore
) - 写入
HDFS
中
- Hbase检索数据的三种方式:
get rowkey
最快的scan range
用的最多的scan
权标扫描,基本很少用
- Hbase架构图
存储过程模型
根据架构图解析Hbase对数据的读写流程,以下为写入数据的流程:
client ---> zookeeper
:当我们连接Zookeeper的时候,会读取Zookeeper下的Hbase目录下的RegionServer地址,根据RegionServer找到Region,根据Region我们会找到Meta表,Meta表里存的就是用户表的RegionServer,然后我们会根据RegionServer找到Region,然后开始扫描数据。Client ---> Hlog --->HDFS
:欲写文件,防止宕机数据丢失,HLog是Hadoop上的Sequence file(序列文件,用于恢复数据),Client ---> MemStore---> HFile
:存储到内存中,当达到一定阈值写到HFile中,HFile是二进制文件格式。StoreFile就是对Hfile的封装,当StoreFile的数量达到一定的阈值就会触发Compact合并操作,所有的更新与删除操作都是在Compact阶段执行的。HFile ---> HDFS
:写到HDFS中
- Hbase的API使用
在
pom.xml
添加依赖(具体版本由自己Hadoop版本决定,我用的是hadoop-2.6.0-cdh5.7.0
)<!--hbase依赖--> <dependency> <groupId>org.apache.hbase</groupId> <artifactId>hbase-client</artifactId> <version>1.2.0-cdh5.7.0</version> </dependency> <!--hbase依赖--> <dependency> <groupId>org.apache.hbase</groupId> <artifactId>hbase-server</artifactId> <version>1.2.0-cdh5.7.0</version> </dependency> <!--hadoop依赖--> <dependency> <groupId>org.apache.hadoop</groupId> <artifactId>hadoop-client</artifactId> <version>2.6.0-cdh5.7.0</version> </dependency>
拷贝
${HADOOP_HOME}/etc/hadoop/
下的core-site.xml
配置文件和hdfs-site.xml
,以及${HBASE}/conf/下的hbase-site.xml
配置文件到项目下resource目录中
编写基本的操作Hbase的代码,其余的api可以对照着Shell命令进行编写。
package hbase; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.hbase.Cell; import org.apache.hadoop.hbase.CellUtil; import org.apache.hadoop.hbase.HBaseConfiguration; import org.apache.hadoop.hbase.TableName; import org.apache.hadoop.hbase.client.*; import org.apache.hadoop.hbase.util.Bytes; import org.apache.hadoop.io.IOUtils; import java.io.IOException; import java.util.ArrayList; import java.util.List; /** * 类的注释 * * @Package hbase * @ClassName HbaseClient * @Description 连接Hbase * @Author liyuzhi * @Date 2018-05-12 21:54 */ public class HbaseClient { public static void main(String[] args) throws IOException { Connection conn = getConnection(); Table user = getTableByTableName(conn); get(user); conn.close(); } //Hbase里的scan api 条件扫描 private static void scanOther(Table user) throws IOException { Scan scan1 = new Scan(); ResultScanner scanner1 = user.getScanner(scan1); // co ScanExample-2-GetScanner Get a scanner to iterate over the rows. for (Result res : scanner1) { System.out.println(res); } scanner1.close(); System.out.println("Scanning table #2..."); Scan scan2 = new Scan(); scan2.addFamily(Bytes.toBytes("colfam1")); ResultScanner scanner2 = user.getScanner(scan2); for (Result res : scanner2) { System.out.println(res); } scanner2.close(); System.out.println("Scanning table #3..."); Scan scan3 = new Scan(); scan3.addColumn(Bytes.toBytes("colfam1"), Bytes.toBytes("col-5")). addColumn(Bytes.toBytes("colfam2"), Bytes.toBytes("col-33")). setStartRow(Bytes.toBytes("row-10")). setStopRow(Bytes.toBytes("row-20")); ResultScanner scanner3 = user.getScanner(scan3); for (Result res : scanner3) { System.out.println(res); } scanner3.close(); System.out.println("Scanning table #4..."); Scan scan4 = new Scan(); scan4.addColumn(Bytes.toBytes("colfam1"), Bytes.toBytes("col-5")). setStartRow(Bytes.toBytes("row-10")). setStopRow(Bytes.toBytes("row-20")); ResultScanner scanner4 = user.getScanner(scan4); for (Result res : scanner4) { System.out.println(res); } scanner4.close(); System.out.println("Scanning table #5..."); Scan scan5 = new Scan(); scan5.addColumn(Bytes.toBytes("colfam1"), Bytes.toBytes("col-5")). setStartRow(Bytes.toBytes("row-20")). setStopRow(Bytes.toBytes("row-10")). setReversed(true); ResultScanner scanner5 = user.getScanner(scan5); for (Result res : scanner5) { System.out.println(res); } scanner5.close(); user.close(); } //Hbase里的scan api 全表扫描 private static void scanAll(Table user) throws IOException { Scan scan = new Scan(); ResultScanner scanner = user.getScanner(scan); for (Result result : scanner) { System.out.println(result.listCells()); } user.close(); } //Hbase里的delete api private static void delete(Table user) throws IOException { Delete delete = new Delete(Bytes.toBytes("10001")); delete.addFamily(Bytes.toBytes("info")); user.delete(delete); user.close(); } //Hbase里的put api private static void put(Table user) throws IOException { try { Put put = new Put(Bytes.toBytes("10002")); put.addColumn(Bytes.toBytes("info"), Bytes.toBytes("name"), Bytes.toBytes("liyuzhi")); put.addColumn(Bytes.toBytes("info"), Bytes.toBytes("age"), Bytes.toBytes(20)); put.addColumn(Bytes.toBytes("info"), Bytes.toBytes("addrees"), Bytes.toBytes("dashiqiao")); put.addColumn(Bytes.toBytes("info"), Bytes.toBytes("phone"), Bytes.toBytes(12345)); user.put(put); } catch (IOException e) { e.printStackTrace(); } finally { IOUtils.closeStream(user); } user.close(); } //Hbase里的get api private static void get(Table user) throws IOException { Get get = new Get(Bytes.toBytes("row1")); get.addColumn(Bytes.toBytes("colfam1"), Bytes.toBytes("qual1")); Result result = user.get(get); byte[] val = result.getValue(Bytes.toBytes("colfam1"), Bytes.toBytes("qual1")); System.out.println("Value: " + Bytes.toString(val)); } //Hbase里的get api private static void getList(Table user) throws IOException { byte[] cf1 = Bytes.toBytes("colfam1"); byte[] qf1 = Bytes.toBytes("qual1"); byte[] qf2 = Bytes.toBytes("qual2"); byte[] row1 = Bytes.toBytes("row1"); byte[] row2 = Bytes.toBytes("row2"); List<Get> gets = new ArrayList<Get>(); Get get1 = new Get(row1); get1.addColumn(cf1, qf1); gets.add(get1); Get get2 = new Get(row2); get2.addColumn(cf1, qf1); gets.add(get2); Get get3 = new Get(row2); get3.addColumn(cf1, qf2); gets.add(get3); Result[] results = user.get(gets); System.out.println("First iteration..."); for (Result result : results) { String row = Bytes.toString(result.getRow()); System.out.print("Row: " + row + " "); byte[] val = null; if (result.containsColumn(cf1, qf1)) { val = result.getValue(cf1, qf1); System.out.println("Value: " + Bytes.toString(val)); } if (result.containsColumn(cf1, qf2)) { val = result.getValue(cf1, qf2); System.out.println("Value: " + Bytes.toString(val)); } } System.out.println("Second iteration..."); for (Result result : results) { for (Cell cell : result.listCells()) { System.out.println( "Row: " + Bytes.toString(cell.getRowArray(), cell.getRowOffset(), cell.getRowLength()) + // co GetListExample-7-GetValue2 Two different ways to access the cell data. " Value: " + Bytes.toString(CellUtil.cloneValue(cell))); } } for (Result result : results) { System.out.println(result); } user.close(); } //初始化连接 private static Connection getConnection() throws IOException { Configuration configuraton = HBaseConfiguration.create(); return ConnectionFactory.createConnection(configuraton); } //设置要操作的表 private static Table getTableByTableName(Connection conn) throws IOException { return conn.getTable(TableName.valueOf("user")); } }
- Hbase与MapReduce集成
编码
package hbase.mapreduce; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.conf.Configured; import org.apache.hadoop.hbase.Cell; import org.apache.hadoop.hbase.CellUtil; import org.apache.hadoop.hbase.HBaseConfiguration; import org.apache.hadoop.hbase.client.Put; import org.apache.hadoop.hbase.client.Result; import org.apache.hadoop.hbase.client.Scan; import org.apache.hadoop.hbase.io.ImmutableBytesWritable; import org.apache.hadoop.hbase.mapreduce.TableMapReduceUtil; import org.apache.hadoop.hbase.mapreduce.TableMapper; import org.apache.hadoop.hbase.mapreduce.TableReducer; import org.apache.hadoop.hbase.util.Bytes; import org.apache.hadoop.io.Text; import org.apache.hadoop.mapreduce.Job; import org.apache.hadoop.util.Tool; import org.apache.hadoop.util.ToolRunner; import java.io.IOException; /** * 类的注释 * * @Package hbase.mapreduce * @ClassName UserToSubuser * @Description * @Author liyuzhi * @Date 2018-05-13 19:15 */ public class UserToSubuser extends Configured implements Tool { public static class UserInputMapper extends TableMapper<Text, Put> { /** * 方法的注释 * * @return void * @description 从Hbase里获取数据传给Reduce,将数据插入新的表 * @methodName map * @Param: key 封装了二进制的rowkey * @Param: value 就是rowkey下边的所有数据 * @Param: context * @author liyuzhi * @createTime 2018-05-13 21:10 * @version v1.0 */ @Override protected void map(ImmutableBytesWritable key, Result value, Context context) throws IOException, InterruptedException { //得到字符串的rowkey String rowkey = Bytes.toString(key.get());//封装了 //创建一个Put对象,,传给TableReducer Put put = new Put(key.get()); //以下就是根据具体的业务需求进行逻辑处理 for (Cell cell : value.listCells()) { if ("info".equals(Bytes.toString(CellUtil.cloneFamily(cell)))) { if ("name".equals(Bytes.toString(CellUtil.cloneQualifier(cell)))) { put.add(cell); } if ("age".equals(Bytes.toString(CellUtil.cloneQualifier(cell)))) { put.add(cell); } } } //写入数据 context.write(new Text(rowkey), put); } } public static class UserOutputReducer extends TableReducer<Text, Put, ImmutableBytesWritable> { @Override protected void reduce(Text key, Iterable<Put> values, Context context) throws IOException, InterruptedException { for (Put put : values) { context.write(null, put); } } } public int run(String[] strings) throws Exception { //创建job Job job = Job.getInstance(this.getConf(), this.getClass().getSimpleName());//创建Job job.setJarByClass(this.getClass());//设置运行jar的class Scan scan = new Scan();// scan.setCaching(100); scan.setCacheBlocks(false);//不需要缓存,因为这是抽取数据 //初始化Map类的 TableMapReduceUtil.initTableMapperJob("user", scan, UserInputMapper.class, Text.class, Put.class, job); //初始化Reduce类的 TableMapReduceUtil.initTableReducerJob("sub_user", UserOutputReducer.class, job); job.setNumReduceTasks(1); //提交任务 boolean states = job.waitForCompletion(true); return states ? 0 : 1; } public static void main(String[] args) throws Exception { Configuration conf = HBaseConfiguration.create();//获取配置文件 int states = ToolRunner.run(conf, new UserToSubuser(), args); System.exit(states); } }
运行jar包
HADOOP_CLASSPATH=`${HADOOP_HOME}/lib/hbase mapredcecp` haodop jar /opt/jar/example.jar
- Hbase批量迁徙数据
(利用importtsv方法迁徙tsv数据,这个缺点是数据只保存在内存中,并没有保存磁盘中)
HADOOP_CLASSPATH=`${HBASE_HOME}/bin/hbase classpath` \ ${HADOOP_HOME}/bin/hadoop jar ${HBASE_HOME}/lib/hbase-server-1.2.0-cdh5.7.0.jar \ importtsv -Dimporttsv.columns=HBASE_ROW_KEY,info:name,info:age,info:address,info:phone \ student hdfs://hadoop001:8020/opt/testfile/importtsv
(最常用的方法,而且能够大批量的迁徙数据,必会的):
(1)先将数据变成HfileHADOOP_CLASSPATH=`${HBASE_HOME}/bin/hbase classpath` ${HADOOP_HOME}/bin/hadoop jar \ ${HBASE_HOME}/lib/hbase-server-1.2.0-cdh5.7.0.jar importtsv -Dimporttsv.columns=HBASE_ROW_KEY,info:name,info:age,info:address,info:phone \ -Dimporttsv.bulk.output=hdfs://hadoop001:8020/opt/testfile/hfileoutput \ student2 hdfs://hadoop001:8020/opt/testfile/importtsv
(2)将Hfile同步到Hbase数据库里
HADOOP_CLASSPATH=`${HBASE_HOME}/bin/hbase classpath` ${HADOOP_HOME}/bin/hadoop jar ${HBASE_HOME}/lib/hbase-server-1.2.0-cdh5.7.0.jar \ completebulkload hdfs://hadoop001:8020/opt/testfile/hfileoutput student2
注意:当我们在向Hbase迁徙大量数据的时候,在创建表的时候需要创建多个Region,因为默认创建一张表值创建一个Region,那么当我们向表中插入大量数据的时候,由于只有一个Region,而Region是被RegionServer管理的,由此会增加单个服务器的内存压力,有可能宕机。所以我们在创建表的时候应该多创建Region,根据预估rowkey来创建。
- Hbase表的属性
{
NAME => 'info', #列簇
BLOOMFILTER => 'ROW',
VERSIONS => '1', #版本
IN_MEMORY => 'false', #在写的时候缓存(占RegionServer40%的内存),达到一定大小就会flush到磁盘中,还有一中功能是缓存meta元数据
KEEP_DELETED_CELLS => 'FALSE',
DATA_BLOCK_ENCODING => 'NONE',
TTL => 'FOREVER',
COMPRESSION => 'NONE',#压缩,如果需要配置压缩:1.配制hadoop压缩,2.配制Hbase压缩,将hadoop-snappy.jar方到Hbase的lib目录下,然后将
hadoop的里lib下的native软连接到Hbase下的lib目录下的native,并且名称一定要命名为
Linux-amd64-64,3.在hbase的habse.core-site.xml配置hbase.regionserver.codecs为snappy
重启regionserver
MIN_VERSIONS => '0',#最小版本,
BLOCKCACHE => 'true', #在读的时候缓存(占RegionServer40%的内存),当同步数据或者分支数据的时候一般设置为false
BLOCKSIZE => '65536',
REPLICATION_SCOPE => '0'
}
Hbase数据查询流程:用户-->MemStore-->BlockCache(每一个RegionServer一个)--->HFile-->meger-->返回给用户
- Hbase主表与索引表
- 索引表:功能就是辅助作用,来充当索引
- 主表和索引表怎么建立同步方式:
- phoenix,只能用JDBC的方式才能实现同步
- 利用solr,将重要字段建立索引存在solr中,从solr get出来,拿到rowkey,再从主表get出来,同步方式利用lily实现同步,或者用cloudera search方式实现同步。
- Hbase表的压缩
- 配置Hadoop压缩:https://blog.csdn.net/suubyy/article/details/80397176
配置Hbase
- 拷贝
hadoop-snappy.jar
到${HBASE_HOME}/lib
目录下,hadoop-snappy.jar
需要自己提前编译出来 运行命令:
ln -s ${HADOOP_HOME}/lib/native ${HBASE_HOME}/lib/native/Linux-amd64-64
在RegionServer上配置hbase.site.xml里配置压缩
<property> <name>hbase.regionserver.codecs</name> <value>snappy</value> </property>
- 拷贝
- Hbase与Hive集成(由于CDH已经帮我们集成好了,所以不需要配置与操作就可以利用hive操作hbase表)
创建管理表(Hbase不存在的表)
#单列 CREATE TABLE hbase_table_1(key int, value string) STORED BY 'org.apache.hadoop.hive.hbase.HBaseStorageHandler' WITH SERDEPROPERTIES ("hbase.columns.mapping" = ":key,cf1:val") TBLPROPERTIES ("hbase.table.name" = "xyz", "hbase.mapred.output.outputtable" = "xyz"); #多列 CREATE TABLE hbase_table_1(key int, value1 string, value2 int, value3 int) STORED BY 'org.apache.hadoop.hive.hbase.HBaseStorageHandler' WITH SERDEPROPERTIES ( "hbase.columns.mapping" = ":key,a:b,a:c,d:e" ); INSERT OVERWRITE TABLE hbase_table_1 SELECT foo, bar, foo+1, foo+2 FROM pokes WHERE foo=98 OR foo=100; #(key int, value string):代表的是Hbase里表的字段,Key为rowkey,value为列簇下对应列的值 #("hbase.columns.mapping" = ":key,cf1:val")::key为固定写法,cf1:val,就是指定具体的列簇与列,一定要与上边table里的一一对应 #"hbase.table.name":为Hbase里表名
创建外部表(Hbase已经存在的表)
CREATE EXTERNAL TABLE hbase_table_2(key int, value string) STORED BY 'org.apache.hadoop.hive.hbase.HBaseStorageHandler' WITH SERDEPROPERTIES ("hbase.columns.mapping" = "cf1:val") TBLPROPERTIES("hbase.table.name" = "some_existing_table", "hbase.mapred.output.outputtable" = "some_existing_table");
插入数据
INSERT OVERWRITE TABLE hbase_table_1 SELECT rowkey,value FROM pokes WHERE foo=98; #具体插入的数据的列数要与Hbase里的列数要一致
- Hbase完全分布式集群搭建
配置
hbase.site.xml
<property> <name>hbase.rootdir</name> <value>hdfs://hadoop001:8020/hbase</value> </property> <property> <name>hbase.cluster.distributed</name> <value>true</value> </property> <property> <name>hbase.zookeeper.quorum</name> <value>hadoop001,hadoop002,hadoop003</value> </property>
配置
${HBASE_HOME}/conf/regionserver
hadoop002 hadoop003
拷贝该机器刚才配置好的Hbase目录到其他两台机器上