XY个人记
一、HBase的压缩配置
HBase压缩的三个阶段:
1.在数据进入HDFS之前进行压缩
2.在MapRecduce的shuffle过程中:Map完成 Reduce开始阶段 数据在节点之间传输的时候进行压缩
3.数据处理完成存到HDFS之上的时候进行压缩
压缩的目的:
1.节省HDFS的存储空间,缓解存储压力
2.减少网络传输的数据,减轻网络传输负载
HBase配置压缩前hadoop需要支持压缩,关于hadoop的压缩可以参考:第五记·Hadoop SSH免秘钥配置以及本地native配置
查看Hadoop是否支持压缩:
$ bin/hadoop checknative
检查当前HBase是否支持压缩:
$ bin/hbase org.apache.hadoop.util.NativeLibraryChecker #检查HBase是否支持压缩
1.首先解压 hadoop-snappy-0.0.1-SNAPSHOT.tar.gz
$ tar -zxf /opt/software/hadoop-snappy-0.0.1-SNAPSHOT.tar.gz ./ #我这解压到hadoop下
2.声明配置窗口环境变量
export HBASE_HOME=/opt/modules/apache/hbase-1.2.1
export HADOOP_SNAPPY_HOME=/opt/modules/apache/hadoop-2.7.3/hadoop-snappy-0.0.1-SNAPSHOT
export HADOOP_HOME=/opt/modules/apache/hadoop-2.7.3
3.将snappy里面的jar拷贝到hbase下面的lib里
$ cp /opt/modules/apache/hadoop-2.7.3/hadoop-snappy-0.0.1-SNAPSHOT/lib/hadoop-snappy-0.0.1-SNAPSHOT.jar lib/
4.在hbase的lib目录下创建native文件夹
$ mkdir lib/native
5.设置软连接
ln -s $HADOOP_HOME/lib/native $HBASE_HOME/lib/native/Linux-amd64-64
6.再次查看是否支持压缩
7.查看表支持那种格式的压缩
8.测试压缩文件
$ bin/hbase org.apache.hadoop.hbase.util.CompressionTest hdfs://hadoop01.com:8020/test.txt snappy
9.创建两张表一张支持压缩 一张不支持
hbase(main):004:0> create 'hbase01:t2',{NAME=>'f1'}
hbase(main):005:0> create 'hbase01:t3',{NAME=>'f1',COMPRESSION => 'snappy'}
//导入数据 更改表的信息
disable 'test' #禁用
alter 'test', NAME => 'f', COMPRESSION => 'snappy' #针对列簇修改COMPRESSION
enable 'test' #启用
major_compact 'test' #合并
二、Hive HBase集成
可参考官网:
https://cwiki.apache.org/confluence/display/Hive/HBaseIntegration
关于HBase和Hive的集成
a.hbase表数据映射到hive表中,数据存在hbase
b.hive表类型:管理表(在hive建表时会在hbase建相同的表,数据也存在于hbase中)、外部表(在hive建表数据也是存在
于hbase中)
c.如果两个版本不兼容,建议考虑编译Hive的版本
1.HBase到hive需要一些jar的支持
在HBase的lib目录下找到相应的jar 添加到Hive的lib目录下
2.因为ZK是访问入口,所以需要指定ZK的实例化地址,用于连接hbase集群,修改hive-site.xml文件增加如下配置
<property>
<name>hbase.zookeeper.quorum</name>
<value>hadoop01.com</value>
</property>
3.将hbase中的表stu_import映射到hive——创建一个外部表stu_import,并映射到hive
CREATE EXTERNAL TABLE stu_import(
uuid int,
name string,
age string,
addr string,
desaddr string
)
STORED BY 'org.apache.hadoop.hive.hbase.HBaseStorageHandler'
WITH SERDEPROPERTIES ("hbase.columns.mapping" = ":key,f1:name,f2:age,f3:addr,f1:desaddr")
TBLPROPERTIES("hbase.table.name" = "stu_import");
查询hive中存在stu_import,并且已经存在hbase中的数据
我们发现hbase中的列簇、时间戳是不进行任何映射的
4.创建一个内部表,将hive的表映射到hbase
需要用stored by 指向类 org.apache.hadoop.hive.hbase.HBaseStorageHandler
CREATE TABLE hive_hbase_1(
id int,
name string
)
STORED BY 'org.apache.hadoop.hive.hbase.HBaseStorageHandler'
WITH SERDEPROPERTIES ("hbase.columns.mapping" = ":key,info:name")
TBLPROPERTIES ("hbase.table.name" = "hive_hbase", "hbase.mapred.output.outputtable" = "hive_hbase");
hbase.columns.mapping:属性必配,列之间的映射
hbase.table.name:属性是可选的,不配则hbase中的表与hive的表名称一致,配了则指定hbase中的表的名称
hbase.mapred.output.outputtable:跑MapReduce指向输出目录 属性是可选的
建表之后发现会报错:
org.apache.hadoop.hive.ql.exec.DDLTask. org.apache.hadoop.hbase.HTableDescriptor.addFamily(Lorg/apache/hadoop/hbase/HColumnDescriptor;)V
我们分析一下原因是因为Hive和HBase版本之间不兼容导致的。
解决办法
1.解压支持hbase的tar包apache-hive-1.2.1-hbase.tar.gz
$ tar -zxf ../../software/apache-hive-1.2.1-hbase.tar.gz #
$ mv apache-hive-1.2.1-bin hive-1.2.1-hbase #更名为hive-1.2.1-hbase
$ cp ../../hive-1.2.1/conf/hive-env.sh ./ #复制hive-env.sh到相应conf目录
$ cp ../../hive-1.2.1/conf/hive-site.xml ./ #复制hive-site.sh到相应conf目录
$ cp ../../hive-1.2.1/conf/hive-log4j.properties ./
2.更改配置文件的配置
3.还需要修改数据仓库的路径,在hive-site.xml中添加如下配置
<!-- 默认为 /user/hive/warehouse 防止冲突更改为如下配置 -->
<property>
<name>hive.metastore.warehouse.dir</name>
<value>/user/hive/warehouse_hbase</value>
</property>
4.将jar包添加到/opt/modules/apache/hive-1.2.1-hbase/lib
三、操作演示
5.完成之后可以进入支持我们hbase的hive
create database hive_hbase; #创建数据库
use hive_hbase;
CREATE TABLE hive_hbase_1(
id int,
name string
)
STORED BY 'org.apache.hadoop.hive.hbase.HBaseStorageHandler'
WITH SERDEPROPERTIES ("hbase.columns.mapping" = ":key,info:name")
TBLPROPERTIES ("hbase.table.name" = "xyz", "hbase.mapred.output.outputtable" = "xyz");
hbase.columns.mapping:这个属性必须要写的
hbase.table.name:这个是映射到hbase表的名称,这个属性可选,如果不要,那么对应的hbase表名称就是hive建表的名称hbase_table_1
hbase.mapred.output.outputtable:这个可选,直接可以不要
在hive创建表后可以在hbase中查到表‘xyz’
创建表并上传数据:
create table student(
id int,
name string
)
row format delimited fields terminated by '\t';
load data local inpath '/opt/datas/stu_info' into table student;
把数据映射到表hive_hbase_1中:
hive (hive_hbase)> insert overwrite table hive_hbase_1 select id,name from student;
在hive中去加载映射表数据:load是不行的,必须使用要跑mr。inser into 子查询的方式。
在映射到hive_hbase_1中需要跑mr。完成后可以查看结果 :
查看HBase,发现关联的HBase表中xyz也增加了数据
然后在HBase中put一行数据,在hive中查看发现也增加了数据。
在hive表中添加数据在hbase中也会更新添加了数据
在hbase中添加数据在hive中也添加了数据
打开HDFS中Hive发现hive_hbase_1里面是空的没有数据
查看HDFS中HBase里面region的列簇info也是空的,由于在hbase写数据还存在内存中,所以需要手动flush
hbase(main):106:0> flush 'xyz' #刷新'xyz'
FLUSH之后,刷新HDFS发现有数据
总结:数据是存在HBase中的,只是把数据和HBase做了关联
6.将HBase已经存在的表映射到hive(创建外部表:EXTERNAL)
想要映射hbase中已经存在的表,那么在hive中必须要是使用外部表属性EXTERNAL
CREATE EXTERNAL TABLE hbase_table_2(
uuid int,
username string
)
STORED BY 'org.apache.hadoop.hive.hbase.HBaseStorageHandler'
WITH SERDEPROPERTIES ("hbase.columns.mapping" = "info:name")
TBLPROPERTIES("hbase.table.name" = "xyz");
这样有利于在HIve中做一个数据分析的工作
在hive的hbase_table_2中添加数据
hive (hive_hbase)> INSERT OVERWRITE TABLE hbase_table_2 SELECT id,name from student;
在hive重新修改数据到外部表,hbase数据没有做更新(针对映射到hbase的外部表)
在HBase中put数据
hbase(main):108:0> put 'xyz','5','info:name','li'
在hbase重新修改数据,hive是有变化的(针对映射到hbase的外部表)
创建外部表hbase_table_3
CREATE EXTERNAL TABLE hbase_table_3(
uuid int,
username string
)
STORED BY 'org.apache.hadoop.hive.hbase.HBaseStorageHandler'
WITH SERDEPROPERTIES ("hbase.columns.mapping" = ":key,info:name")
TBLPROPERTIES("hbase.table.name" = "xyz");
当删除外部表hbase_table_3时,hbase中xyz表和数据是不会被删除的
hive (hive_hbase)> drop table hbase_table_3;
当删除内部表hive_hbase_1时,hbase中的xyz表也被删除
hive (hive_hbase)> drop table hive_hbase_1;
Hive集成HBase建表出现报错:
FAILED: Execution Error, return code 1 from org.apache.hadoop.hive.ql.exec.DDLTask. MetaException(message:For direct MetaStore DB connections, we don't support retries at the client level.)
解决办法:
修改mysql元数据的编码字符集:alter database metastore2 character set latin1;