HBase(三)

Hadoop实时day21–Apache HBase


今日内容大纲
1、Apache HBase和 mapreduce整合(重要)
	读写hbase表
	bulkload加载数据
	(file--->hfile--->bulkload--->hbase)
2、Apache HBase Hive整合(重要)
3、Apache HBase sqoop整合
  mysql<---->hbase

4、HBase 预分区 + rowkey设计(重要)(重要)(重要)(重要)(重要)(重要)
	rowkey是字符串 底层使用bytes[]  
	从左到右根据字典序比较

5、Hbase 协处理器
6、Hbase 二级索引
	什么一级索引。 hbase中只有rowkey才有索引。
	
--------
重要扩展
1、master HA机制
2、TTL 超时时间
3、布隆过滤器  加快查询速度 
	概率型数据结构

HBase 和mapreduce整合
  • mapreduce天生可以和hbase整合。

  • mapreduce专门设计了两个类 用于mr和hbase的交互

    • TableMapper --负责从HBase中读数据的类

    • TableReducer– 负责把数据写入HBase中

      在使用tablereducer写数据到hbase的时候 输出的v必须是put或者是delete
      
      the output value must be either a Put or a Delete instance when using the TableOutputFormat class.
      
  • 需求:使用mapreduce从hbase一张表中读取数据 对数据进行处理 再把部分数据写入hbase另一张表。

    将myuser这张表当中f1列族的 name 和 age 字段写入到 myuser1 这张表的 f1 列族当中去。
    create 'myuser1','f1'
    
    get  put  scan  delete
    
  • HBase专门封装了一个工具类 TableMapReduceUtil用于mr程序的map reduce任务的初始化。

            TableMapReduceUtil.initTableMapperJob(TableName.valueOf("myuser"),
                    scan,HBaseMrMapper.class, ImmutableBytesWritable.class, Put.class,job);
    
            TableMapReduceUtil.initTableReducerJob("myuser1",HBaseMrReducer.class,job);
    
  • bulkloadh功能

    • 当我们使用put方式加载数据的时候 需要一条条插入进行 数据需要经过内存 磁盘 最终才能编程hfile。

    • 也可以使用技术把数据首先变成hfile格式 加载移动到hbase对应的位置路径下

    • 弊端:使用bulkload导入数据 不会有hlog日志产生 意味着后续数据恢复成为问题。

    • 实现

      • 如何把普通的文件变成hfile格式 要满足表约束。

        • 使用mapreduce内置==HFileOutputFormat2==类把输出的数据变成Hfile格式

          job.setOutputFormatClass(HFileOutputFormat2.class);
          
          HFileOutputFormat2.configureIncrementalLoad(job,table,connection.getRegionLocator(TableName.valueOf("myuser1")));
          
      • 如何把hfile加载到hbase对应的路径下。

        • 核心api

          LoadIncrementalHFiles load = new LoadIncrementalHFiles(configuration);
          load.doBulkLoad(new
          Path("hdfs://node-1:8020/hbase/output_hfile2"),
          admin,table,connection.getRegionLocator(TableName.valueOf("myuser1")));
          
    • 数据准备

      #hdfs 路径/hbase/input/user.txt 内容如下:
      
      0007    zhangsan        18
      0008    lisi    25
      0009    wangwu  20
      

HBase 和HIve整合
  • 两者对比

    • hive–数据仓库

      基于Hadoop的数仓。面向分析支持分析。 olap系统。
      可以将结构化文件映射成为一张表 提供了基于表sql查询能力。
      支持复杂的业务分析。
      
    • hbase–nosql数据库

      基于hdfs的nosql数据库。 
      不支持sql 不支持复杂业务分析。不支持复杂事务,支持简单行级事务。
      支持基于rowkey索引查询。
      大表数据实时读写查询。
      
  • 整合方式

    • 创建hive表 把数据存储在hbase中。
    • 创建hive外部表 映射hbase已有的表。
  • 整合过程

    • 添加hbase相关的jar到hive lib路径下

      cd /export/servers/hbase/lib/
      
      cp hbase-client-1.2.0-cdh5.14.0.jar hbase-hadoop2-compat-1.2.0-cdh5.14.0.jar hbase-hadoop-compat-1.2.0-cdh5.14.0.jar hbase-it-1.2.0-cdh5.14.0.jar hbase-server-1.2.0-cdh5.14.0.jar /export/servers/hive/lib/
      
    • 修改hive的配置文件 添加zk属性

      <property>
      	<name>hive.zookeeper.quorum</name>
      	<value>node-1,node-2,node-3</value>
      </property>
      <property>
      	<name>hbase.zookeeper.quorum</name>
      	<value>node-1,node-2,node-3</value>
      </property>
      
    • 修改hive环境变量shell 添加hbase路径

        export HADOOP_HOME=/export/servers/hadoop-2.6.0-cdh5.14.0
        export HBASE_HOME=/export/servers/hbase
        export HIVE_CONF_DIR=/export/servers/hive/conf
      
  • 核心api语法

    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")
    

HBase和sqoop整合
  • 从mysql到hbase

    bin/sqoop import \
    --connect jdbc:mysql://192.168.1.5:3306/library \
    --username root \
    --password admin \
    --table book \
    --columns "id,name,price" \  #列
    --column-family "info" \ #列族名称
    --hbase-create-table \   #在hbase中创建表
    --hbase-row-key "id" \   #rowkey对应着表的字段
    --hbase-table "hbase_book" \   #表名
    --num-mappers 1 \
    --split-by id
    
  • 从hbase到mysql

    • 思路:Hbase→hive 外部表→hive 内部表→通过 sqoop→mysql
    • 注意:位于mysql中表要提前存在。
    #step1 创建hive外部表映射hbase表
    CREATE EXTERNAL TABLE 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");
    
    
    #step2 创建hive内部表 把外部表数据插入到内部表中
    CREATE TABLE hbase2mysqlin(id int,name string,price int);
    insert overwrite table hbase2mysqlin select * from hbase2mysql;
    
    #step3 使用sqoop把内部表的数据导出到mysql中
    bin/sqoop export -connect jdbc:mysql://node-1:3306/library \
    -username root -password hadoop -table book \
    -export-dir /user/hive/warehouse/hbase2mysqlin \
    --input-fields-terminated-by '\001' \
    --input-null-string '\\N' --input-null-non-string '\\N'
    
    #sqoop参数 
    	--input-null-string '\\N' --input-null-non-string '\\N'
    	
    	对于hive的空值数据 不管是字符串类型的空值 还是非字符串类型的空值 在导出到mysql的时候 统一的使用\N表示空  避免null和“null”歧义。
    

HBase 预分区、rowkey设计
  • rowkey特性

    • rowkey是字符串类型 最大长度64K。

    • 底层是以二级制==字节数组byte[]==形式存储的。

    • 默认根据字节数组**索引字典序**排序。

      从左往右逐位比较 如果相等继续比较下一位。
      
       001 
       0010
       001|
       002 
       00a 
      #底层是通过ASCII 码表进行比较
      
      http://ascii.911cha.com/
      
  • HBase预分区

    • 默认region split规则有什么不好的地方。

      • 拆分规则导致region大小不相等 负载不均衡
      • 默认的rowkey排序会导致某块区域集中访问 热点问题
    • 默认情况下创建表的时候只有一个分区 范围是:

      [-oo , +oo]
      
      • 意味着数据只要put 就写入该分区中 直到满足条件进行region split拆分
      • 分区的关键之处是分区标识键:Start Key End Key
    • hbase支持在创建表的时候 指定分区的个数 提取创建好分区 这叫做预分区。

    • 如何预分区

      • 把分区标识写在文件中 建表的时候加载文件。

        cd /export/servers/
        vim splits.txt
        
        aa|
        bb|
        cc|
        dd|
        
         create 'staff3','partition2',SPLITS_FILE =>'/export/servers/splits.txt'
        
      • 建表手动写

        create 'staff','info' ,SPLITS =>['1000','2000','3000','4000']
        
    • 预分区创建好之后 还必须结果rowkey设计 否则将失去意义

  • rowkey设计原则
    • 官方指导标准:https://hbase.apache.org/book.html#rowkey.design

    • 唯一原则

      rowkey是不同行数据之间的唯一标识。类似于主键 不能重复的。
      
    • rowkey长度原则

      理论上rowkey最高支持64K。实际中并不是越长越好,因为rowkey最终也是要存储在hfile总的。
      
    • 散列原则

      尽量避免rowkey在一台regionserver上,造成读写的热点问题。尽量打散分布在各个不同机器上,配合预分区技术实现负载均衡。
      
      • 在追求散列原则的同时 追求集中原则

        追求散列的目的是避免热点问题。
        追求集中的目的是保证业务查询相关的数据尽量集中在一起 避免多台机器查询。
        
      • 散列实现方式

        • 加盐(Salting)–random

          在rowkey前加上随机字符串等符号。
          
          foo0001
          foo0002
          foo0003
          foo0004
          
          加盐之后
          a-foo0003
          b-foo0001
          c-foo0004
          d-foo0002
          a-foo0003
          b-foo0001
          
          比如:分区表示
          a|
          b|
          c|
          d|
          
        • ==哈希(Hashing==重点

          使用hash等算法对数据进行取值  只要数据不变 得出的结果是一样的。
          
          哈希方法:  hash(手机号+月+天)  % 4 = 余数就是前缀
          
          hash(13888888888+2018+1031) = 1
          hash(13888888888+2018+1101) = 3
          hash(13888888888+2018+1101) = 3
          hash(13888888888+2018+1102) = 4
          
        • 反转

          原始数据:
          13888888888
          13999999999
          13777777777
          13666666666
          
          反转之后:
          88888888831
          99999999931
          77777777731
          66666666631
          
        • 时间戳反转

  • 案例:中国联不通–手机上网流量详单

    • 需求:提供用户查询指定某一天上网详细记录。 按天查询

    • 预分区

      # 根据业务和数据量 确定hbase表分区个数
      	100个 region
      # 确定分区标识键 starkey stookey
      00|
      01|
      02|
      03|
      ...
      98|
      
    • rowkey设计

      • 指导标准:追求散列的同时 追求数据集中

        • 散列:不同用户不同天上网记录分散开
        • 集中:同一个用户同一上网记录集中一起 便于查询。
      • 设计hash方法

        hash(手机号+天) % 99
        
      • 原始数据

        用户:18888888888
        
        起始时间	  				通信地点	网络类型	计费类型	总流量/KB	  通信费
        2020-08-10 00:25:29  		sh        4G         免费       2225        0.0
        2020-08-10 11:43:49  		nj        7G         免费       5566        0.0
        2020-08-12 03:25:52  		dj        2G         免费       3152        0.0
        2020-08-13 04:23:29  		sh        4G         免费       445         0.0
        
        
      • rowkey的前缀

        #step1
        18888888888+2020-08-10  通过hash方法计算前缀
        hash(18888888888+2020-08-10) % 99  = 25
        
        	rowkey
        25-手机号+2020-08-10+00:25:29    sh        4G         免费       2225        0.0
        25-手机号+2020-08-10+11:43:49    nj        7G         免费       5566        0.0
        32-手机号+2020-08-12+03:25:52    dj        2G         免费       3152        0.0
        48-手机号+2020-08-13+04:23:29    sh        4G         免费       445         0.0
        
      • scan查询的时候如何设置查询条件

        # 用户操作:查询 18888888888 2020-08-10上网通信记录。
        
        # step1: 通过页面表单拿取到当前操作的用户手机号 查询天条件
        	18888888888 2020-08-10
        
        # step2: 使用哈希方法计算前缀值
            hash(18888888888+2020-08-10) % 99 = 25
        # step3:封装scan查询条件
        
        Scan scan = new Scan();
        scan.setStartRow("25-手机号+2020-08-10")  #有比没有打
        scan.setStopRow("25-手机号+2020-08-10|")  #| 老子倒数第三大
        

Hbase 协处理器
  • 概念

    • 协助帮助用户进行某种操作的处理器技术。
  • 背景知识

    • 触发器
      • 相当于在数据库上绑定一些函数 当用户操作行为满足条件 触发函数的执行。
      • 对应hbase来说 给put delete进行绑定
    • 存储过程
      • 相当于定义一个函数。需要用户手动调用才会在服务器上执行相关的逻辑。
  • hbase协处理器分类

    • observer --触发器 和具体操作绑定
    • endpoint–存储过程 需要用户手动调用执行。
  • hbase协处理器都是在服务端执行的。

  • 栗子:observer 使用。

    • 需求:给一张表绑定协处理器 当有put数据插入的时候 通过协处理器把数据复制一份到另一张表。

    • 创建表

      create 'proc1','info'
      create 'proc2','info'
      
      #没有挂载协处理器之前 表元数据样子
      hbase(main):041:0> describe 'proc1'
                                                                                
      {NAME => 'info', BLOOMFILTER => 'ROW', VERSIONS => '1', IN_MEMORY => 'false', KEEP_DELETED_CELLS => 'FALS
      E', DATA_BLOCK_ENCODING => 'NONE', TTL => 'FOREVER', COMPRESSION => 'NONE', MIN_VERSIONS => '0', BLOCKCAC
      HE => 'true', BLOCKSIZE => '65536', REPLICATION_SCOPE => '0'}    
      
    • 写类继承BaseRegionObserver

    • 把协处理器打成一个jar 注意:此时打包只需要把自己的代码打包即可 把pom中打包插件注释掉

    • 把打好jar上传到hdfs的目录下

      cd /export/servers
      mv example-hbase-1.0.jar processor.jar
      
      hdfs dfs -mkdir -p /processor
      hdfs dfs -put processor.jar /processor
      
    • 给指定的表挂载协处理器

      alter 'proc1',METHOD =>
      'table_att','Coprocessor'=>'hdfs://node-1:8020/processor/processor.jar|cn.itcast.hbase.MyCp|1001|'
      
      Coprocessor'=>'hdfs jar路径|主类|1001|   数字是优先级 一个表可以挂载多个协处理器 数字越小优先级越高
      
  • 晚上练习:https://hbase.apache.ocp_examplerg/book.html#


HBase 重要扩展
  • master HA机制

    • master在哪台机器运行是如何决定的?

      在哪里启动 哪台机器就是master
      
      当使用脚本一键的时候 在运行脚本的机器上就是master.
      
    • 如果多个机器都启动master怎么办?

      谁先启动去zk注册节点/master 谁就是master 其他的自动成为备份master.
      
      hbase支持多主
      
      当active master出现故障之后 其他备份收到zk通知 去抢夺节点。谁抢到谁就是新的master.
      
    • 如果想在一键启动的时候 自动帮助我们启动备份master 可以在conf下创建一个文件

      backup-masters
      
      node-2
      node-3
      
  • HBase TTL

    • 概念:Time To Live 生存时间值。

    • 在hbase中 默认情况下数据 TTL是永久的。除非手动删除 否则一致存在。

    • 可以在建表的时候 或者修改表 让TTL时间生效 倒计时结束之后 数据将会被自动删除。

      TTL => 'FOREVER'
      
      create 't_9', {NAME => 'f1', VERSIONS => 1, TTL => 10}   #单位是s
      
      TTL => '10 SECONDS',
      
    • 应用场景

      • 秒杀场景
      • 支付验证码
      • 扩展:redis也有TTL 基于内存nosql数据库。 它的TTL功能更好哦。
  • HBase 布隆过滤器

    • 是一种概率型数据结构
    • 可以判断某个数据一定不在 但是不能判断数据是否一定在

今日作业
  • hbase和mapreduce、hive 、sqoop集成。
  • 预分区和rowkey设计 吃透概念 举一反三。
    • 散列又集中
  • 笔记上概率 扩展知识 查缺补漏。
  • 预习kafka MQ。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

章鱼哥TuNan&Z

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值