HBase是一个分布式的、面向列的开源数据库,该技术来源于 Fay Chang 所撰写的Google论文“Bigtable:一个结构化数据的分布式存储系统”。就像Bigtable利用了Google文件系统(File System)所提供的分布式数据存储一样,HBase在Hadoop之上提供了类似于Bigtable的能力。HBase是Apache的Hadoop项目的子项目。HBase不同于一般的关系数据库,它是一个适合于非结构化数据存储的数据库。另一个不同的是HBase基于列的而不是基于行的模式。
HBase 简介
HBase是一个分布式的、多版本的、面向列的开源数据库
利用Hadoop HDFS作为其底层存储系统,提供高可靠性、高吞吐、列存储、可伸缩、实时读写的数据库系统。
利用Hadoop MapReduce来处理HBase中的海量数据
利用Zookeeper作为协同服务。
HBase中表的特点
大:一个表可以有上亿行,上百万列(列多时,插入变慢)
面向列:面向列(族)的存储和权限控制,列(族)独立检索。
稀疏:对于为空(null)的列,并不占用存储空间,因此,表可以设计的非常稀疏。
每个cell中的数据可以有多个版本,默认情况下版本号自动分配,是单元格插入时的时间戳;
HBase中的数据都是字符串,没有类型;
强一致性
同一行数据的读写只在同一台Region Server上进行
水平伸缩
- Region的自动分裂以及Master的balance;
- 只用增加Datanode机器即可增加容量;
- 只用增加Region Server机器即可增加读写吞吐量
行事务
同一行的列的写入是原子的
按列存储 + 三维有序
支持有限查询方式和一级索引
- 仅支持单行事务
- 仅支持三种查询方式(single row key、range row key、scan all rows of table)
- 仅基于row key的索引
高性能随机读写
和Hadoop无缝集成
- Hadoop分析后的结果可直接写入HBase;
- 存放在HBase的数据可直接通过Hadoop来进行分析。
HBase与RDBMS对比
HBase | RDBMS | |
数据类型 | 只有字符串 | 丰富的数据类型 |
数据操作 | 简单的增删改查 | 各种各样的函数,表连接 |
存储模式 | 基于列存储 | 基于表格结构和行存储 |
数据保护 | 更新后旧版本仍然会保留 | 替换 |
可伸缩性 | 轻易的进行增加节点,可扩展性高 | 需要中间层 |
HBase逻辑视图、物理视图
逻辑视图
HBase以表的形式存储数据。表由行和列组成。列划分为若干个列族(row family)
Row Key | Time Stamp | CF “contents:” | CF “anchor:” | CF “mime:” | |
www.360buy.com | “” | “fashon.com” | “tuan.com” | “” | |
t9 | “fashion.360buy” | ||||
t8 | “tuan.360buy” | ||||
t6 | “<html>…” | “text/html” | |||
t5 | “<html>…” | ||||
t3 | “<html>…” |
HBase每个列族存储为一个Store物理视图
Row Key | Time Stamp | Column “contents:” |
www.360buy.com | t6 | “<html>…” |
t5 | “<html>…” | |
t3 | “<html>…” |
Row Key | Time Stamp | Column “anchor:” | |
www.360buy.com | t9 | “anchor:fashon.com” | “fashion.360buy” |
t8 | “anchor:tuan.com” | “tuan.360buy” |
Row Key | Time Stamp | Column “mime:” |
www.360buy.com | t6 | “text/html” |
存储结构
Hbase是基于列存储的数据库,可简单认为每个ColumnFamily对应一张存储表,表格的RowKey、Timestamp和column确定了每条记录的唯一索引。在物理层面上,表格的数据是通过StoreFile来存储的,每个StoreFile相当于一个可序列化的Map,Map的key和value都是可解释型字符数组,如key的字符数组主要由以下信息组成(value类似):
Rowlength | rowKey的字符长度 |
Row | rowKey的值 |
columnFamilyLength | columnFamily的长度 |
columnFamily | columnFamily的值 |
columnqualifier | column |
timestamp | 时间戳(版本) |
Keytype | Key的类型(Put,Delete,DeleteColumn,DeleteFamily) |
而多个map整合到一起,便形成一张松散的、可分布式的、多维的、可序列化的BigTable
HBase 数据表中一些关键概念
键 Row key
表中行的键是字节数组(最大长度是 64KB )
任何字符串都可以作为键;
表中的行根据行的键值进行排序,数据按照Row key的字典序(byte order)排序存储;
所有对表的访问都要通过键
- 通过单个row key访问
- 通过row key的range
- 全表扫描
列族 Column Family
HBase表中的每个列都归属于某个列族,列族必须作为表模式(schema)定义的一部分预先定义。如 create ‘info’, ‘realtime’;
列名以列族作为前缀,每个“列族”都可以有多个列成员(column);如info:name, realtime:price,
新的列族成员可以随后按需、动态加入;
权限控制、存储以及调优都是在列族层面进行的;
- 同一列族成员最好有相同的访问模式和大小特征;
HBase把同一列族里面的数据存储在同一目录下,由几个文件保存。
单元格修饰符 Cell qualifier
通过列族:单元格修饰符,可以具体到某个列;
可以把单元格修饰符认为是实际的列名;
在列族存在,客户端随时可以把列添加到列族;
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())); }
时间戳Timestamp
在HBase每个cell存储单元对同一份数据有多个版本,根据唯一的时间戳来区分每个版本之间的差异,不同版本的数据按照时间倒序排序,最新的数据版本排在最前面。
时间戳的类型是 64位整型。
时间戳可以由HBase(在数据写入时自动)赋值,此时时间戳是精确到毫秒的当前系统时间。
时间戳也可以由客户显式赋值,如果应用程序要避免数据版本冲突,就必须自己生成具有唯一性的时间戳。
区域 Region
HBase自动把表水平划分成多个区域(region),每个region会保存一个表里面某段连续的数据;
每个表一开始只有一个region,随着数据不断插入表,region不断增大,当增大到一个阀值的时候,region就会等分会两个新的region;
当table中的行不断增多,就会有越来越多的region。这样一张完整的表被保存在多个Region 上。
Cell单元格
由行和列的坐标交叉决定;
单元格是有版本的;
单元格的内容是未解析的字节数组;
由{row key, column( =<family> + <label>), version} 唯一确定的单元。cell中的数据是没有类型的,全部是字节码形式存贮。
锁
HBase的写操作是锁行的,每一行都是一个原子元素,无论对行进行访问的事务涉及多少列,对行的更新都是原子的,也就是说要么成功要么失败不会存在成功一部分的情况。
Comments