HBase02

ε祈祈猫儿з 提交于 2019-12-01 09:44:08

1. Hbase与hive的对比

A. Hive(数据仓库):Hive的本质其实就相当于将HDFS中已经存储的文件在mysql中做了一个双射关系,以便使用HSQL查询。hive适用于离线数据的分析和清洗,延迟较高。hive基于hdfs和mapreduce。

B. HBase(数据库):列式存储的非关系型数据库,用于存储结构化和半结构化的数据,不适合关联查询,基于hdfs,数据的持久化存储的体现形式是Hfile,存放于DataNode中。延迟较低。

总结:Hive和HBase是两种基于hadoop的不同技术,hive是一种类sql查询引擎,并且运行mapreduce任务,Hbase是在hadoop之上的nosql的key-value数据库。这两种工具可以同时使用,hive用来统计查询,hbase用来实时查询。两者之间数据可以互相写入。

2. HBase和Hive整合

A. hive的结果导入HBase中

--创建Hive表
create external table if not exists course.score(id int,cname string,score int) row format delimited fields terminated by '\t' stored as textfile ;
--数据内容
1    zhangsan    80
2    lisi    60
3    wangwu    30
4    zhaoliu    70
--加载数据
load data local inpath '/export/hive-hbase.txt' into table score;
--创建hive管理表和Hbase映射
create table course.hbase_score(id int,cname string,score int)  
stored by 'org.apache.hadoop.hive.hbase.HBaseStorageHandler'  
with serdeproperties("hbase.columns.mapping" = "cf:name,cf:score") 
tblproperties("hbase.table.name" = "hbase_score");
--加载数据
insert overwrite table course.hbase_score select id,cname,score from course.score;
View Code

B. 将Hbase中已有的数据加载到Hive的外部表中

--在HBase中创建表并插入数据
create 'hbase_hive_score',{ NAME =>'cf'}
put 'hbase_hive_score','1','cf:name','zhangsan'
put 'hbase_hive_score','1','cf:score', '95'
put 'hbase_hive_score','2','cf:name','lisi'
put 'hbase_hive_score','2','cf:score', '96'
put 'hbase_hive_score','3','cf:name','wangwu'
put 'hbase_hive_score','3','cf:score', '97'
--在Hive中创建外部表,映射当前映射表
CREATE external TABLE course.hbase2hive(id int, name string, score int) STORED BY 'org.apache.hadoop.hive.hbase.HBaseStorageHandler' WITH SERDEPROPERTIES ("hbase.columns.mapping" = ":key,cf:name,cf:score") TBLPROPERTIES("hbase.table.name" ="hbase_hive_score");
View Code

C. mysql数据导入HBase

--在mysql中创建数据表并插入数据
CREATE DATABASE  IF NOT EXISTS library;
USE library;
CREATE TABLE book(
id INT(4) PRIMARY KEY NOT NULL AUTO_INCREMENT, 
NAME VARCHAR(255) NOT NULL, 
price VARCHAR(255) NOT NULL);
INSERT INTO book(NAME, price) VALUES('Lie Sporting', '30');  
INSERT INTO book (NAME, price) VALUES('Pride & Prejudice', '70');  
INSERT INTO book (NAME, price) VALUES('Fall of Giants', '50');  
View Code

D. 将HBase中的数据导入到mysql

具体流程Hbase-->hive外部表-->hive内部表-->通过sqoop-->mysql

创建hive外部表,映射hbase中的数据表
CREATE EXTERNAL TABLE course.hbase2mysql (id int,name string,price int)
   STORED BY 'org.apache.hadoop.hive.hbase.HBaseStorageHandler'
   WITH SERDEPROPERTIES (
    "hbase.columns.mapping" =
     ":key,info:name, info:price"
   )
   TBLPROPERTIES( "hbase.table.name" = "hbase_book",
    "hbase.mapred.output.outputtable" = "hbase2mysql");
创建hive的内部表,将外部表导入内部
CREATE TABLE course.hbase2mysqlin(id int,name string,price int);
insert overwrite table course.hbase2mysqlin select * from course.hbase2mysql;
清空数据mysql
TRUNCATE TABLE book;
sqoop导出hive内部表数据到mysql
bin/sqoop export -connect jdbc:mysql://hadoop01:3306/library -username root -password 123456  -table book -export-dir /user/hive/warehouse/course.db/hbase2mysqlin --input-fields-terminated-by '\001' --input-null-string '\\N' --input-null-non-string '\\N';
View Code

3. HBase的预分区

region:一个表的部分或者全部数据,一个region维护着startRowKey与endRowKey,加入的数据如果在这个范围内,这个数据就会交给这个region维护。

A:为什么要设置预留分区?

  • 负载均衡,防止数据倾斜
  • 增加数据读写效率
  • 方便集群容灾调度region
  • 优化Map数量

B:如何预留分区?

Hbase默认建表时候只有一个region,并且startRowKey和endRowKey是没有边界的,所有数据都默认写入到这个region,这个region会变大,当达到一定阈值时候,会切割分成两个split。所以让每个region维护一定范围的rowKey就达到了预留分区目的。

C. 如何创建预留分区?

  • 手动指定预定分区
create 'staff','info','partition1',SPLITS=>['1001','1002',1000=3','1004']
View Code
  • 使用16进制算法生成预分区
create 'staff2','info','partition2',{NUMREGIONS => 15, SPLITALGO => 'HexStringSplit'}
View Code
  • 分区规则创建于文件当中
分区文件:
aaaa
bbbb
cccc
dddd
--创建语句
create 'staff3','partition2',SPLITS_FILE => '/export/servers/splits.txt'
View Code
  • 使用java api创建预分区
package com.partition;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.HColumnDescriptor;
import org.apache.hadoop.hbase.HTableDescriptor;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.Admin;
import org.apache.hadoop.hbase.client.Connection;
import org.apache.hadoop.hbase.client.ConnectionFactory;

import java.io.IOException;

public class PasartionTest {
    /**
     * 通过javaAPI进行HBase的表的创建以及预分区操作
     */
    public static void main(String[] args) throws IOException {
        hbaseSplit();
    }
   static public void hbaseSplit() throws IOException {
        //获取连接
        Configuration configuration = HBaseConfiguration.create();
        configuration.set("hbase.zookeeper.quorum", "hadoop01:2181,hadoop02:2181,hadoop03:2181");
        Connection connection = ConnectionFactory.createConnection(configuration);
        Admin admin = connection.getAdmin();
        //自定义算法,产生一系列Hash散列值存储在二维数组中
        byte[][] splitKeys = {{1,2,3,4,5},{'a','b','c','d','e'}};
        //通过HTableDescriptor来实现我们表的参数设置,包括表名,列族等等
        HTableDescriptor hTableDescriptor = new HTableDescriptor(TableName.valueOf("stuff4"));
        //添加列族
        hTableDescriptor.addFamily(new HColumnDescriptor("f1"));
        //添加列族
        hTableDescriptor.addFamily(new HColumnDescriptor("f2"));
        admin.createTable(hTableDescriptor,splitKeys);
        admin.close();
    }

}
View Code

 

4. Hbase的rowkey设计技巧

rowkey的长度原则:最好保证rowkey在10-100字节内,建议在16字节以下。当存储当量数据时,rowkey长度过长也会占用大量磁盘空间,memstore部分数据缓存到内存,rowkey长度过长,内度利用率会降低。

散列原则:建议将rowkey的高位作为散列字段,由程序随机生成,将低位放时间字段,这样将提高数据均衡分布在每个Region Server,以实现负载均衡。

rowkey唯一原则:保证rowkey是唯一的,rowkey是按照字典排序存储的,因此设计rowkey时必须充分利用这个排序的特点,将经常读取的数据存储到一块,将最近可能会被访问的数据也放到一块。

什么是热点?

  检索habse的记录首先要通过row key来定位数据行。当大量的client访问hbase集群的一个或少数几个节点,造成少数region server的读/写请求过多、负载过大,而其他region server负载却很小,就造成了“热点”现象。

热点问题产生的原因:

hbase中的数据是按照字典顺序排序的,当大量连续的rowkey几种卸载个别region,各个region之间的数据分布不均匀。

创建表时没有提前预分区,创建的表默认只有一个region,大量的数据写入region。

创建表时提前预分区,但是设计rowkey没有规律可循。

如何解决数据倾斜(热点)?

加盐:在rowkey前面加随机数。增加随机前缀以使得他和以前的rowkey的开头不一样。

哈希:在rowkey前面增加hash值。

反转:将固定格式的rowkey进行反转,如电话号码。

时间反转:将时间戳进行反转。

5. Hbase的协处理器(coprocessor)

协处理器包括两种:

observer:相当于RDBMS中 的触发器。

insert into 之前或者之后一旦监控到,可以完成其他的功能。

hbase:put,preput,postput

endpoint:相当于关系型数据库中的存储过程,完成max,sum,avg等聚合工作

协处理器的加载方式:

静态加载:通过修改hbase-site.xml,配置协处理器在配置文件中,为所有的表增加协处理器,不提倡。

动态加载:启用表aggregtaion

Hbase中的二级索引,可以存在冗余数据,空间换时间。

总结:

  • Observer 允许集群在正常的客户端操作过程中可以有不同的行为表现
  • Endpoint 允许扩展集群的能力,对客户端应用开放新的运算命令
  • observer 类似于 RDBMS 中的触发器,主要在服务端工作
  • endpoint 类似于 RDBMS 中的存储过程,主要在 client 端工作
  • observer 可以实现权限管理、优先级设置、监控、 ddl 控制、 二级索引等功能
  • endpoint 可以实现 min、 max、 avg、 sum、 distinct、 group by 等功能

6. HBase优化见笔记

 

 

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!