部署与使用

Introduction

Hbase是运行在Hadoop上的NoSQL数据库,它是一个分布式的和可扩展的大数据仓库,也就是说HBase能够利用HDFS的分布式处理模式,并 从HadoopMapReduce程序模型中获益。这意味着在一组商业硬件上存储许多具有数十亿行和上百万列的大表。除去Hadoop的优 势,HBase本身就是十分强大的数据库,它能够融合key/value存储模式带来实时查询的能力,以及通过MapReduce进行离线处理或者批处理 的能力。总的来说,Hbase能够让你在大量的数据中查询记录,也可以从中获得综合分析报告。HBase的发展历史进程简介如下

  • 2006.11 G release paper on BigTable
  • 2007.2 inital HBase prototype created as Hadoop contrib
  • 2007.10 First useable Hbase
  • 2008.1 Hadoop become Apache top-level project and Hbase becomes subproject
  • 2008.10 Hbase 0.18,0.19 released

HBase中的表一般有如下特点

  • 大:一个表可以有上亿行,上百万列
  • 面向列:面向列()的存储和权限控制,列()独立检索。
  • 稀疏:对于为空(null)的列,并不占用存储空间,因此,表可以设计的非常稀疏。

Logical View:逻辑视图

HBase介于NoSQLRDBMS之间,仅能通过主键(row key)和主键的range来检索数据,仅支持单行事务(可通过hive支持来实现多表join等复杂操作)。主要用来存储非结构化和半结构化的松散数据。HBase实际上定义了一个四维数据模型,下面就是每一维度的定义:

  • 行键:每行都有唯一的行键,行键没有数据类型,它内部被认为是一个字节数组。
  • 列簇:数据在行中被组织成列簇,每行有相同的列簇,但是在行之间,相同的列簇不需要有相同的列修饰符。在引擎中,HBase将列簇存储在它自己的数据文件中,所以,它们需要事先被定义,此外,改变列簇并不容易。
  • 列修饰符:列簇定义真实的列,被称之为列修饰符,你可以认为列修饰符就是列本身。
  • 版本:每列都可以有一个可配置的版本数量,你可以通过列修饰符的制定版本获取数据。

如上图所示,通过行键获取一个指定的行,它由一个或多个列簇构成,每个列簇有一个或多个列修饰符(也被称为列),每列又可以有一个或多个版本。为了获取指定数据,你 需要知道它的行键、列簇、列修饰符以及版本。当设计HBase数据模型时,对考虑数据是如何被获取是十分有帮助的。你可以通过以下两种方式获得HBase数据:

  • 通过他们的行键,或者一系列行键的表扫描。
  • 使用map-reduce进行批操作

Row Key

Row key行键(Row key)可以是任意字符串(最大长度是64KB,实际应用中长度一般为10-100bytes),在hbase内部,row key保存为字节数组。存储时,数据按照Row key的字典序(byte order)排序存储。设计key时,要充分排序存储这个特性,将经常一起读取的行存储放到一起。(位置相关性)注意:字典序对int排序的结果是1,10,100,11,12,13,14,15,16,17,18,19,2,20,21,…,9,91,92,93,94,95,96,97,98,99。要保持整形的自然序,行键必须用0作左填充。行的一次读写是原子操作(不论一次读写多少列)。这个设计决策能够使用户很容易的理解程序在对同一个行进行并发更新操作时的行为。

列簇

HBase表中的每个列,都归属与某个列簇。列簇是表的Schema的一部分(而列不是),必须在使用表之前定义。列名都以列簇作为前缀。例如courses:historycourses:math都属于courses这个列簇。访问控制、磁盘和内存的使用统计都是在列簇层面进行的。实际应用中,列簇上的控制权限能帮助我们管理不同类型的应用:我们允许一些应用可以添加新的基本数据、一些应用可以读取基本数据并创建继承的列族、一些应用则只允许浏览数据(甚至可能因为隐私的原因不能浏览所有数据)

时间戳

HBase中通过rowcolumns确定的为一个存贮单元称为cell。每个cell都保存着同一份数据的多个版本。版本通过时间戳来索引。时间戳的类型是64位整型。时间戳可以由hbase(在数据写入时自动)赋值,此时时间戳是精确到毫秒的当前系统时间。时间戳也可以由客户显式赋值。如果应用程序要避免数据版本冲突,就必须自己生成具有唯一性的时间戳。每个cell中,不同版本的数据按照时间倒序排序,即最新的数据排在最前面。为了避免数据存在过多版本造成的的管理(包括存贮和索引)负担,hbase提供了两种数据版本回收方式。一是保存数据的最后n个版本,二是保存最近一段时间内的版本(比如最近七天)。用户可以针对每个列族进行设置。

Cell

{row key, column(= + ), version}唯一确定的单元。cell中的数据是没有类型的,全部是字节码形式存贮。

Quick Start

Installation:安装

让我们开始用命令行操作HBase,在HBase bin目录下执行下面命令:

./hbase shell

你应该看到如下类似的输出:

HBase Shell; enter 'help<RETURN>' for list of supported commands.
Type "exit<RETURN>" to leave the HBase Shell
Version 0.98.5-hadoop2, rUnknown, Mon Aug  4 23:58:06 PDT 2014
hbase(main):001:0>

表创建

创建一个名为PageViews的表,并具有名为info的列簇:

hbase(main):002:0> create 'PageViews', 'info'
0 row(s) in 5.3160 seconds
=> Hbase::Table - PageViews

每张表至少要有一个列簇,因此我们创建了info,现在,看看我们的表,执行下面list命令:

hbase(main):002:0> list

TABLE

PageViews

1 row(s) in 0.0350 seconds

=> ["PageViews"]

如你所见,list命令返回一个名为PageViews的表,我们可以通过describe命令得到表的更多信息:

hbase(main):003:0> describe 'PageViews'

DESCRIPTION                                                                                                                                         ENABLED

'PageViews', {NAME => 'info', DATA_BLOCK_ENCODING => 'NONE', BLOOMFILTER => 'ROW',

REPLICATION_SCOPE => '0', VERSIONS => '1', COMPRESSION => 'NONE true

', MIN_VERSIONS => '0', TTL => 'FOREVER', KEEP_DELETED_CELLS => 'false',

BLOCKSIZE => '65536', IN_MEMORY => 'false', BLOCKCACHE => 'true'}

1 row(s) in 0.0480 seconds

Describe命令返回表的详细信息,包括列簇的列表,这里我们创建的仅有一个:info。

数据插入

现在为表添加以下数据,下面命令是在info中添加新的行:

hbase(main):004:0&gt; put ";PageViews", ";rowkey1", ";info:page", ";/mypage"
0 row(s) in 0.0850 seconds

Put命令插入一条行键为rowkey1的新纪录,指定在info下的page列,插入值为/mypage的记录,我们随后可以通过get命令通过行键rowkey1查询到这条记录:

hbase(main):005:0> get 'PageViews', 'rowkey1'

COLUMN                                                     CELL

 info:page                                                 timestamp=1410374788088, value=/mypage

1 row(s) in 0.0250 seconds

数据查询

让我们查询出PageViews表的所有记录:

hbase(main):007:0> scan 'PageViews'

ROW                                                        COLUMN+CELL

 rowkey1                                                   column=info:page, timestamp=1410374788088, value=/mypage

 rowkey2                                                   column=info:page, timestamp=1410374823590, value=/myotherpage

2 row(s) in 0.0350 seconds

如前面所提到的,我们不能查询本身,但是我们可以对表进行scan操作,如果你执行scan table命令,它会返回表中所有行,这很有可能不是你想要做的。你可以给出行的范围来限制返回的结果,让我们插入一带有s开头行键的新记录:

hbase(main):012:0> put 'PageViews', 'srowkey2', 'info:page', '/myotherpage'

现在,如果我增加点限制,想查询行键在rs之间的记录,可以使用如下结构:

hbase(main):014:0> scan 'PageViews', { STARTROW => 'r', ENDROW => 's' }

ROW                                                        COLUMN+CELL

rowkey1                                                   column=info:page, timestamp=1410374788088, value=/mypage

rowkey2                                                   column=info:page, timestamp=1410374823590, value=/myotherpage

2 row(s) in 0.0080 seconds

这个scan返回了仅有s开头的记录,这个类比是基于全行键上的,所以rowkey1r大,所有它被返回了。另外,scan的结果包含了所指范围的STARTROW,但不包含ENDROW,注意,ENDROW不是必须指定的,如果我们执行相同查询只给出了STARTROW,那么我们会得到行键比r大 的所有记录。

hbase(main):013:0> scan 'PageViews', { STARTROW => 'r' }

ROW                                                        COLUMN+CELL

rowkey1                                                   column=info:page, timestamp=1410374788088, value=/mypage

rowkey2                                                   column=info:page, timestamp=1410374823590, value=/myotherpage

srowkey2                                                  column=info:page, timestamp=1410375975965, value=/myotherpage

3 row(s) in 0.0120 seconds
上一页
下一页