Hbase

一. Hbase的概述

1.1 Hbase简介

1) 简要介绍

1. Hbase是一个hadoop数据库
2. 是一个非关系型数据库,具有分布式,良好的扩展性,面向列式存储的数据库
3. 灵感来源与Google的《Big Table》论文,java语言编写,开源

2) 特性

- 强一致性读写,适合统计分析聚合类任务
- 自动分片
- 自动RegionServer故障转移
- hbase存储是基于HDFS的
- Hbase可以与MapReduce进行整合,进行数据分析
- Hbase还提供java语言的客户端接口
- Thrift/REST API,也提供了非java语言的连接操作
- Hbase提供了快缓存和布隆过滤器等机制来提高查询效率等

3) 使用场景

1. 当数据量特别大的时候
2. 集群节点数多以10个的情况
3. 以及不需要具有事务,高级查询语言等功能的情况下

1.2 Hbase的表的模型

1.2.1 关系型数据的表的模型

1. 表的模型是面向行式存储的,也就是每条记录都是紧凑的挨着的
2. 优点
    - 用户再插入数据的时候,效率特别高,只是追加操作
    - 查询操作时,效率高例如(select *)
    - 结构清晰,每一行的列的数据都是固定的
    - 支持ACID事务
3. 缺点
    - 一但数据表中存储数据后,修改表的结构就会 变得特别困难
    - 如果我们想扩展字段的时候,会对表的结构产生影响
    - 即使某一行中的某个字段没有赋值,也要使用null填充
    - 一旦涉及多张表,因为数据表存在复杂关系,管理非常不方便
    - 一旦面对海量数据的处理时,读写性能特别差,尤其是高并发这一块

1.2.2 Hbase的表模型

1. Hbase是面向列是存储的
2. 定义表的时候不需要指定列明,列类型,只需要指定列族名即可
3. 数据实际上的是按照key:value的形式存储的,一个kv被称为一个cell(单元格),每个单元格之后都对应一个版本号,版本号就是时间戳,一个k可以对应多个版本
4. 列族:为了方便管理多个key:value
5. rowkey:区分不同事物的key:value
6. region:为了管理表的数据,一个region对应一张表或是一个表的是一部分
7. Hbase中的数据都是byte[]
8. Hbase会在内存中进行排序
    查询时:先按照rowkey排序,然后是列族名排序,再按照key进行排序
    插入数据时,先按照rowkey进行排序,再按照key进行排序,都是字典排序规则

1.3Hbase的体系结构

1. Client:Hbase的客户端
    - Hbase提供了客户端使用API接口
    - API里还维护了一个缓存机制,用于加快客户端的访问效率
2. Zookeeper
    - 维护者Hbase的高可用,保证只有一个活跃的Hmaster
    - 维护者regionServer的动态上下线的感知
    - 维护者所有的region的地址以及部分元数据
3. Hmaster
    - 只要管理者region的负载均衡
        1) 表的第一个region的分配位置
        2) region过大之后进行切分,形成新的region重新分配
        3) regionServer宕机后的region的重新分配
    - hdfs上的垃圾回收
    - 处理新的schama的维护(namespance的创建和删除等)
4. regionServer
    - 主要就是管理本节点上的所有region
    - 处理客户端的读写请求
    - 负责hlog和storefile的读写
5. Region
    - 实际上就是表,或者是表的一部分
    - 本质就是region下的子目录
6. store
    - 一个列族对应一个store
    - 本质:在region目录下的子目录
7. metastore
    - 一个store对应一个metastore(写缓存),默认(128)
8. Hfile/StoreFile
    - 当metastore达到阈值的时候(128M,40%,1小时)就会被flush出来,形成一个storefile
9. hlog
    - 一个regionServer上维护着一个hlog文件,以WAL格式记录这客户端的操作,防止宕机止呕丢失数据,然后可以重演一次,一便找回数据

二. 完全分布式的搭建

2.1 注意事项

必须配置好集群的免密登录认证
必须配置时间同步。保证集群节点的时间差不能超过30秒,否则regionserver启动失败

2.2 上传,解压,配置环境变量

tar -zxvf hbase-1.2.1-bin.tar.gz -C /usr/local/
cd /usr/local/
mv hbase-1.2.1/ hbase
vim /etc/profile
.......省略.......
#hbase environment
export HBASE_HOME=/usr/local/hbase
export PATH=$HBASE_HOME/bin:$PATH
​
source /etc/profile

2.3配置hbase-env.sh环境脚本

vi $HBASE_HOME/conf/hbase-env.sh
​
#找到下面内容,解开注释,添加具体路径
​
# The java implementation to use.  Java 1.7+ required.
export JAVA_HOME=/usr/local/jdk
​
# Tell HBase whether it should manage it's own instance of Zookeeper or not.
export HBASE_MANAGES_ZK=false       #禁止内置zookeeper

步骤3):配置hbase-site.xml文件

<configuration>
   <!-- 指定hbase在HDFS上存储的路径 -->
   <property>
      <name>hbase.rootdir</name>
      <value>hdfs://192.168.10.101:8020/hbase</value>
   </property>  
   <!-- 指定hbase是分布式的 -->
   <property>
      <name>hbase.cluster.distributed</name>
      <value>true</value>
   </property>
   <!-- 指定zk的地址,多个用“,”分割 -->
   <property>
      <name>hbase.zookeeper.quorum</name>
      <value>192.168.10.101:2181,192.168.10.102:2181,192.168.10.103:2181</value>
   </property>
   <!--将属性hbase.unsafe.stream.capability.enforce 改为true -->
   <property>
      <name>hbase.unsafe.stream.capability.enforce</name>
      <value>true</value>
   </property>
   <!-- 取消内存检查 -->
   <property>
      <name>hbase.table.sanity.checks</name>
      <value>false</value>
   </property>
</configuration>

步骤4):配置regionservers文件,添加regionserver所在机器的host

vi $HBASE_HOME/conf/regionservers
​
删除localhost
添加:
    192.168.10.101
    192.168.10.102
    192.168.10.103

步骤5):配置备份hmaster: 创建backup-masters文件

cd $HBASE_HOME/conf/
echo "qianfeng02">> backup-masters

步骤6): 将hadoop的core-site.xml和hdfs-site.xml拷贝到hbase的conf目录下

cp $HADOOP_HOME/etc/hadoop/{core-site.xml,hdfs-site.xml} $HBASE_HOME/conf/

步骤7):同步到其他节点上

scp -r /usr/local/hbase 192.168.10.102:/usr/local
scp -r /usr/local/hbase 192.168.10.103:/usr/local
scp /etc/profile 192.168.10.102:/etc/
scp /etc/profile 192.168.10.103:/etc/
​
注意:
     重新引导一下各个节点的环境变量配置情况

2.3.3 启动集群

启动顺序如下:

第一步:必须先启动hdfs和zookeeper

zkServer.sh start
zkServer.sh start
zkServer.sh start
​
别忘记:zkServer.sh status查看状态
​
start-dfs.sh

第二步:启动hbase的守护进程

start-hbase.sh

第三步:检查相关进程

方式1: jps
方式2: webui  ---> 192.168.10.101:16010

2.3.4 客户端连接集群

1)hbase本身自己就提供了一个命令行连接工具

hbase shell

2)可以使用java语言调用API接口连接

三. Hbase的shell

hbase(main): > help      查看所有的命令组及其命令 名称
hbase(main): > help 'COMMAND GROUPNAME'  查看命令组里的命令用法
hbase(main): > help 'COMMAND'  查看指定的命令用法

3.1 namespace的DDL

1. 列出命令空间: list_namespace
2. 创建命名空间: create_namespace
3. 描述命名空间: describe_namespace
4. 修改命名空间: alter_namespace
5. 删除命名空间: drop_namespace

3.2 table的DDL

创建表
表结构的查看: list,list_namespace_tables,describe
表结构的修改: alter(对列族的增加,或者是列族)
表结构的删除: disable,disable_all,drop,drop_all

3.3 table的CRUD

表数据的增加: put
表数据的查看: scan,get
表数据的删除: delete,truncate

四. Hbase的工作机制

4.1 habse的寻址机制

1. 先访问当前节点缓存,看有没有region的信息
2. 如果没有访问zookeeper,找到meta的表的信息
3. 访问meta表,找到自己想要找的数据在哪儿,拿到region的源数据
4. 去管理region的regionServer,找到具体的region

4.2 hbase的存储机制

1. 通过寻址流程找到具体的region
2. 将单元格存储到store对应的metastore中
3. 排序:按照rowkey升序,key升序,timestamp降序
4. 达到flush的阈值时,开始flush,生成storefile,然后youstore来维护n个storefile的索引信息
5. 当storefile达到阈值的时候,就会进行合并,合并期间会进行排序,还会进行真正的删除(删除老版本)和修改操作(将有delete标记的单元格删除)
6. 当storefile达到大小阈值的时候,就会触发split操作,将数据尽量做到平均分配为两个region,旧的region下线,新的region上线,由hmaster来重新进行负载均衡

4.3 名词解释

flush
    当memstore达到阈值是,将内存中的数据冲刷成文件
compact
    当storefile达到数量阈值时,进行合并操作
spilt
    当文件达到大小阈值的时候,会对region进行切分

4.4 hbase的读写流程

4.4.1 hbase的读流程

1. 客户端请求zookeeper,获取meta表的位置信息
2. 客户端跳转到meta的表,获取要访问的表的具体region位置
3. 客户端跳转到具体region所在的regionserver,找到该region
4. 访问对应的store下的memstore(写缓存),日过有数据就返回,如果没有数据,就访问regionserver的对应读缓存,如果没有数据,在访问磁盘,然后数据返回给客户端,并保存到读缓存中,方便下次读取

4.4.2 hbase的写流程

1. 客户端请求zookeeper,获取meta的位置信息
2. 客户端跳到meta表吗,获取要访问的表的具体region的位置
3. 客户端跳转到具体region的所在的regionserver的位置,找到region,将单元格写入对应的store的metstore
4. 在memstore里进行排序(rowkey升序,key升序,timestamp降序)
5. 如果达到memstore的阈值,就会flush成storefile文件,由store进行管理索引信息
6. 如果storefile数量达到阈值是,会进行合并操作(排序,实际的删除和修改)
7.  如果合并成的文件达到大小阈值时,会进行切分,造成region的切分(旧region下线,两个新region生成)

4.5 布隆过滤器

4.5.1 简介

- 布隆过滤器是一个数据结构
- 内部维护着一个二进制向量的位数组,默认大小64K
- 还维护着N个hash算法, 默认值是3个。
- 牺牲了准确率,算法的时间复杂度是O(1)。从而提高了查询效率
- 特点:  判断一个元素是否在一个集合中,有两种结果:一种就是在集合中,但是不一定真实存在
         另外一种结果就是不在集合中,那么就一定不在集合中。

4.5.2 原理

当存储元素时,会调用hash算法,计算元素的三个hash值,三个值作为bit数组的下标,将对应的元素由0改为1. (注意,hbase在put数据,不判断是否存在过)。
​
当在查询一个元素是否在这个集合中时,也是算出三个hash值作为下标,访问对应上的数据是否为1,如果全都是1,表明该元素可能存在这个集合中。只要有一个位置上是0,则表示该元素一定不在集合中。 

五. hbase的二级索引和协处理器

5.1二级索引的简介

概念:维护的数据是另外一张表的单元格与rowkey的映射关系的表,就是二级索引表
作用:提高查询效率,避免对原表的全表遍历, 牺牲磁盘空间,换取查询效率。

5.2 协处理器

在Hbase的低版本(0.92以前)作为列族数据库最经常被人诟病的特性包括:无法轻易建立“二级索引”,难以执行求和、计数、排序等操作。
之后引入了协处理器(coprocessor)进行改进,可以轻松的实现上述需求。

5.3 协处理器的分类

分两大类型:一个是Observer类型, 一个是endpoint类型
​
- Observer 允许集群在正常的客户端操作过程中可以有不同的行为表现  
- Observer 类似于 RDBMS 中的触发器,主要在服务端工作
- Observer 可以实现权限管理、优先级设置、监控、ddl 控制、二级索引等功能
​
- Endpoint 类似于 RDBMS 中的存储过程,主要在服务端工作
- Endpoint 允许扩展集群的能力,对客户端应用开放新的运算命令  
- Endpoint 可以实现 min、max、avg、sum、distinct、group by 等功能

六. hbase的优化

6.1 在设计表上进行优化

1)预分区

在创建表的时候进行预分区,好处是,减少hbase的region的切分所造成的性能开销。

2)优秀的rowkey设计(重要)

热点问题:  当过多的请求集中在某一个机器节点上,可能会造成机器的瘫痪。 这种问题就叫热点问题。
1. rowkey的唯一原则
​
2. rowkey的长度一致原则
    长度不一致的缺点,排序不是我们所想要的
    长度:建议低于100个字节, 最好是16个字节。 不过要看具体需求具体分析。     
3. rowkey的散列原则(rowkey反过来):(避免热点问题)
    123123 => 321321
    -- 加盐Salt  
    -- hash随机
          提前对普通的rowkey进行hash算法或者是取模算法或者其他的加密算法。将计算出来的结果,取前4位,作为前缀,拼接到rowkey前。这样的就可以将数据分散到不同的region里存储了。
          
         942a-abc001  -->     
         3030-abc002

3)列族个数

-- hbase对多于2以上的列族维护性能开销很大
   某一个列族下的一个文件达到大小阈值时,可能会关联到其他文件的切分,就会产生大量的磁盘IO。

4)使用内存

在建表时,可以开启regionserver的缓存。将表缓存到服务端。

5)版本数量与存活周期的设计

根据数据的重要性,适当的调整版本数量和存储周期

6)合并和切分

compact: 减少storefile的数量,可以提高查询效率。因此,可以适当的手动触发合并。
split: hbase的切分会产生性能开销,因此可以调高storefile大小阈值。

6.2 写表操作的优化

1)大数据集多可客户端写

数据量特别大的时候,可以使用多个Table进行写操作

2)取消自动flush

客户端有缓存,默认情况下是一条一flush,取消后,可以批量的put
HTable.setAutoFlush(false)

3)提高客户端的buffer

可以提高客户端的缓存字节数,批量的冲刷
table.setWriteBufferSize();
参数: hbase.client.write.buffer

4)取消WAL写(谨慎使用)

在配置文件中设置HLog的是否写操作。hbase-site.xml

5)批量put

默认情况下是一条一put。  可以使用put(List<put> puts)

6)多线程写

并发的写

6.3 读表操作的优化

1)大数据集多客户端读

数据量特别大的时候,可以使用for循环开启多个Table读数据

2)参数设置

可以设置客户端,以及服务端的相关参数:
hbase.client.scanner.caching : 设置一次scan的条数, 默认是1条, 可以往大了调整。 减少scan与hbase的交互次数

3)批量读取

get(List<Get> gets)

4)多线程读取

并发读取

5)客户端设置缓存

可以自己写api, 在程序中维护一个数据结构,来存储查询过的数据。前提是这样的数据要频繁查询多次。

6)提高服务端的读缓存

6.4 其他相关优化

1)hdfs

2)zookeeper

3)linux

4)hbase高可用

启动高可用,多个hmaster.     hmaster可以有多个

5)关闭不必要的服务

节省内存使用资源
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值