HBase从入门到放弃

2020-06-23  本文已影响0人  江澈_SIMON
先放入一张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周末小总结
上一篇 下一篇

猜你喜欢

热点阅读