HBase知识点总结

一、HBase简介

1.HBase概念

  • HBase – Hadoop Database,是一个高可靠性、高性能、面向列、可伸缩的分布式存储系统。
  • 利用HBase技术可在廉价PC Server上搭建起大规模结构化存储集群。
  • HBase利用Hadoop HDFS作为其文件存储系统,利用Hadoop MapReduce来处理HBase中的海量数据,利用Zookeeper作为协调工具。

2.HBase特点

  • :一个表可以有数十亿行,上百万列;
  • 无模式:每行都有一个可排序的主键和任意多的列,列可以根据需要动态的- 增加,同一张表中不同的行可以有截然不同的列;
  • 面向列:面向列(族)的存储和权限控制,列(族)独立检索;
  • 稀疏:对于空(null)的列,并不占用存储空间,表可以设计的非常稀疏;
  • 数据多版本:每个单元中的数据可以有多个版本,默认情况下版本号自动分配,是单元格插入时的时间戳;
  • 数据类型单一:HBase中的数据都是字符串,没有类型

3.引入HBase的原因

  • 传统关系型数据库系统已无法适应大型分布式数据存储的需要
  • 改良的关系数据库(副本、分区等)难于安装与维护
  • 关系模型对数据的操作使数据的存贮变得复杂
  • HBase从设计理念上就为可扩展做好了充分准备
  • 空间的扩展只需要加入存储结点,使用‘表’的概念,但不同于关系数据库,HBase实质上是一张极大的、非常稀疏的,存储在分布式文件系统上的表(不支持SQL)

4.HBase数据模型

  • 数据存放在带标签的表中
    Tables 由 rows和columns组成.
  • Table cells单元格有版本
    是HBase插入单元格时候的时间戳.
  • 列组成“列族”
    所有的列族成员有相同的前缀.
  • 物理上,所有的列族成员都一起存放在文件系统中
    HBase实际上就是一个面向列族的存储器
  • HBase中的每一张表,就是所谓的BigTable。稀疏表。
  • RowKey 和 ColumnKey 是二进制值byte[],按字典顺序排序
  • Timestamp 是一个 64 位整数
  • value 是一个未解释的字节数组byte[]
  • 表中的不同行可以拥有不同数量的成员。即支持“动态模式”模型

HBase数据模型-行:
在这里插入图片描述
行的特点:
(1)字符串、整数、二进制串甚至串行化的结构都可以作为行键
(2)表按照行键的“逐字节排序”顺序对行进行有序化处理
(3)表内数据非常‘稀疏’,不同的行的列的数完全目可以大不相同
(4)可以只对一行上“锁”
(5)对行的写操作是始终是“原子”的

数据模型-列:
在这里插入图片描述
列的特点:
(1)列必须用‘族’(family)来定义
(2)任意一列有如下形式
1)“族:标签”
2)其中,族和标签都可为任意形式的串
(3)物理上将同“族”数据存储在一起
(4)数据可通过时间戳区分版本

5.HBase物理存储

在这里插入图片描述

二、HBase的shell操作

1.HBase shell介绍

  • HBase提供了一个shell的终端给用户交互。我们称之 为:“HBase shell”。
  • HBase Shell 提供了大多数的 HBase 命令, 通过 HBase Shell 用户可以方便地创建、删除及修改表, 还可以向表中添加数据、列出表中的相关信息等。
  • 注意:写错 HBase Shell 命令时用键盘上的“Delete” 进行删除,“Backspace”不起作用。

2.HBase shell的启动

(1)启动HBase:start-hbase.sh
这将启动一个 HBase instance
(2)启动HBase shell:hbase shell
经过以上2步操作即可启动HBase shell,在命令行输入:help,即可查看 HBase shell支持的命令。
(3)退出HBase shell:quit

3.HBase shell常用命令

名称命令表达式
创建表create ‘表名称’, ‘列族名称1’,‘列族名称2’,‘列族名 称N’
添加记录put ‘表名称’, ‘行名称’, ‘列名称:’, ‘值’
查看记录get ‘表名称’, ‘行名称’
查看表中的记录总数count ‘表名称’
删除记录delete ‘表名’ ,‘行名称’ , ‘列名称’
删除一张表先要屏蔽该表,才能对该表进行删除,第一步 disable ‘表名称’ 第二步 drop ‘表名称’
查看所有记录scan “表名称”
查看某个表某个列中 所有数据scan “表名称” , {COLUMNS=>‘列族名称:列名称’}
更新记录就是重写一遍进行覆盖
列出全部表list
得到表的描述describe ‘表名称’
查看表的状态exists ‘表名’;is_enabled ‘表名’;is_disabled ‘表名’
删除整行deleteall ‘表名’,‘行名’
清空表truncate ‘表名’

三、HBase组件、架构及运行原理

1.HBase基本组件

HMaste

  • 管理用户对Table的增、删、改、查操作
  • 管理RegionServer的负载均衡、调整Region的分布
  • 在Region Split后,将新Region分布到不同的RegionServer。
  • 在RegionServer宕机后,该RegionServer上所管理的Region 由HMaster进行重新分配。

RegionServer

  • RegionServer是HBase集群运行在每个工作节点上的服务组件
  • RegionServer维护Master分配给它的region,处理对这些region的IO请求
  • Region server负责切分在运行过程中变得过大的region

Region

  • Region可理解为关系型数据库中的“分区”
  • 处理RegionServer分配给它的任务

2.HBase架构

架构图
在这里插入图片描述

  • Client
    包含访问HBase的接口,client维护着一些cache 来加快对HBase的访问,比如region的位置信息

  • Zookeeper
    (1)保证任何时候,集群中只有一个running master
    (2)存贮所有Region的寻址入口
    (3)实时监控Region Server 的状态,将Region server 的上线和下线信息,实时通知给Master
    (4)存储HBase的schema,包括有哪些table,每个table有哪些column family

  • Master
    可以启动多个HMaster,通过Zookeeper的Master Election机制保证总有一个Master运行
    (1)为Region server 分配region
    (2)负责region server 的负载均衡
    (3)发现失效的region server 并重新分配其上的region

  • Region Server
    (1)维护Master 分配给它的region,处理对这些 region 的 IO 请求
    (2)负责切分在运行过程中变得过大的region

3.HBase组件单元

(1)表空间

  • 在关系数据库系统中,命名空间namespace指的是一个表的逻辑分组,同一组中的表有类似的用途.
  • 有两个系统内置的预定义命名空间(默认表空间):
    hbase:系统命名空间,用于包含hbase的内部表
    default:所有未指定命名空间的表都自动进入该命名空间

(2)表
HBase以表的形式存储数据,表在hdfs上以文件夹形式存

  • HBase表组成模型
    1)RowKey:是Byte array,是表中每条记录的“主键”,方便快速查找
    2)Column Family:列族,拥有一个名称(string),包含一个或者多个相关列
    3)Column:属于某一个columnfamily,Version Number:类型为Long,默认值是系统时间戳,可由用户自定义
    4)Value(Cell):Byte array

  • HBase表的物理属性
    1)Table中所有行都按照row key的字典序排列;
    2)Table在行的方向上分割为多个Region;
    3)Region按大小分割的,每个表开始只有一个region,随着数据增多,region不断增大,当增大到一个阀值的时候,region就会等分会两个新的region,之后会有越来越多的region;
    4)Region是HBase中分布式存储和负载均衡的最小单元,不同Region分布到不同RegionServer上。

(3)列族
hbase表中的每个列,都归属与某个列族。每个column family存储在HDFS上的一个单独文件中,必须在使用表之前定义。列名都以列族作为前缀。例如info:name,info:age都属于info这个列族。

(4)列
在使用中动态添加
例如name,age是列,属于info这个列族

(5)RowKey

  • Rowkey行键 (Rowkey)可以是任意字符串(最大长度是 64KB,实际应用中长度一般为 10-100bytes),在hbase内部,rowkey保存为字节数组,是hbase的key-value存储中的key。
  • RowKey特性:rowkey按字典顺序的从小到大排序

(6)ColumnKey
二进制值byte[],按字典顺序排序。是表中每条记录的“主键”,方便快速查找

(7)时间戳( Timestamp )
时间戳,每次数据操作对应的时间戳,可以看作是数据的version number。是一个 64 位整数

(8)value
一个未解释的字节数组byte[]。

四、HBase数据写入与查询流程

1.HBase写入数据流程

(1)Client通过Zookeeper调度获取表的元数据信息;
(2)Cilent通过rpc协议与RegionServer交互,通过-ROOT-表与.META.表找到对应的对应的Region;
(3)将数据写入HLog日志中,如出现意外可以同通过HLog恢复信息;
(4)将数据写入Region的MemStore中,当MemStore达到阈值开始溢写,将其中的数据Flush成一个StoreFile;
(5)MemStore不断生成新的StoreFile,当StoreFile的数量到达阈值后会出发Compact合并操作,将多个StoreFile合并成一个StoreFile;
(6)StoreFile文件会不断增大,当达到阈值后会出发Split操作,把当前的Region且分为两个新的Region。父Region会下线,两个子Region会被HMaster分配到相应的RegionServer。

2.HBase查询数据流程

(1)Client访问Zookeeper,从ZK获取-ROOT-表的位置信息,通过访问-ROOT-表获取.META.表的位置,然后确定数据所在的HRegion位置;
(2)Client访问HRegion所在的HRegionServer,通过HRegionServer获取需要查找的数据;
(3)Client到HRegion的中去查找数据,首先到MemStore中查找,查到直接返回;查不到就去ClockCache中查找,查到直接返回;再查不到就去StoreFile中读数据,把读到的数据存入BlockCache中再返回Client。

五、HBase的API和工具类

1.HBase API 简介

HBase访问接口说明
Native Java API最常规和高效的访问方式,适合Hadoop MapReduce Job并行批处理HBase表数据
HBase ShellHBase的命令行工具,最简单的接口,适合HBase管理使用
Thrift Gateway利用Thrift序列化技术,支持C++,PHP,Python等多种语言,适合其他异构系统在线访问HBase表数据
REST Gateway支持REST 风格的Http API访问HBase, 解除了语言限制
Pig可以使用Pig Latin流式编程语言来操作HBase中的数据,和Hive类似,本质最终也是编译成MapReduce Job来处理HBase表数据,适合做数据统计
Hive当前Hive的Release版本尚没有加入对HBase的支持,但在下一个版本Hive 0.7.0中将会支持HBase,可以使用类似SQL语言来访问HBase

2.HBase的Java接口

在这里插入图片描述
示例代码

package org.apache.hbase.hbase;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

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.KeyValue;
import org.apache.hadoop.hbase.MasterNotRunningException;
import org.apache.hadoop.hbase.ZooKeeperConnectionException;
import org.apache.hadoop.hbase.client.Delete;
import org.apache.hadoop.hbase.client.Get;
import org.apache.hadoop.hbase.client.HBaseAdmin;
import org.apache.hadoop.hbase.client.HTable;
import org.apache.hadoop.hbase.client.Put;
import org.apache.hadoop.hbase.client.Result;
import org.apache.hadoop.hbase.client.ResultScanner;
import org.apache.hadoop.hbase.client.Scan;
import org.apache.hadoop.hbase.util.Bytes;

public class hbase {

  private static final String TABLE_NAME = "demo_table";

    public static Configuration conf = null;
    public HTable table = null;
    public HBaseAdmin admin = null;

    static {
      conf = HBaseConfiguration.create();
      System.out.println(conf.get("hbase.zookeeper.quorum"));
    }

    /**
     * 创建一张表
     */
    public static void creatTable(String tableName, String[] familys)
        throws Exception {
      HBaseAdmin admin = new HBaseAdmin(conf);
      if (admin.tableExists(tableName)) {
        System.out.println("table already exists!");
      } else {
        HTableDescriptor tableDesc = new HTableDescriptor(tableName);
        for (int i = 0; i < familys.length; i++) {
          tableDesc.addFamily(new HColumnDescriptor(familys[i]));
        }
        admin.createTable(tableDesc);
        System.out.println("create table " + tableName + " ok.");
      }
    }

    /**
     * 删除表
     */
    public static void deleteTable(String tableName) throws Exception {
      try {
        HBaseAdmin admin = new HBaseAdmin(conf);
        admin.disableTable(tableName);
        admin.deleteTable(tableName);
        System.out.println("delete table " + tableName + " ok.");
      } catch (MasterNotRunningException e) {
        e.printStackTrace();
      } catch (ZooKeeperConnectionException e) {
        e.printStackTrace();
      }
    }

    /**
     * 插入一行记录
     */
    public static void addRecord(String tableName, String rowKey,
        String family, String qualifier, String value) throws Exception {
      try {
        HTable table = new HTable(conf, tableName);
        Put put = new Put(Bytes.toBytes(rowKey));
        put.add(Bytes.toBytes(family), Bytes.toBytes(qualifier),
            Bytes.toBytes(value));
        table.put(put);
        System.out.println("insert recored " + rowKey + " to table "
            + tableName + " ok.");
      } catch (IOException e) {
        e.printStackTrace();
      }
    }

    /**
     * 删除一行记录
     */
    public static void delRecord(String tableName, String rowKey)
        throws IOException {
      HTable table = new HTable(conf, tableName);
      List list = new ArrayList();
      Delete del = new Delete(rowKey.getBytes());
      list.add(del);
      table.delete(list);
      System.out.println("del recored " + rowKey + " ok.");
    }

    /**
     * 查找一行记录
     */
    public static void getOneRecord(String tableName, String rowKey)
        throws IOException {
      HTable table = new HTable(conf, tableName);
      Get get = new Get(rowKey.getBytes());
      Result rs = table.get(get);
      for (KeyValue kv : rs.raw()) {
        System.out.print(new String(kv.getRow()) + " ");
        System.out.print(new String(kv.getFamily()) + ":");
        System.out.print(new String(kv.getQualifier()) + " ");
        System.out.print(kv.getTimestamp() + " ");
        System.out.println(new String(kv.getValue()));
      }
    }

    /**
     * 显示所有数据
     */
    public static void getAllRecord(String tableName) {
      try {
        HTable table = new HTable(conf, tableName);
        Scan s = new Scan();
        ResultScanner ss = table.getScanner(s);
        for (Result r : ss) {
          for (KeyValue kv : r.raw()) {
            System.out.print(new String(kv.getRow()) + " ");
            System.out.print(new String(kv.getFamily()) + ":");
            System.out.print(new String(kv.getQualifier()) + " ");
            System.out.print(kv.getTimestamp() + " ");
            System.out.println(new String(kv.getValue()));
          }
        }
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
    
    
  public static void main(String[] args) {
      // TODO Auto-generated method stub
       try {
            String tablename = "201712320**";
            String[] familys = { "grade", "course" };
            hbase.creatTable(tablename, familys);

            // add record wsn001
            hbase.addRecord(tablename, "wsn001", "grade", "", "大三");
            hbase.addRecord(tablename, "wsn001", "course", "分布式数据库", "100");
            hbase.addRecord(tablename, "wsn001", "course", "虚拟化原理", "100");
            hbase.addRecord(tablename, "wsn001", "course", "大数据处理技术", "100");
            // add record wsn102
            hbase.addRecord(tablename, "wsn102", "grade", "", "大四");
            hbase.addRecord(tablename, "wsn102", "course", "软件工程", "100");

            System.out.println("===========get one record========");
            hbase.getOneRecord(tablename, "wsn001");

            System.out.println("===========show all record========");
            hbase.getAllRecord(tablename);

            System.out.println("===========del one record========");
            hbase.delRecord(tablename, "wsn102");
            hbase.getAllRecord(tablename);

            System.out.println("===========show all record========");
            hbase.getAllRecord(tablename);
          } catch (Exception e) {
            e.printStackTrace();
          }
        }}

3.HBase的工具类

HTable是一个比较重的对象,比如加载配置文件,连接ZK,查询meta表等等,高并发的时候影响系统的性能,因此引入了“池”的概念
HTablePool定义

public class TableConnection {
	private TableConnection(){		
	}
private static HConnection connection =null;	
 public static HConnection getConnection(){	
if(connection==null){
ExecutorService pool =  Executors.newFixedThreadPool(10);
Configuration conf = HBaseConfiguration.create();	
 conf.set("hbase.zookeeper.quorum", "192.168.1.81:2181,192.168.1.82:2181");	
 try {			
  connection=HConnectionManager.createConnection(conf,pool);	
} catch (IOException e) {
 }			
 }
 return connection;		
}
}

使用

Put put =new Put(Bytes.toBytes("row")); 
TableConnection.getConnection().getTable("tableName").put(put);

4.HBase过滤器

过滤器筛选的数据能够细化到具体的一个存储单元格上(由行键,列明,时间戳定位),多条件查询。过滤器在服务器端执行。

六、HBase调优

1.Rowkey优化的主要方式

(1)生成随机数、hash、散列值
(2)字符串反转
(3)字符串拼接

2.HBase优化分配堆内存

HBase 操作过程中需要大量的内存开销,毕竟 Table 是可以缓存在内存中的,一般会分配整个可用内存的 70%给 HBase 的 Java 堆。但是不建议分配非常大的堆内存,因为 GC 过 程持续太久会导致 RegionServer 处于长期不可用状态,一般 16~48G 内存就可以了,如果因 为框架占用内存过高导致系统内存不足,框架一样会被系统服务拖死。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

达娃里氏

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

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

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

打赏作者

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

抵扣说明:

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

余额充值