美文网首页
HBase从入门到放弃

HBase从入门到放弃

作者: 江澈_SIMON | 来源:发表于2020-06-23 15:16 被阅读0次
    先放入一张HBase架构整理镇楼

    HBase解决了什么问题:

    1)HBase主要解决在Hdfs上可以随机读写的问题

    2)Hive只能查询,不能随机读写


    一、HBase依赖于Zookeeper和HDFS

    1)Zookeeper

    HBase通过Zookeeper来做master的高可用、RegionServer的监控、元数据的入口以及集群配置的维护等工作。具体工作如下:

    通过Zoopkeeper来保证集群中只有1个master在运行,如果master异常,会通过竞争机制产生新的master提供服务

    通过Zoopkeeper来监控RegionServer的状态,当RegionSevrer有异常的时候,通过回调的形式通知Master RegionServer上下线的信息

    通过Zoopkeeper存储元数据的统一入口地址

    2)HDFS

    HDFS为Hbase提供最终的底层数据存储服务,同时为HBase提供高可用(Hlog存储在HDFS)的支持,具体功能概括如下:

    提供元数据和表数据的底层分布式存储服务

    数据多副本,保证的高可靠和高可用性


    二、HBase中的角色

    1.3.1 HMaster

    功能

    1.监控RegionServer

    2.处理RegionServer故障转移

    3.处理元数据的变更

    4.处理region的分配或转移

    5.在空闲时间进行数据的负载均衡

    6.通过Zookeeper发布自己的位置给客户端

    1.3.2 RegionServer

    功能

    1、HregionServer直接对接用户的读写请求,是真正的“干活”的节点。它的功能概括如下:

    2、管理master为其分配的Region

    3、处理来自客户端的读写请求

    4、负责和底层HDFS的交互,存储数据到HDFS

    5、负责Region变大以后的拆分

    6、负责Storefile的合并工作

    1.2.3相关名词

    1. Hlog:写数据时会先把操作写到Hlog,可以数据恢复,如果某一台RegionServer宕机了,Hmaster通过Hlog的备份,把这台RegionServer的表负载到不同的RegionServer上

    2. Region:Hbase表的分片,HBase表会根据RowKey值被切分成不同的region存储在RegionServer中,在一个RegionServer中可以有多个不同的region。

    3. Store:HFile存储在Store中,一个Store对应HBase表中的一个列族。

    4. MemStore:读缓存

    5. BlockCache:写缓存

    5. HFile:这是在磁盘上保存原始数据的实际的物理文件,是实际的存储文件。StoreFile是以Hfile的形式存储在HDFS的。


    三、HBase表的数据结构

    一、rowkey每张表的唯一主键

    RowKey是用来检索的主键

    二、column family列族

    Hbase表中的每个列,都归属于某个列族,列族是表schema的一部分(而列不是),必须在使用表之前定义,列名都以列族为前缀。例如:courses:history,courses:math;都属于course这个列族

    三、Cell单元格

    Hbase中通过rowkey和columns确定的一个存储单元称为cell,每个cell保存着同一份数据的多个版本。版本通过时间戳来索引,cell中的数据是没有类型的,全都是字节码形式存储

    关键字:无类型,字节码

    四、TimeStamp时间戳

    Hbase中通过rowkey和columns确定的一个存储单元称为cell,每个cell保存着同一份数据的多个版本。版本通过时间戳来索引


    四、HBase的读写流程

    ①  HBase的读数据流程:

    1)  Client向Zookeeper发送请求,得到meta表所在位置(如regionServer hadoop102)

    2)  Client获取mate表数据

    3)  读取的rowKey所在的regionServer,先读取缓存,缓存没有读取磁盘

    4)  返回读取到数据

    ② Hbase写数据流程

    1) Client向Zookeeper发送请求,得到meta表所在位置(如regionServer hadoop102)

    2) Client获取mate表数据,得到要写到哪个region

    3) 先写数据到Hlog(为了数据的恢复)

    4) 在写到内存,当内存足够大会溢写到HDFS,溢写文件数量超过三个时,合并文件

    ③ 数据flush过程

    1)当MemStore数据达到阈值(默认是128M,老版本是64M),将数据刷到硬盘,将内存中的数据删除,同时删除HLog中的历史数据;

    2)并将数据存储到HDFS中;

    3)在HLog中做标记点。

    ④ 数据合并过程

    1)当数据块拆过三块,Hmaster触发合并操作,Region将数据块加载到本地,进行合并;

    2)当合并的数据超过256M,进行拆分,将拆分后的Region分配给不同的HregionServer管理;

    3)当HregionServer宕机后,将HregionServer上的hlog拆分,然后分配给不同的HregionServer加载,修改.META.;

    4)注意:HLog会同步到HDFS。


    五、HBase rowkey设计和预分区

    Rowkey设计原则:

    · 唯一性

    · 散列(避免热点)

    · 长度

    为了<散列>我们引入了预分区:

    · HBase默认建表时有一个region,这个region的rowkey是没有边界的,即没有startkey和endkey,在数据写入时,所有数据都会写入这个默认的region,随着数据量的不断增加,此region已经不能承受不断增长的数据量,会进行split,分成2个region。在此过程中,会产生两个问题:

    1. 数据往一个region上写,会有写热点问题。

    2. region split会消耗宝贵的集群I/O资源。

    · 基于此我们可以控制在建表的时候,创建多个空region,并确定每个region的起始和终止rowky,这样只要我们的rowkey设计能均匀的命中各个region,就不会存在写热点问题。自然split的几率也会大大降低。当然随着数据量的不断增长,该split的还是要进行split。像这样预先创建hbase表分区的方式,称之为预分区;


    六、Hbase API

    1、HbaseAdmin admin = connection.getAdmin( ),获取admin对象

    admin:做DDL(数据库定义语言),对命名空间,表,列族的 创建、修改、删除操作

    ①查看表是否存在:admin.tableExists(tableName)

    ②创建表:descript对象

    HTableDescriptor descriptor = new HTabelDescriptor(TableName.valueOf(tableName)); //创建HTableDescriptor(表描述)对象

    descriptor.addFamily(new HColumnDescriptor(columnFamily1));  //表描述 添加 列描述

    admin.createTabel(descriptor); //根据描述创建表

    ③删除表: admin.deleteTbale(tableName);

    2、HTable table = connection.getTable( ),获取table对象

    table:做DML(数据操纵语言),对数据的增删改查

    ①插入数据: PUT对象

    //根据rowkey创建put对象,Bytes是Utils类中转换字符串为字节数组,因为Hbase存储都是字节数组

    Put put = new Put(Bytes.toBytes(rowKey));

    put.add(Bytes.toBytes(columnFamily),Bytes.tiBytes(column),Bytes.toBytes(value)); //根据行

    table.put(put); //向表中添加数据

    table.colse(); //关闭资源,源码中为关闭执行池和关闭连接

    ②删除数据:delete对象

    List deleteList = new ArrayList();

    Delete delete1 = new Delete(Bytes.toBytes(rowkey)); //根据rowkey创建delete对象

    deleteList.add(delete1);

    table.delete(deleteList); //每次删除一组rowkey对应的数据

    ③获取所有数据scan对象

    Scan scan = new Scan(); //得到用于扫描region的对象

    ResultScanner resulteScanner = hTable.getScanner(scan); //扫描所有数据的结果

    for(Result result : resultScanner){ //Result是一行数据的结果

        Cell[] cells = result.rawRow(); //cell是一个单元格对象

        for(Cell cell : cells){

        CellUtils.cloneValue; //获取单元格的值

        }

    }

    ④获取单行数据get对象

    Get get = new Get(Bytes.toBytes(rowkey)); 

    get.setMaxVersions(); //显示最后一个版本

    get.setTimeStamp(); //显示指定时间戳的版本

    get.addColumn(Bytes.toBytes(column_family),Bytes.toBytes(qualifier)); //指定列族:列

    // 遍历数据集

    Result result = table.get(get); //获取一行数据

    Cell[] cells  = result.rawRow(); //获取所有单元格

    for(Cell cell : cells){

        CellUtils.cloneValue; //获取单元格的值

    }

    hbase周末小总结

    相关文章

      网友评论

          本文标题:HBase从入门到放弃

          本文链接:https://www.haomeiwen.com/subject/msjsxktx.html