【博学谷学习记录】超强总结,用心分享 | 狂野大数据-Phenix学习分享


提示:以下是本篇文章正文内容,下面案例可供参考

一、HBase的表结构设计

1.1 HBase的名称空间

HBase的名称空间类似于MySQL中的库
在HBase中, 默认提供了两个名称空间:

  • 1- default: 默认的名称空间, 在创建表的时候, 如果不指定名称空间, 默认就会将表创建在这个default名称空间下
    • 类似于在HIVE中有一个default库
  • 2- hbase: 此名称空间是hbase专门用于放置hbase系统表的名称空间, 例如: meta 表就是存储在这个名称空间下, 此名称空间, 一般不使用的
# 创建名称空间
create_namespace '名称空间名字'

# 查看所有名称空间
list_namespace

# 在指定的名称空间下创建表
create '名称空间:表名','列族1','列族2'...

# 删除名称空间(删除名称空间的时候, 此名称空间下, 不能有表存在, 否则无法删除)
drop_namespace '名称空间' 

# 查看某一个名称空间
describe_namespace '名称空间'

1.2 HBase的列族的设计

HBase在构建表时,列族建议越少越好,在某一些情况下可以构建多个列族
情况一:需要将一份数据存储到HBase的时候, 整个数据集中只有某几列数据经常使用到, 其他列的数据使用频次并不高,建议将其分为两个列族, 一个列族中用于放置经常使用的字段, 一个列族放置其他的字段

情况二: 一份数据集主要是用于对接两个不同的业务, 不同的业务的体系使用的数据集中不同的字段, 根据业务要求, 将不同业务数据划分到不同的列族中, 便于各个业务读取不同列族的下数据

1.3 Hbase的表压缩方案的选择

在HBase中,压缩的操作是存在与磁盘(HDFS)上,只有当数据落在HDFS上才会进行压缩,如果数据在内存中是不存在压缩的
如何选择压缩方案:

  • 如果写入请求远远大于读取请求(写多读少),建议采用GZIP,保证在有限的空间下,存储更多的数据
  • 如果读取请求远远大于写入数据的请求(读多写少),建议采用SNAPPY压缩方案,在保证一定的压缩率下,更好的提高压缩和解压的效率
    配置压缩的格式:
# 新建表时设置压缩方案
create '表名',{NAME=>'列族',COMPERSSION=>'压缩算法'}
create 'test1',{NAME=>'C1', COMPERSSION=>'GZ'}

# 为已存在表添加压缩方案
 alter '表名', {NAME => '列族', COMPRESSION => '压缩算法'}
 alter 'test02' {NAME=>'C1',COMPRESSION=> 'GZ'}

注意: 在设置压缩方案的时候, 默认GZ是被支持的, 如果使用LZO 或者 SNAPPY , 有可能出现无法使用的情况, 如果非要尝试, 需要将HBase重新编译, 设置其支持其他的压缩方案, 以及增加相关的压缩方案的jar包, 或者 使用CDH版本的HBase

1.4 HBase的预分区

在HBase中默认情况下, 创建一个表只有一个Region, 只有一个Region也就意味着只能被一个RegionServer所管理

在此种情况下, 如果遇到大量的并发访问, 此时所有的请求全部打向同一个RegionServer上, 从而导致这个RegionServer承担更大的并发, 出现宕机的风险, 宕机后, 如果region被其他的RegionServer接管了, 可能还会接着宕机, 最终导致出现雪崩问题, 全部节点一起奔溃。
因此,引入预分区,让表的Region数量变得更多, 当Region变多了, 那么就可以让更多的RegionServer参与, 从而让更多RegionServer一起来承担并发读写请求

  • 手动预分区(适合于对表的rowkey数据比较了解,可以大概预知分区后数据的平均分配情况)
    create '表名','列族1','列族2'..., SPLITS=>[自定义分区方案]
    create 'test01','C1',SPLITS=>['10','20','30','40','50']
    
  • Hash的预分区
    create '表名','列族1','列族2'...,{NUMREGIONS => N, SPLITALGO => 'HexStringSplit'}
    create 'ns1:test01','C1',{NUMREGIONS=>5,SPLITALGO=>'HexStringSplit'}
    

不管采用哪种预分区的方式, 建议预分区的数量为RegionServer数量的2~5倍左右即可

1.5 HBase中rowkey的设计原则

  通过预分区, 可以保证在创建表的时候, 就可以让表一开始拥有多个Region, 但是Region的划分方案是基于rowkey的范围来划分的, 如果说, rowkey在设计的过程中, 前缀都是以固定的名称来命名. 此时可能会导致所有的数据全部写入到某一个Region或者某几个Region上, 从而导致预分区设置没有效果的

  • 官方设计原则:
    1- 避免使用递增的行键/时序的数据作为rowkey的前缀 ( 不要以固定的前缀作为rowkey)
    2- 在设计的时候rowkey和列的长度不能太长了, 建议越短越好, 一般建议在1~30区间,最长不能超过100字节
    3- 使用数值类型的要比使用string更加节省空间
    4- 保证rowkey的唯一性
    
  • 业务原则
    保证相关性的数据放置到同一个Region中
    rowkey的设计能够满足一些固定的查询需求
    

如果rowkey的设计不良好,就会导致大量的数据集中到某一个或者几个Region中,而其他的Region中没有数据,或者数据极少。
解决方案

    1. 加盐处理(加随机数)
    • 好处:基本保证数据落在不同的Region中
    • 弊端:相关性无法保证,会将数据完全打散
    1. 反转的策略:手机号的反转,时间戳反转
    • 好处:基本保证数据落在不同的Region中
    • 弊端:相关性无法保证,会将数据完全打散
    1. hash处理–后续此种方式可以和Hash预分区配合使用, 基于HBase提供MD5HASH 方案生成rowkey的前缀(推荐)
    • 好处:相关性的数据可以放置到一起
    • 弊端:如果相关性的数据比较多,依然会导致热点问题的发生

1.6 HBase的版本确界和TTL

对于版本确界 和 TTL 在实际中需要根据实际生产需求进行设置, 如果生产环境中没有要求, 选择默认即可

1.6.1 版本的确界

所谓的版本的确界, 本质上指的就是是否需要保留历史版本, 以及保留多少个问题

  • 下界: 指的至少需要保留多少个历史版本, 即使数据过期了, 也是需要保留的 默认为 0 (禁用)
  • 上界: 指的最多需要保留多少个历史版本数据, 默认值: 1

1.6.2 数据TTL(数据保质期)

在HBase中可以对数据设置过期时间, 当达到时间后, 数据就会自动被删除掉了

1.6.3 代码演示版本确界和TTL

package com.itheima.hbase.ttl;

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 java.io.IOException;

public class HBaseVersionAndTTL {
    public static void main(String[] args) throws IOException {
        //1. 根据连接工厂, 创建HBase的连接对象
        Configuration conf = HBaseConfiguration.create();
//        conf.set("hbase.zookeeper.quorum","node1:2181,node2:2181,node3:2181");
        Connection HbaseConnect = ConnectionFactory.createConnection(conf);

        //2. 根据连接对象, 获取相关管理对象
        Admin admin = HbaseConnect.getAdmin();
        // 2.1 判断某个表是否存在
        if (!admin.tableExists(TableName.valueOf("VERSION_TTL"))) {
            // 2.2  如果表不存在, 创建这个表
            ColumnFamilyDescriptor columnFamily = ColumnFamilyDescriptorBuilder
                    .newBuilder("C1".getBytes())
                    .setMaxVersions(5)
                    .setMinVersions(3)
                    .setTimeToLive(80)
                    .build();
            TableDescriptor version_ttl = TableDescriptorBuilder.newBuilder(TableName.valueOf("VERSION_TTL")).setColumnFamily(columnFamily).build();
            admin.createTable(version_ttl);
        }
        // 2.3 如果表存在, 获取这个表对象
        Table table = HbaseConnect.getTable(TableName.valueOf("VERSION_TTL"));

        // 3. 执行相关操作:  添加数据(添加一条, 修改N次)
        for (int i = 1; i <7 ; i++) {
            Put put = new Put("rk0001".getBytes());
            put.addColumn("C1".getBytes(),"NAME".getBytes(),("张三"+i).getBytes());
            table.put(put);
        }
        // 4- 查看数据: 查看历史版本的数据
        Get get = new Get("rk0001".getBytes());
        // 设置读取所有的版本数据
        get.readAllVersions();
        Result result = table.get(get);
        Cell[] cells = result.rawCells();// 获取所有版本的单元格信息
        for (Cell cell : cells) {
            System.out.println(Bytes.toString(CellUtil.cloneValue(cell)));
        }
        //5. 释放资源:
        table.close();
        admin.close();
        HbaseConnect.close();
    }
}

执行结果:
在这里插入图片描述

二、Phoenix的基本介绍

Phoenix是属于Apache旗下的一款顶级开源的基于HBase的工具,此工具提供一种权限的方式来操作HBase中数据(SQL),同时Phoenix对HBase进行大量的优化工作, 能够让我们更加有效的操作HBase

​ Phoenix的出现仅仅时为HBase提供了权限的方式, 并不是数据分析的引擎, 所以一般也不会使用Phoenix + HBase构建数仓, 传统的离线数仓 依然是基于Hadoop + HIVE

​ Phoenix更主要做的是一种即席查询

三、Phoenix的基本使用

3.1 如何在Phoenix中创建表

代码如下(示例):

# 创建一张订单表
create table order_dtl(
	id varchar primary key,#primary key主键标识必须加
    c1.status varchar,
    c1.money integer,
    c2.pay_way integer,
    c1.user_id integer,
    c2.operation_time varchar,
    c2.category varchar);

默认情况下: Phoenix会将所有的小写的字段 表名 以及列族都变更为大写
一旦使用小写, 以后只要使用小写的内容, 必须使用双引号进行包裹, 所以一般建议使用大写, 而不是小写

3.2 查看所有的表

!table

3.3 查看某一个表结构信息

!desc 表名

3.4 向表中插入数据(修改数据)

#添加数据
upsert into order_dtl(id,status,money,pay_way,user_id,operation_time,category) values('000001','已提交',4070,1,4944191,'2020-04-25 12:09:16','手机;');

#修改操作:
upsert into order_dtl(id,category) values('000001','电脑;')
  • 查询操作: 与标准的SQL是一致的

    • 仅支持单表的操作, 不支持子查询, 也不支持Join的操作
  • 删除数据: 与标准的SQL是一致的

  • 删除表: 与标准的SQL是一致的


总结

使用phoenix就是将Hbase添加可以使用sql进行操作的过程,javaAPI也可以通过实现JDBC接口连接。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值