Hbase入门到实战-连载一(基本概念&集群安装&基本使用)

Hadoop的局限

HBase 是一个构建在 Hadoop 文件系统之上的面向列的数据库管理系统。

要想明白为什么产生 HBase,就需要先了解一下 Hadoop 存在的限制?Hadoop 可以通过 HDFS 来存储结构化、半结构甚至非结构化的数据,它是传统数据库的补充,是海量数据存储的最佳方法,它针对大文件的存储,批量访问和流式访问都做了优化,同时也通过多副本解决了容灾问题。

但是 Hadoop 的缺陷在于它只能执行批处理,并且只能以顺序方式访问数据,这意味着即使是最简单的工作,也必须搜索整个数据集,无法实现对数据的随机访问。实现数据的随机访问是传统的关系型数据库所擅长的,但它们却不能用于海量数据的存储。在这种情况下,必须有一种新的方案来解决海量数据存储和随机访问的问题,HBase 就是其中之一 (HBase,Cassandra,couchDB,Dynamo 和 MongoDB 都能存储海量数据并支持随机访问)。

注:数据结构分类:

  • 结构化数据:即以关系型数据库表形式管理的数据;
  • 半结构化数据:非关系模型的,有基本固定结构模式的数据,例如日志文件、XML 文档、JSON 文档、Email 等;
  • 非结构化数据:没有固定模式的数据,如 WORD、PDF、PPT、EXL,各种格式的图片、视频等。

HBase简介

HBase 是一个构建在 Hadoop 文件系统之上的面向列的数据库管理系统。

HBase 是一种类似于 Google’s Big Table 的数据模型,它是 Hadoop 生态系统的一部分,它将数据存储在 HDFS 上,客户端可以通过 HBase 实现对 HDFS 上数据的随机访问。它具有以下特性:

  • 不支持复杂的事务,只支持行级事务,即单行数据的读写都是原子性的;
  • 由于是采用 HDFS 作为底层存储,所以和 HDFS 一样,支持结构化、半结构化和非结构化的存储;
  • 支持通过增加机器进行横向扩展;
  • 支持数据分片;
  • 支持 RegionServers 之间的自动故障转移;
  • 易于使用的 Java 客户端 API;
  • 支持 BlockCache 和布隆过滤器;
  • 过滤器支持谓词下推。

HBase Table

HBase 是一个面向  的数据库管理系统,这里更为确切的而说,HBase 是一个面向 列族 的数据库管理系统。表 schema 仅定义列族,表具有多个列族,每个列族可以包含任意数量的列,列由多个单元格(cell )组成,单元格可以存储多个版本的数据,多个版本数据以时间戳进行区分

Row Key

Row Key 是用来检索记录的主键。想要访问 HBase Table 中的数据,只有以下三种方式:

  • 通过指定的 Row Key 进行访问;

  • 通过 Row Key 的 range 进行访问,即访问指定范围内的行;

  • 进行全表扫描。

Row Key 可以是任意字符串,存储时数据按照 Row Key 的字典序进行排序。这里需要注意以下两点:

  • 因为字典序对 Int 排序的结果是 1,10,100,11,12,13,14,15,16,17,18,19,2,20,21,…,9,91,92,93,94,95,96,97,98,99。如果你使用整型的字符串作为行键,那么为了保持整型的自然序,行键必须用 0 作左填充。

  • 行的一次读写操作时原子性的 (不论一次读写多少列)。

Column Family(列族)

HBase 表中的每个列,都归属于某个列族。列族是表的 Schema 的一部分,所以列族需要在创建表时进行定义。列族的所有列都以列族名作为前缀,例如personal:namepersonal:city 都属于 personal 这个列族。

Column Qualifier(列限定符)

列限定符,你可以理解为是具体的列名,例如 personal:namepersonal:city 都属于 personal 这个列族,它们的列限定符分别是 name 和 city。需要注意的是列限定符不是表 Schema 的一部分,你可以在插入数据的过程中动态创建列

Column(列)

HBase 中的列由列族和列限定符组成,它们由 :(冒号) 进行分隔,即一个完整的列应该表述为 列族名 :列限定符

Cell

Cell 是行,列族和列限定符的组合,并包含值和时间戳。你可以等价理解为关系型数据库中由指定行和指定列确定的一个单元格,但不同的是 HBase 中的一个单元格是由多个版本的数据组成的,每个版本的数据用时间戳进行区分。

Timestamp(时间戳)

HBase 中通过 row key 和 column 确定的为一个存储单元称为 Cell。每个 Cell 都保存着同一份数据的多个版本。版本通过时间戳来索引,时间戳的类型是 64 位整型,时间戳可以由 HBase 在数据写入时自动赋值,也可以由客户显式指定。每个 Cell 中,不同版本的数据按照时间戳倒序排列,即最新的数据排在最前面

字典序(dictionary order),又称 字母序(alphabetical order),原意是表示英文单词在字典中的先后顺序,在计算机领域中扩展成两个任意字符串的大小关系。

下图为 HBase 中一张表的: 

Hbase 的表具有以下特点:

  • 容量大:一个表可以有数十亿行,上百万列;

  • 面向列:数据是按照列存储,每一列都单独存放,数据即索引,在查询时可以只访问指定列的数据,有效地降低了系统的 I/O 负担;

  • 稀疏性:空 (null) 列并不占用存储空间,表可以设计的非常稀疏 ;

  • 数据多版本:每个单元中的数据可以有多个版本,按照时间戳排序,新的数据在最上面;

  • 存储类型:所有数据的底层存储格式都是字节数组 (byte[])

存储结构

Regions

HBase Table 中的所有行按照 Row Key 的字典序排列。HBase Tables 通过行键的范围 (row key range) 被水平切分成多个 Region, 一个 Region 包含了在 start key 和 end key 之间的所有行。

 每个表一开始只有一个 Region,随着数据不断增加,Region 会不断增大,当增大到一个阀值的时候,Region 就会等分为两个新的 Region。当 Table 中的行不断增多,就会有越来越多的 Region

Region 是 HBase 中分布式存储和负载均衡的最小单元。这意味着不同的 Region 可以分布在不同的 Region Server 上。

 

Region Server

 Region Server 运行在 HDFS 的 DataNode 上。它具有以下组件:

  • WAL(Write Ahead Log,预写日志)用于存储尚未进持久化存储的数据记录,以便在发生故障时进行恢复。
  • BlockCache:读缓存。它将频繁读取的数据存储在内存中,如果存储不足,它将按照 最近最少使用原则 清除多余的数据
  • MemStore:写缓存。它存储尚未写入磁盘的新数据,并会在数据写入磁盘之前对其进行排序。每个 Region 上的每个列族都有一个 MemStore
  • HFile :将行数据按照 Key\Values 的形式存储在文件系统上。

 Region Server 存取一个子表时,会创建一个 Region 对象,然后对表的每个列族创建一个 Store 实例,每个 Store 会有 0 个或多个 StoreFile 与之对应,每个 StoreFile 则对应一个 HFile,HFile 就是实际存储在 HDFS 上的文件。

Hbase系统架构

系统架构

HBase 系统遵循 Master/Salve 架构,由三种不同类型的组件组成:

Zookeeper

  1. 保证任何时候,集群中只有一个 Master;

  2. 存贮所有 Region 的寻址入口;

  3. 实时监控 Region Server 的状态,将 Region Server 的上线和下线信息实时通知给 Master;

  4. 存储 HBase 的 Schema,包括有哪些 Table,每个 Table 有哪些 Column Family 等信息。

Master

  1. 为 Region Server 分配 Region ;

  2. 负责 Region Server 的负载均衡 ;

  3. 发现失效的 Region Server 并重新分配其上的 Region;

  4. GFS 上的垃圾文件回收;

  5. 处理 Schema 的更新请求。

Region Server

  1. Region Server 负责维护 Master 分配给它的 Region ,并处理发送到 Region 上的 IO 请求;

  2. Region Server 负责切分在运行过程中变得过大的 Region。

组件间的协作

HBase 使用 ZooKeeper 作为分布式协调服务来维护集群中的服务器状态。 Zookeeper 负责维护可用服务列表,并提供服务故障通知等服务:

  • 每个 Region Server 都会在 ZooKeeper 上创建一个临时节点,Master 通过 Zookeeper 的 Watcher 机制对节点进行监控,从而可以发现新加入的 Region Server 或故障退出的 Region Server;

  • 所有 Masters 会竞争性地在 Zookeeper 上创建同一个临时节点,由于 Zookeeper 只能有一个同名节点,所以必然只有一个 Master 能够创建成功,此时该 Master 就是主 Master,主 Master 会定期向 Zookeeper 发送心跳。备用 Masters 则通过 Watcher 机制对主 HMaster 所在节点进行监听;

  • 如果主 Master 未能定时发送心跳,则其持有的 Zookeeper 会话会过期,相应的临时节点也会被删除,这会触发定义在该节点上的 Watcher 事件,使得备用的 Master Servers 得到通知。所有备用的 Master Servers 在接到通知后,会再次去竞争性地创建临时节点,完成主 Master 的选举

述数据的读写流程简

写入数据的流程

  1. Client 向 Region Server 提交写请求;

  2. Region Server 找到目标 Region;

  3. Region 检查数据是否与 Schema 一致;

  4. 如果客户端没有指定版本,则获取当前系统时间作为数据版本;

  5. 将更新写入 WAL Log;

  6. 将更新写入 Memstore;

  7. 判断 Memstore 存储是否已满,如果存储已满则需要 flush 为 Store Hfile 文件。

读取数据的流程

以下是客户端首次读写 HBase 上数据的流程:

  1. 客户端从 Zookeeper 获取 META 表所在的 Region Server;

  2. 客户端访问 META 表所在的 Region Server,从 META 表中查询到访问行键所在的 Region Server,之后客户端将缓存这些信息以及 META 表的位置;

  3. 客户端从行键所在的 Region Server 上获取数据。

如果再次读取,客户端将从缓存中获取行键所在的 Region Server。这样客户端就不需要再次查询 META 表,除非 Region 移动导致缓存失效,这样的话,则将会重新查询并更新缓存。

注:META 表是 HBase 中一张特殊的表,它保存了所有 Region 的位置信息,META 表自己的位置信息则存储在 ZooKeeper 上。

集群安装

前提:已经配置好了JDK,zookeeper环境,如果没有可以看我的zookeeper专栏

官方下载地址

Index of /dist/hbase

本次软件的百度网盘地址

链接:https://pan.baidu.com/s/1utT4wpnNZkvN2dlhO7GrCw 
提取码:yyds 


重点:

安装之前一定要保证集群之间的时间一致,因为Hbase存储的数据和时间戳有关,集群之间的通信也和时间戳有关,如果时间不同步那么会失败

时间同步

sudo yum install -y ntpdate
sudo ntpdate 120.24.81.91

其他几个NTP Server

  • cn.pool.ntp.org
  • asia.pool.ntp.org
  • asia.pool.ntp.org
  • 也可以自己搭建NTP Server

将系统时间写入到系统硬件当中,避免重启服务器时间覆盖

 显示hardwareclock系统硬件时间

sudo hwclock

将系统时间写入到系统硬件当中

sudo hwclock -w

设定计划任务同步网络时间

crontab格式如下:

# For details see man 4 crontabs
# Example of job definition:
# .---------------- minute (0 - 59)
# |  .------------- hour (0 - 23)
# |  |  .---------- day of month (1 - 31)
# |  |  |  .------- month (1 - 12) OR jan,feb,mar,apr ...
# |  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# |  |  |  |  |
# *  *  *  *  *  command to be executed
crontab -e
10 5 * * * root ntpdate us.pool.ntp.org;hwclock -w

这样每天5:10自动进行网络校时,并同时更新BIOS的时间

安装

tar -zxvf hbase-2.4.9-bin.tar.gz

配置环境变量

sudo vi /etc/profile.d/my_env.sh
#HBASE_HOME
export HBASE_HOME=/home/bigdata/module/hbase-2.4.9
export PATH=$PATH:$HBASE_HOME/bin
source /etc/profile.d/my_env.sh

修改配置文件

hbase-site.xml

<configuration>
  <!--
    The following properties are set for running HBase as a single process on a
    developer workstation. With this configuration, HBase is running in
    "stand-alone" mode and without a distributed file system. In this mode, and
    without further configuration, HBase and ZooKeeper data are stored on the
    local filesystem, in a path under the value configured for `hbase.tmp.dir`.
    This value is overridden from its default value of `/tmp` because many
    systems clean `/tmp` on a regular basis. Instead, it points to a path within
    this HBase installation directory.

    Running against the `LocalFileSystem`, as opposed to a distributed
    filesystem, runs the risk of data integrity issues and data loss. Normally
    HBase will refuse to run in such an environment. Setting
    `hbase.unsafe.stream.capability.enforce` to `false` overrides this behavior,
    permitting operation. This configuration is for the developer workstation
    only and __should not be used in production!__

    See also https://hbase.apache.org/book.html#standalone_dist
  -->
  <!--
   这里是hdfs的namenode节点的位置
  -->
  <property>
    <name>hbase.rootdir</name>
    <value>hdfs://hadoop102:8020/HBase</value>
  </property>
  <!--
   是否集群工作
  -->
  <property>
    <name>hbase.cluster.distributed</name>
    <value>true</value>
  </property>

  <!--
   这里是zookeeper节点的位置
  -->
  <property>
    <name>hbase.zookeeper.quorum</name>
    <value>hadoop102,hadoop103,hadoop104</value>
  </property>
  
  <!-- 注意:为了开启hbase的namespace和phoenix的schema的映射,在程序中需要加这个配置文件,另外在linux服务上,也需要在hbase以及phoenix的hbase-site.xml配置文件中,
加上以上两个配置,并使用xsync进行同步-->
    <property>
        <name>phoenix.schema.isNamespaceMappingEnabled</name>
        <value>true</value>
    </property>

    <property>
        <name>phoenix.schema.mapSystemTablesToNamespace</name>
        <value>true</value>
    </property>


</configuration>

 regionservers (配置regionservers的地址用来群起集群的时候使用)

hadoop102
hadoop103
hadoop104

分发安装包到其他机器

./xsync ../module/hbase-2.4.9/

分发的脚本xsync

#!/bin/bash
#1. 判断参数个数
if [ $# -lt 1 ]
then
  echo Not Enough Arguement!
  exit;
fi
#2. 遍历集群所有机器
for host in hadoop102 hadoop103 hadoop104
do
  echo ====================  $host  ====================
  #3. 遍历所有目录,挨个发送
  for file in $@
  do
    #4 判断文件是否存在
    if [ -e $file ]
    then
      #5. 获取父目录
      pdir=$(cd -P $(dirname $file); pwd)
      #6. 获取当前文件的名称
      fname=$(basename $file)
      ssh $host "mkdir -p $pdir"
      rsync -av $pdir/$fname $host:$pdir
    else
      echo $file does not exists!
    fi
  done
done
  • 启动hadoop
  • 启动zookeeper

集群启动脚本hbase.sh(在那台机器执行start-hbase.sh那台就是master)

#!/bin/bash
case $1 in
"start"){
    for i in hadoop102
    do
        echo " --------启动 $i hbase-------"
        ssh $i "/home/bigdata/module/hbase-2.4.9/bin/start-hbase.sh"
    done
};;
"stop"){
    for i in hadoop102
    do
        echo " --------停止 $i hbase-------"
        ssh $i "/home/bigdata/module/hbase-2.4.9/bin/stop-hbase.sh"
    done
};;
esac
chmod 744 hbase.sh
./hbase.sh start

Hbase 常用 Shell 命令

基本命令

打开 Hbase Shell:

hbase shell

获取帮助

# 获取帮助
help
# 获取命令的详细信息
help 'status'

查看服务器状态

status

查看版本信息

version

表的操作

查看所有表

list

创建表

命令格式: create '表名称', '列族名称 1','列族名称 2','列名称 N'

# 创建一张名为Student的表,包含基本信息(baseInfo)、学校信息(schoolInfo)两个列族
create 'Student','baseInfo','schoolInfo'

查看表的基本信息

命令格式:desc '表名'

describe 'Student'

表的启用/禁用

enable 和 disable 可以启用/禁用这个表,is_enabled 和 is_disabled 来检查表是否被禁用

# 禁用表
disable 'Student'
# 检查表是否被禁用
is_disabled 'Student'
# 启用表
enable 'Student'
# 检查表是否被启用
is_enabled 'Student'

检查表是否存在

exists 'Student'

 删除表

# 删除表前需要先禁用表
disable 'Student'
# 删除表
drop 'Student'

增删改

添加列族

命令格式: alter '表名', '列族名'

alter 'Student', 'teacherInfo'

删除列族

命令格式:alter '表名', {NAME => '列族名', METHOD => 'delete'}

alter 'Student', {NAME => 'teacherInfo', METHOD => 'delete'}

更改列族存储版本的限制

默认情况下,列族只存储一个版本的数据,如果需要存储多个版本的数据,则需要修改列族的属性。修改后可通过 desc 命令查看。

alter 'Student',{NAME=>'baseInfo',VERSIONS=>3}

插入数据

命令格式:put '表名', '行键','列族:列','值'

注意:如果新增数据的行键值、列族名、列名与原有数据完全相同,则相当于更新操作

put 'Student', 'rowkey1','baseInfo:name','tom'
put 'Student', 'rowkey1','baseInfo:birthday','1990-01-09'
put 'Student', 'rowkey1','baseInfo:age','29'
put 'Student', 'rowkey1','schoolInfo:name','Havard'
put 'Student', 'rowkey1','schoolInfo:localtion','Boston'

put 'Student', 'rowkey2','baseInfo:name','jack'
put 'Student', 'rowkey2','baseInfo:birthday','1998-08-22'
put 'Student', 'rowkey2','baseInfo:age','21'
put 'Student', 'rowkey2','schoolInfo:name','yale'
put 'Student', 'rowkey2','schoolInfo:localtion','New Haven'

put 'Student', 'rowkey3','baseInfo:name','maike'
put 'Student', 'rowkey3','baseInfo:birthday','1995-01-22'
put 'Student', 'rowkey3','baseInfo:age','24'
put 'Student', 'rowkey3','schoolInfo:name','yale'
put 'Student', 'rowkey3','schoolInfo:localtion','New Haven'

put 'Student', 'wrowkey4','baseInfo:name','maike-jack'

获取指定行、指定行中的列族、列的信息

# 获取指定行中所有列的数据信息
get 'Student','rowkey3'
# 获取指定行中指定列族下所有列的数据信息
get 'Student','rowkey3','baseInfo'
# 获取指定行中指定列的数据信息
get 'Student','rowkey3','baseInfo:name'

删除指定行、指定行中的列

# 删除指定行
deleteall 'Student','rowkey3'
# 删除指定行中指定列的数据
delete 'Student','rowkey3','baseInfo:name'

查询

hbase 中访问数据有两种基本的方式:

  • 按指定 rowkey 获取数据:get 方法;

  • 按指定条件获取数据:scan 方法。

scan 可以设置 begin 和 end 参数来访问一个范围内所有的数据。get 本质上就是 begin 和 end 相等的一种特殊的 scan。

Get查询

# 获取指定行中所有列的数据信息
get 'Student','rowkey3'
# 获取指定行中指定列族下所有列的数据信息
get 'Student','rowkey3','baseInfo'
# 获取指定行中指定列的数据信息
get 'Student','rowkey3','baseInfo:name'

查询整表数据

scan 'Student'

查询指定列簇的数据

scan 'Student', {COLUMN=>'baseInfo'}

条件查询

# 查询指定列的数据
scan 'Student', {COLUMNS=> 'baseInfo:birthday'}

除了列 (COLUMNS) 修饰词外,HBase 还支持 Limit(限制查询结果行数),STARTROWROWKEY 起始行,会先根据这个 key 定位到 region,再向后扫描)、STOPROW(结束行)、TIMERANGE(限定时间戳范围)、VERSIONS(版本数)、和 FILTER(按条件过滤行)等。

如下代表从 rowkey2 这个 rowkey 开始,查找下两个行的最新 3 个版本的 name 列的数据:

scan 'Student', {COLUMNS=> 'baseInfo:name',STARTROW => 'rowkey2',STOPROW => 'wrowkey4',LIMIT=>2, VERSIONS=>3}

条件过滤

Filter 可以设定一系列条件来进行过滤。如我们要查询值等于 24 的所有数据:

scan 'Student', FILTER=>"ValueFilter(=,'binary:24')"

值包含 yale 的所有数据:

scan 'Student', FILTER=>"ValueFilter(=,'substring:yale')"

列名中的前缀为 birth 的:

scan 'Student', FILTER=>"ColumnPrefixFilter('birth')"

FILTER 中支持多个过滤条件通过括号、AND 和 OR 进行组合:

# 列名中的前缀为birth且列值中包含1998的数据
scan 'Student', FILTER=>"ColumnPrefixFilter('birth') AND ValueFilter ValueFilter(=,'substring:1998')"

PrefixFilter 用于对 Rowkey 的前缀进行判断:

scan 'Student', FILTER=>"PrefixFilter('wr')"

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

工作变成艺术

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

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

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

打赏作者

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

抵扣说明:

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

余额充值