- HBase 安装
- 简介
- Hbase数据模型
- RowKey 的设计
- 列簇设计
HBase 安装
简介
什么是 HBase
Hbase 是一个高可靠性,高性能,面向列,可伸缩的分布式存储系统,目标是存储并处理大型的数据
与传统数据相比
特点 | MySQL | HBase |
---|---|---|
数据库的概念 | 有数据库 database 的概念和表 table 的概念 | 没有数据库的概念,有替代的命名空间 namespace 的概念,有表的概念,所有的表都是在一个 namespace 下的 |
主键 | 主键唯一决定了一行 | 没有主键但是有行建:rowkey |
字段 | 表中直接包含字段 | 有列簇的概念,每个列簇中才包含了字段,给相同属性的列划分一个组,叫做 column family 列簇,在建表的时候至少要指明一个列簇,可以不给字段 |
版本 | 行列交叉可到一个唯一的单元格,数据的版本数只有 1 | 可以存储多个版本 version(相当于是可以存储多个值),HBase 行列交叉得到一个唯一的单元格组,组中可以有多个单元格,可以设置 HBase 的 version 版本数,是 int 值,当 version 为 1 的时候没就没有单元格组的概念了,就是一个单元格,默认情况下,显示 timestamp 最新的那个单元格的值 |
空值 | MySQL 中没有值的话就是 null,是占空间的 | 对于 HBase 来说,如果没有这一列的信息,那么就不会存储,不会分配任何空间 |
Hbase 架构
HBase 集群中的角色
- 一个或多个主节点 HMaster
- 管理 HRegionServer,通过 ZK 监控其状态,实现负载均衡
- 管理和分配 HRegion,比如在 HRegion 进行 spilit 的时候将分配新的 HRegion,当 HRegionServer 退出或者宕机的时候对 HRegionServer 管理的 HRegion 进行迁移
- Admin 职能:创建、修改、删除 Table 的定义,实现 DDL 操作(namespace 和 table 的增删改,列簇的增删改)
- 管理 namespace 和表的元数据(存储在 HDFS 上)
- 权限控制
- 多个从节点 RegionServer
- 管理自己负责的 Region 数据的读写
- 读写 HDFS,管理 table 中的数据
- Client 直接通过 RegionServer 读写数据(从 ZK 中获取 meta 表的存储位置,从 meta 表中获取 RowKey 所在的 RegionServer 的位置)
- Zookeeper
- 存放整个 HBase 集群的元数据
- 保证任何时候,集群中只有一个master
- 保证 HMaster 的失败恢复
- 监控 RegionServer 的运行状态
- 存储 HBase 的 schema 和 table 元数据
HBase 中的表的特点
- 大:一个表可以有上亿行,上百万列
- 面向列:面向列的存储和权限控制,列独立检索
- 稀疏:对于为空(null)的列,并不占用存储空间,因此,表可以设计的非常稀疏
- HBase 的存储数据都是二进制的
Hbase数据模型
单元格(Cell)
- cell 由行和列的坐标交叉决定
- 单元格是有版本的
- cell 的内容是未解析的字节数组
- cell 由 {rowkey, column(
<column family>
+<qualifier>
), value} 来确定唯一的单元 - cell 中的数据是没有类型的,全部是字节码形式存储的
RowKey
- 决定一行数据,按行检索数据,相当于一级索引
- 按照字典顺序排序,说明数据是有序的
- 只能存储 64k 的字节数据,RowKey 越短越好
列族 / 列簇(Column Family)
- HBase 表中的每个列都归属于某个列簇,列簇必须作为表模式(schema)定义的一部分预先给出,列名以列簇作为前缀,每个列簇都可以有多个列
- 权限控制、存储以及调优都是在列簇层面进行的
- HBase 把同一列簇里面的数据存储在同一目录下,由几个文件保存
时间戳(Timestamp)
- 在 HBase 每个 cell 存储单元对同一份数据可以有多个版本,根据唯一的时间戳来区分每个版本之间的差异,不同本的数据按照时间倒序排序,最新的数据版本排在最前面
- 时间戳的类型是 64 位整型,一般由 HBase(在数据写入时自动)赋值,此时时间戳时精确到毫秒的当前系统时间
时间戳也可以由客户显示赋值,如果应用程序要避免数据版本冲突,就必须自己生成具有唯一性的时间戳
HBase 读数据流程
RowKey 的设计
列簇设计
一般不建议设计多个列族,具体原因如下
假如 HBase 的表设置两个列族,若已一个列族 1000 万行,另一个列族 100 行。当一个要求 region 分裂时候,会导致 100 行的列会同样分布到多个 region 中。这样就出现基数问题,会导致扫描列族A的性能低下。某个列族在 flush 的时候,它邻近的列族也会因关联效应出发 flush,最终导致系统产生更多的I/O。