一、HBase特性
Hbase是典型的nosql数据库,通常被描述成稀疏的、分布式的、持久化的,由行键、列键和时间戳进行索引的多维有序映射数据库,主要用来存储非结构化和半结构化的数据。因为Hbase基于hadoop的HDFS完成分布式存储,以及mapreduce完成分布式并行计算,所以一些特点与hadoop相同,依靠横向扩展,通过不断增加性价比高的商业服务器来增加计算和存储能力。
1.容量巨大
Hbase单表可以有百亿行、百万列,采用LSM树作为内部数据存储结构,这种结构会周期性地将较小文件合成大文件,以减少对磁盘的访问。
2.列存储
与面向行存储的关系型数据库不同,Hbase是面向列的存储和权限控制的,每个列是单独存储的,且支持基于列的独立检索。进行数据的插入和更新,行存储会相对容易。进行行存储时,查询操作需要读取所有数据,列存储只需要读取相关列,可以大幅降低系统IO吞吐量。
3.稀疏性
Hbase中的数据都是以字符串形式存储的,为空的列并不占用存储空间,这与关系型数据库不同。
4.扩展性强
Hbase支持分布式表,继承了HDFS的扩展性。Hbase的扩展是横向的,横向扩展是指扩展时不需要提升服务器本身的性能,只需添加服务器到现有集群即可。Hbase表根据region大小进行分区,分别存在集群中不同的节点上,当添加新的节点时是动态扩展和热扩展,在不停止现有服务的前提下添加减少节点。
5.高可靠性
HDFS的多副本存储可以让它出现故障时自动恢复。WAL预写日志是在Hbase服务器处理数据插入和删除过程中用来记录操作内容的日志,保证了数据写入时不会因集群异常而导致写入数据丢失;replication机制是基于日志操作来做数据同步的。当单个节点出现故障时,协调服务组件zookeeper通知集群主节点,将故障节点的Hlog中的日志信息分发到各从节点进行护具恢复。
二、HDFS原理
1.HDFS基本架构
HDFS是以master/slave模式运行的,namenode和secondarynamenode运行在master节点上,,datanode运行在slave节点上。文件是被分成块进行存储的,一个文件包含许多个块,每个块存储在不同的datanode中,当客户端请求读取一个文件时,需要先从namenode中获取文件元数据信息,然后从对应的数据节点上并行读取数据块。
2.HDFS的分块机制和副本机制
1.分块机制
HDFS中数据块大小默认为64MB,是为了最小化寻址开销。
2.副本机制
HDFS默认3个副本的情况下,会把第一个副本放到机架的一个节点,第二副本放在同一个机架的另一个节点,第三个副本放在不同的机架上。
3.HDFS的读写机制
1.读文件
HDFS通过RPC调用namenode获取文件块的位置信息,并且对每个块返回所在的datanode地址信息,然后再从datanode获取数据块的副本。
2.写文件
namenode负责通知datanode创建文件,在创建之前会检查客户端是否有写入数据的权限。通过检测后,namenode会向edits文件写入一条创建文件的操作记录。
三、Hbase的组件和功能
1.客户端
客户端与Hmaster进行管理类操作的通信,在获取regionserver的信息后,直接与regionserver进行数据读写类操作。客户端获取region的位置信息后会缓存下来,用来加速后续数据的访问过程。
2.zookeeper
功能有master选举、系统容错、region元数据管理、region状态管理、提供meta表存储位置。
3.Hmaster
Hmaster是Hbase集群中的主服务器,负责监控集群中所有regionserver。Hmaster通常运行在namenode上,Hmaster通过zookeeper避免单点故障,保证只有一个Hmaster处于active状态。Hmaster主要负责表和region的管理工作。
4.regionserver
regionserver运行在datanode服务器上,实现数据的本地性,每个regionserver包含多个region,每个region由多个Hstore组成,每个Hstore对应表中一个列族的存储。
四、Hbase数据模型与使用
1.Hbase数据模型
1.表:表名作为HDFS存储路径的一部分来使用,在HDFS中可以看到每个表名都作为独立目录结构。
2.行:在Hbase表里,每一行代表一个数据对象,每一行都以行健来进行唯一标识,行健是任意字符串。
3.列族:列族中的所有列成员有着相同的前缀。
4.列标识:列族中的数据通过列标识来进行定位,列标识没有特定的数据类型,以二进制字节来存储。
5.单元格:单元格内容没有特定的数据类型,以二进制字节来存储。
6.时间戳:默认情况下每一个单元格插入数据时都会用时间戳进行版本标识。
2.Hbase shell操作
1.创建表,指明表名、两个列族名
create 'student','stuinfo','grades'
2.更改表结构
alter 'student','hobby'
alter 'student','delete'=>'hobby'
3.删除表
disable 'student'
drop 'student'
清空表
truncate 'student'
4.数据操作
put 'student','0001','stuinfo:name','tom green',1
删除时间戳小于等于2的数据
delete 'student','0001','grades:math',2
get 'student','0001'
scan 'student'
5.列过滤器
scan 'student',FILTER=>"FamilyFilter (=,'substring:grades')"