您的位置:首页 > 运维架构

hadoop之hbase学习

2016-07-12 08:45 435 查看

HBASE介绍

    HBase是一个分布式的、面向列的开源数据库,该技术来源于 Fay Chang 所撰写的Google论文“Bigtable:一个结构化数据的分布式存储系统”。就像Bigtable利用了Google文件系统(File System)所提供的分布式数据存储一样,HBase在Hadoop之上提供了类似于Bigtable的能力。HBase是Apache的Hadoop项目的子项目。HBase不同于一般的关系数据库,它是一个适合于非结构化数据存储的数据库。另一个不同的是HBase基于列的而不是基于行的模式。

    HBase – Hadoop Database,是一个高可靠性、高性能、面向列、可伸缩的分布式存储系统,利用HBase技术可在廉价PC Server上搭建起大规模结构化存储集群。

    Pig和Hive还为HBase提供了高层语言支持,使得在HBase上进行数据统计处理变的非常简单。 Sqoop则为HBase提供了方便的RDBMS数据导入功能,使得传统数据库数据向HBase中迁移变的非常方便。

1. HBASE安装

    (1) 三种模式:单机模式(Standalone)、伪分布模式(Pseudo-Distributed)、完全分布式模式(Fully Distributed);

    (2) JAVA 版本的选择:

 

HBase Version
JDK 6
JDK 7
JDK 8
1.2
Not Supported
yes
yes
1.1
Not Supported
yes
Running with JDK 8 will work but is not well tested.
1.0
Not Supported
yes
Running with JDK 8 will work but is not well tested.
0.98
yes
yes
Running with JDK 8 works but is not well tested. Building with JDK 8 would require removal of the deprecated remove()method of the PoolMap class and is under consideration. SeeHBASE-7608for
more information about JDK 8 support.
    (3) HBASE 自带的Hadoop jar包版本;

    Hbase 0.98的lib目录下自带的hadoop jar包版本为2.2 ;为避免版本不匹配而引起的异常,建议将其替换为正在使用集群(版本为2.5.2)的hadoop jar文件;

2. HBASE 与HIVE 的关系

(1) 两者分别是什么?

    Apache Hive是一个构建在Hadoop基础设施之上的数据仓库。通过Hive可以使用HQL语言查询存放在HDFS上的数据。HQL是一种类SQL语言,这种语言最终被转化为Map/Reduce. 虽然Hive提供了SQL查询功能,但是Hive不能够进行交互查询--因为它只能够在Haoop上批量的执行Hadoop。

    Apache HBase是一种Key/Value系统,它运行在HDFS之上。和Hive不一样,Hbase的能够在它的数据库上实时运行,而不是运行MapReduce任务。HBASE被分区为表格,表格又被进一步分割为列簇。列簇必须使用schema定义,列簇将某一类型列集合起来(列不要求schema定义)。例如,“message”列簇可能包含:“to”, ”from” “date”, “subject”, 和”body”. 每一个 key/value对在Hbase中被定义为一个cell,每一个key由row-key,列簇、列和时间戳。在Hbase中,行是key/value映射的集合,这个映射通过row-key来唯一标识。Hbase利用Hadoop的基础设施,可以利用通用的设备进行水平的扩展。

(2)两者的特点

    Hive帮助熟悉SQL的人运行MapReduce任务。因为它是JDBC兼容的,同时,它也能够和现存的SQL工具整合在一起。运行Hive查询会花费很长时间,因为它会默认遍历表中所有的数据。虽然有这样的缺点,一次遍历的数据量可以通过Hive的分区机制来控制。分区允许在数据集上运行过滤查询,这些数据集存储在不同的文件夹内,查询的时候只遍历指定文件夹(分区)中的数据。这种机制可以用来,例如,只处理在某一个时间范围内的文件,只要这些文件名中包括了时间格式。

    HBase通过存储key/value来工作。它支持四种主要的操作:增加或者更新行,查看一个范围内的cell,获取指定的行,删除指定的行、列或者是列的版本。版本信息用来获取历史数据(每一行的历史数据可以被删除,然后通过Hbase compactions就可以释放出空间)。虽然HBase包括表格,但是schema仅仅被表格和列簇所要求,列不需要schema。Hbase的表格包括增加/计数功能。

(3)限制

    Hive目前不支持更新操作。另外,由于hive在hadoop上运行批量操作,它需要花费很长的时间,通常是几分钟到几个小时才可以获取到查询的结果。Hive必须提供预先定义好的schema将文件和目录映射到列,并且Hive与ACID不兼容。

    HBase查询是通过特定的语言来编写的,这种语言需要重新学习。类SQL的功能可以通过Apache Phonenix实现,但这是以必须提供schema为代价的。另外,Hbase也并不是兼容所有的ACID特性,虽然它支持某些特性。最后但不是最重要的--为了运行Hbase,Zookeeper是必须的,zookeeper是一个用来进行分布式协调的服务,这些服务包括配置服务,维护元信息和命名空间服务。

(4)应用场景

    Hive适合用来对一段时间内的数据进行分析查询,例如,用来计算趋势或者网站的日志。Hive不应该用来进行实时的查询。因为它需要很长时间才可以返回结果。

    Hbase非常适合用来进行大数据的实时查询。Facebook用Hbase进行消息和实时的分析。它也可以用来统计Facebook的连接数。

(5)总结

    Hive和Hbase是两种基于Hadoop的不同技术--Hive是一种类SQL的引擎,并且运行MapReduce任务,Hbase是一种在Hadoop之上的NoSQL的Key/vale数据库。当然,这两种工具是可以同时使用的。就像用Google来搜索,用FaceBook进行社交一样,Hive可以用来进行统计查询,HBase可以用来进行实时查询,数据也可以从Hive写到Hbase,设置再从Hbase写回Hive。

3. HBASE Shell 练习

(0)在hbase shell下的常见命令

help
help create
几种常见命令create, list, put, scan,get,alter
(1)关于建表的提示(来自官网说明书):

Create a table with namespace=ns1 and table qualifier=t1,命令如下:

  hbase> create 'ns1:t1', {NAME => 'f1', VERSIONS => 5}

 

Create a table with namespace=default and table qualifier=t1,命令如下:

  hbase> create 't1', {NAME => 'f1'}, {NAME => 'f2'}, {NAME => 'f3'}

  hbase> # The above in shorthand would be the following:

  hbase> create 't1', 'f1', 'f2', 'f3'

  hbase> create 't1', {NAME => 'f1', VERSIONS => 1, TTL => 2592000, BLOCKCACHE => true}

  hbase> create 't1', {NAME => 'f1', CONFIGURATION => {'hbase.hstore.blockingStoreFiles' => '10'}}

 

Table configuration options can be put at the end,示例如下:

  hbase> create 'ns1:t1', 'f1', SPLITS => ['10', '20', '30', '40']

  hbase> create 't1', 'f1', SPLITS => ['10', '20', '30', '40']

  hbase> create 't1', 'f1', SPLITS_FILE => 'splits.txt', OWNER => 'johndoe'

  hbase> create 't1', {NAME => 'f1', VERSIONS => 5}, METADATA => { 'mykey' => 'myvalue' }

  hbase> # Optionally pre-split the table into NUMREGIONS, using

  hbase> # SPLITALGO ("HexStringSplit", "UniformSplit" or classname)

  hbase> create 't1', 'f1', {NUMREGIONS => 15, SPLITALGO => 'HexStringSplit'}

  hbase> create 't1', 'f1', {NUMREGIONS => 15, SPLITALGO => 'HexStringSplit', CONFIGURATION => {'hbase.hregion.scan.loadColumnFamiliesOnDemand' => 'true'}}

 

You can also keep around a reference to the created table,命令如下

  hbase> t1 = create 't1', 'f1'

 

(2)执行脚本文件

编辑一个文本文件sample_commands.txt

create 'test', 'cf'
list 'test'
put 'test', 'row1', 'cf:a', 'value1'
put 'test', 'row2', 'cf:b', 'value2'
put 'test', 'row3', 'cf:c', 'value3'
put 'test', 'row4', 'cf:d', 'value4'
scan 'test'
get 'test', 'row1'
disable 'test'
enable 'test'
执行文本文件:

./hbase shell ./sample_commands.txt

 

4. HBASE与mongoDB、redis以及Nosql

    Nosql = Not only SQL

    hbase,mongodb,redis都属于nosql型存储方案。在实际的项目实践上看,他们的系统存储及处理的数量由大到小。HBase基于列存储,提供<key, family:qualifier, timestamp>三项坐标方式定位数据,由于其qualifier的动态可扩展型(无需schema设计,可存储任意多的qualifier),特别适合存储稀疏表结构的数据(比如互联网网页类)。HBase读取数据方面只支持通过key或者key范围读取,或者全表扫描。

    MongoDb在类SQL语句操作方面目前比HBase具备更多一些优势,有二级索引,支持相比于HBase更复杂的集合查找等。BSON的数据结构使得处理文档型数据更为直接。MongoDb也支持mapreduce,但由于HBase跟Hadoop的结合更为紧密,Mongo在数据分片等mapreduce必须的属性上不如HBase这么直接,需要额外处理。

    HBase与Mongodb的读写性能正好相反,HBase写优于随机读,MongoDB似乎写性能不如读性能。

    Redis为内存型KV系统,处理的数据量要小于HBase与MongoDB。

1,Hbase,mongodb,cassendra三者性能比较:  http://www.jdon.com/46128
2,NoSql 分析比较之 hbase,mongodb,redis:
http://blog.csdn.net/likika2012/article/details/38931345
3,mongodb, redis, hbase 三者都是nosql数据库,区别和不同定位
http://www.zhihu.com/question/30219620
 

5. Hbase与Oracle比较(列式数据库与行式数据库)

一,主要区别

Hbase适合大量插入同时又有读的情况
Hbase的瓶颈是硬盘传输速度,Oracle的瓶颈是硬盘寻道时间。
    Hbase本质上只有一种操作,就是插入,其更新操作是插入一个带有新的时间戳的行,而删除是插入一个带有插入标记的行。其主要操作是收集内存中一批数据,然后批量的写入硬盘,所以其写入的速度主要取决于硬盘传输的速度。Oracle则不同,因为他经常要随机读写,这样硬盘磁头需要不断的寻找数据所在,所以瓶颈在于硬盘寻道时间。

Hbase很适合寻找按照时间排序top n的场景
索引不同造成行为的差异。
Oracle既可以做OLTP又可以做OLAP,但在某种极端的情况下(负荷十分之大),就不适合了。

二,Hbase的局限:

只能做简单的Key value查询,复杂的sql统计做不到。
只能在row key上做快速查询。
三,传统数据库的行式存储



    在数据分析的场景里面,经常是以某个列作为查询条件,返回的结果经常也只是某些列,不是全部的列。行式数据库在这种情况下的I/O性能会很差,以Oracle为例,Oracle会有一个很大的数据文件,在这个数据文件中,划分了很多block,然后在每个block中放入行,行是一行一行放进去,挤在一起,然后把block塞满,当然也会预留一些空间,用于将来update。这种结构的缺点是:当读某个列的时候,比如只需要读红色标记的列的时候,不能只读这部分数据,必须把整个block读取到内存中,然后再把这些列的数据取出来,换句话说,为了读表中某些列的数据,我必须把整个列的行读完,才可以读到这些列。如果这些列的数据很少,比如1T的数据中只占了100M, 为了读100M数据却要读取1TB的数据到内存中去,则显然是不划算。
                                                                                                                    
B+索引
    Oracle中采用的数据访问技术主要是B数索引:

 


 


从树的跟节点出发,可以找到叶子节点,其记录了key值对应的那行的位置。
对B树的操作:

B树插入——分裂节点
B数删除——合并节点
四 列式存储



    同一个列的数据会挤在一起,比如挤在block里,当需要读某个列的时候,值需要把相关的文件或块读到内存中去,整个列就会被读出来,这样I/O会少很多。

    同一个列的数据的格式比较类似,这样可以做大幅度的压缩。这样节省了存储空间,也节省了I/O,因为数据被压缩了,这样读的数据量随之也少了。

    行式数据库适合OLTP,反倒列式数据库不适合OLTP。

 BigTable的LSM(Log Struct Merge)索引



    在Hbase中日志即数据,数据就是日志,他们是一体化的。为什么这么说了,因为Hbase的更新时插入一行,删除也是插入一行,然后打上删除标记,则不就是日志吗?

    在Hbase中,有Memory Store,还有Store File,其实每个Memory Store和每个Store File就是对每个列族附加上一个B+树(有点像Oracle的索引组织表,数据和索引是一体化的),也就是图的下面是列族,上面是B+树,当进行数据的查询时,首先会在内存中memory store的B+树中查找,如果找不到,再到Store File中去找。

    如果找的行的数据分散在好几个列族中,那怎么把行的数据找全呢?那就需要找好几个B+树,这样效率就比较低了。所以尽量让每次insert的一行的列族都是稀疏的,只在某一个列族上有值,其他列族没有值。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  hadoop hbase