前言

安装Hbase的前提是安装好了Hadoop完全分布式的集群
以下的教程及报错,基于一主两从结构的分布式集群

踩了不少坑,最难解决的bug往往是因为自信造成的

安装步骤

Hbase版本

HBase1.1.2和Hadoop2.7.1(或Hadoop2.6.0或Hadoop2.7.3)兼容,而HBase2.2.2和Hadoop3.1.3兼容。

我选择的版本:hbase-1.7.2-bin.tar.gz(尽量选择1.x.x的版本,稳定)


中间安装过程大多重复一样…省略


我的配置文件

hbase-site.xml:

<configuration>

	<property>
	      <name>hbase.rootdir</name>
	      <value>hdfs://Master:9000/hbase</value>
	    </property>
	    <property>
	      <name>hbase.cluster.distributed</name>
	      <value>true</value>
	    </property>
	    <property>
	      <name>hbase.master</name>
	      <value>Master:60000</value>
	    </property>
	    <property>
	      <name>hbase.zookeeper.quorum</name>
	      <value>Master:2181,Slave1:2181,Slave2:2181</value>
	    </property>
	    <property>
	      <name>hbase.zookeeper.property.dataDir</name>
	      <value>/home/hadoop/zoodata</value>
	    </property>
</configuration>

hbase.env.sh:

# The java implementation to use.  Java 1.7+ required.
export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64
export HBASE_CLASSPATH=/usr/local/hadoop/conf
export HBSE_MANAGES_ZK=true

注意坑来了!!!

  • 如果你的java jdk 版本是 java 7(可以跳过这里)
  • 如果你的java jdk 版本是 java 8,那么恭喜您!您一定会看到这样的报错

安装好后hbase启动没有进程 hbase安装问题_大数据

  • 问题原因及解决方法:

文件中有这两个变量,专门针对jdk7的

# Configure PermSize. Only needed in JDK7. You can safely remove it for JDK8+
export HBASE_MASTER_OPTS="$HBASE_MASTER_OPTS -XX:PermSize=128m -XX:MaxPermSize=128m -XX:ReservedCodeCacheSize=256m"
export HBASE_REGIONSERVER_OPTS="$HBASE_REGIONSERVER_OPTS -XX:PermSize=128m -XX:MaxPermSize=128m -XX:ReservedCodeCacheSize=256m"

把这两个变量注释掉:

#export HBASE_MASTER_OPTS="$HBASE_MASTER_OPTS -XX:PermSize=128m -XX:MaxPermSize=128m -XX:ReservedCodeCacheSize=256m"
#export HBASE_REGIONSERVER_OPTS="$HBASE_REGIONSERVER_OPTS -XX:PermSize=128m -XX:MaxPermSize=128m -XX:ReservedCodeCacheSize=256m"

关闭重新启动hbase即可:

stop-hbase.sh
start-hbase.sh

Bug2

安装好后hbase启动没有进程 hbase安装问题_服务器_02

  • 问题提取如下:
slave1: java.io.IOException: Could not find my address: Slave1 in list of ZooKeeper quorum servers
slave1: 	at org.apache.hadoop.hbase.zookeeper.HQuorumPeer.writeMyID(HQuorumPeer.java:178)
slave1: 	at org.apache.hadoop.hbase.zookeeper.HQuorumPeer.main(HQuorumPeer.java:74)
slave2: java.io.IOException: Could not find my address: Slave2 in list of ZooKeeper quorum servers
slave2: 	at org.apache.hadoop.hbase.zookeeper.HQuorumPeer.writeMyID(HQuorumPeer.java:178)
slave2: 	at org.apache.hadoop.hbase.zookeeper.HQuorumPeer.main(HQuorumPeer.java:74)
running master, logging to /usr/local/hbase/bin/../logs/hbase-hadoop-master-Master.out
Slave2: running regionserver, logging to /usr/local/hbase/bin/../logs/hbase-hadoop-regionserver-Slave2.out
Slave1: running regionserver, logging to /usr/local/hbase/bin/../logs/hbase-hadoop-regionserver-Slave1.out

你的子节点映射地址映射有错:

我一开始把Slave1写成slave1 ,就死活找不出来哪里错了

查看地址映射:sudo vim regionservers 内容如下:

Master
Slave1
Slave2

关闭重新启动hbase即可:

Bug3

Zookeeper启动不正常。

在启动hbase时,总是报错,提示zookeeper连接不上,查看zookeeper日志,发现:

ClientCnxn$SendThread@966] - Opening socket connection to server slave1. Will not attempt to authenticate using SASL (无法定位登录配置)。经过百度可得

由于hosts文件的问题,于是vi /etc/hosts 发现 ip slave1配置中ip错误。汗!幸亏hbase和zookeeper都有日志。于是重启zookeeper和hbase,上述问题解决。

Bug4

HBase shell执行list命令报错。

关键错误信息:client.HConnectionManager$HConnectionImplementation: Can't get connection to ZooKeeper: KeeperErrorCode = ConnectionLoss for /hbase

根据信息可以判断zk无法连接。执行jps查看zk都正常。查看hbase-site.xml中zk节点配置正常。根据经验,应该是防火墙没有关闭,2181端口无法访问。ok执行service iptables stop关闭防火墙,重启hbase。进入hbase shell,执行list:

hbase(main):001:0> list
TABLE
SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/root/hadoop/hbase/lib/slf4j-log4j12-1.6.4.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/root/hadoop/hadoop-2.2.0/share/hadoop/common/lib/slf4j-log4j12-1.7.5.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
  • 防火墙命令
请检查防火墙设置,必须打开相应端口或者关闭防火墙:

service iptables status

service iptables stop

chkconfig iptables off

这个SLF4J问题,不用管(不影响Hbase运行),是java编译器版本问题(内部jar包的问题—),要去修改配置文件才能解决

HBase学习

先了解一下BigTable

BigTable:

  1. bigtable 是一个分布式存储系统
  2. 利用MapReduce分布式并行计算框架模型来处理海量数据
  3. 使用分布式文件系统GFS作为数据存储
  4. 采用Chubby提供协同服务管理
  5. 四个特点:广泛应用性、可扩展性、高性能和高可用性
  6. 五大特性:





Hadoop生态和Hbase关系:

  • MapReduce处理海量数据
  • Zookeeper提供协同服务
  • HDFS底层存储
  • Sqoop提供高效RDBMS数据导入
  • Pig和Hive提供高层语言支持

与传统数据库对比

  • 数据类型
    Hbase把数据存储为未经解释的字符串,数据都序列化成字符串保存,用户自己解析数据
  • 数据操作:
    不存在复杂的表与表之间的关系,只有增删改查,没有连接
  • 存储模式:
    基于列存储,每个列族由几个文件保存,不同的列族文件是分离的。大幅度降低IO,只需要回答要查询的列,不需要查询整个行。一个列族中的数据大幅度相似,一起压缩,压缩比很高
  • 数据索引
    只有一个索引—行键,所有的访问全部用行键(保证不会慢),使用MapReduce快速高效生成索引表
  • 数据维护
    数据更新不会覆盖替换原来的值,而是生成一个新的版本,旧版本可保留
  • 可伸缩性
    在集群中增加或减少硬件数量来实现性能的伸缩

HBase数据模型

特性太多,咱整理一下,归一下类

定义:

  • 列族:Row Key
  • 行键:Column Family
  • 列限定符:Column Qualifier
  • 时间戳:TimeStamp
  • 类型都是字节数组 byte[ ]

HBase是一个稀疏、多维度、排序的映射表。索引:行键、列族、列限定符、时间戳

值:
每一个值都是未经解释的字符串,没有数据类型

竖直方向 - > 行:

  1. 每一行都有一个可排序的行键和任意多个列
  • 何谓行键?
  • 行键是来标识每个行的,行键可以是任意字符串(最大长度64KB,长度一般10~100字节)
  • 类型为字节数组
  • 按照字典排序存储
  • 三种访问行的方式:
  1. 单个行键访问
  2. 行键的区间访问
  3. 全表扫描

水平方向 - >列:

  • 何谓列族?
  • 基本的访问控制单元
  • 需要在创建时定义好
  • 列归属于列族,数据存放在列族下面的每一个列下面
  • 列名都以列族作为前缀
  • HBase的访问控制、磁盘和内存使用统计都在列族层面进行的
  1. 由一个或多个列族组成,一个列族中可以包含任意多列
  2. 一个列族中可以包含任意多个列
  3. 同一个列族中的数据存储在一起
  4. 无需预先定义数据数量及类型
  5. 所有列均以字符串形式存储

每一行数据都可以有截然不同的列,整个映射表的每行数据,有些列的值就是空的,所以说HBase是稀疏的

列限定符

列族里的数据通过列限定符(列)来定位

  • 不用事先定义
  • 不同行之间不用保持一致
  • 没有数据类型
  • 数据类型为字节数组byte[]

单元格

行、列族、列限定符确定一个单元格



时间戳

每个单元格都有数据的多个版本,版本用时间戳来索引

  • 时间戳较大的是最新版本的数据

数据视图

数据坐标:

安装好后hbase启动没有进程 hbase安装问题_hadoop_03

安装好后hbase启动没有进程 hbase安装问题_大数据_04


行键是一个反向的URL

因为HBase是按照行键的字典序来排序存储数据的,采用反 向URL的方式,可以让来自同一个网站的数据内容都保存在相邻的位 置,在按照行键的值进行水平分区时,就可以尽量把来自同一个网站 的数据划分到同一个分区(Region)中

contents列族用来存储网页内 容;
anchor 列族包含了任何引用这个页面的锚链接文本

安装好后hbase启动没有进程 hbase安装问题_hbase_05

从概念视图层面,HBase中的每个表是由许多行组成的,但是在物 理存储层面,它是采用了基于列的存储方式

安装好后hbase启动没有进程 hbase安装问题_服务器_06


有些列是空的,即这些列 上面不存在值。在物理视图中,这些空的列不会被存储成null,而是根本就不会被存储,当请求这些空白的单元格的时候,会返回null值

数据库对比:

安装好后hbase启动没有进程 hbase安装问题_安装好后hbase启动没有进程_07

列式数据库特点:

列式数据库主要适合于批量数据处理和即席查询

  1. 可以降低I/O开销,支持大量并发用户查询,其 数据处理速度比传统方法快100倍,因为仅需要处理可以回答这些查询 的列,而不是分类整理与特定查询无关的数据行;
  2. 具有较高的数据压 缩比,较传统的行式数据库更加有效,甚至能达到5倍的效果

如果严格从关系数据库的角度来看,HBase并不是一个 列式存储的数据库,毕竟HBase 是以列族为单位进行分解(列族当中 可以包含多个列),而不是每个列都单独存储,但是HBase借鉴和利用 了磁盘上的这种列存储格式,所以,从这个角度来说,HBase可以被视为列式数据库

HBase实现原理

HBase的实现包括3个主要的功能组件:

  1. 库函数,链接到每个客户 端;
  2. 许多个Region服务器。Region服务器负责存 储和维护分配给自己的Region,处理来自客户端的读写请求。
  3. 主服务器 Master 负责管理和维护 HBase 表的分区信息,Master还处理模式变化,如表和列族的创建

客户端并不是直接从Master主服务器上读取数据,而是在获得 Region的存储位置信息后,直接从Region服务器上读取数据

HBase客户端并不依赖于Master而是借助于Zookeeper来获得 Region的位置信息的,所以大多数客户端从来不和主服务器Master通
信,这种设计方式使Master的负载很小。

表和Region

对于每个HBase表而言,表中的 行是根据行键的值的字典序进行维护的,表中包含的行的数量可能非 常庞大,无法存储在一台机器上,需要分布存储到多台机器上

因此,需要根据行键的值对表中的行进行分区,每个行区间 构成一个分区,被称为“Region”,包含了位于某个值域区间内的所有数 据,它是负载均衡和数据分发的基本单位,这些Region会被分发到不同 的Region服务器上

安装好后hbase启动没有进程 hbase安装问题_安装好后hbase启动没有进程_08

  • 一个表会分裂成多个Region

标准配置:

  1. 每个Region的默认大小是100 MB到200 MB,是HBase中负载均衡 和数据分发的基本单位
  2. 通常在每个Region服务器上会放置10~1 000个Region
  3. 每个Region都有一个RegionID来标识它的唯一性,这样,一个 Region标识符就可以表示成“表名+开始主键+RegionID”。
  4. 元数据表”,又名“.META.表 (即Region和Region服务器之间的对应关系)
  5. “根数据表”,又名“-ROOT-表: 当一个HBase表中的Region数量非常庞大的时候,.META.表的条目 就会非常多,一个服务器保存不下,也需要分区存储到不同的服务器 上,因此.META.表也会被分裂成多个Region

安装好后hbase启动没有进程 hbase安装问题_hadoop_09


HBase使用类似B+树的三层结构来保存Region位置信息

安装好后hbase启动没有进程 hbase安装问题_服务器_10


META表计算:

.META.表的全部Region都会被保存在内存 中。假设.META.表的每行(一个映射条目)在内存中大约占用1 KB,

并且每个Region限制为128 MB,那么,上面的三层结构可以保存的用 户数据表的Region数目的计算方法是:(-ROOT-表能够寻址的.META. 表的 Region 个数)×(每个.META.表的 Region 可以寻址的用户数据表 的 Region 个数)。一个-ROOT-表最多只能有一个 Region,也就是最多 只能有 128 MB,按照每行(一个映射条目)占用1 KB内存计算,128

MB空间可以容纳128 MB/1 KB=217 行,也就是说,一个-ROOT-表可以 寻址217 个.META.表的Region。同理,每个.META.表的Region可以寻址 的用户数据表的Region 个数是 128 MB/1 KB=217 。

  • 最终,三层结构可以保存的 Region 数目是(128 MB/1 KB)×(128 MB/1 KB) = 234 个Region

三级寻址过程:

  1. 客户端访问用户数据之前,需要首先访问 Zookeeper,获取-ROOT- 表的位置信息
  2. 然后访问-ROOT-表,获得.META.表的信息
  3. 接着访 问.META.表,找到所需的Region具体位于哪个Region服务器,最后才会 到该Region服务器读取数据
系统架构

包括客户端、Zookeeper服务器、 Master主服务器、Region服务器

安装好后hbase启动没有进程 hbase安装问题_hbase_11

客户端

客户端包含访问 HBase 的接口,同时在缓存中维护着已经访问过 的 Region 位置信息,用来加快后续数据访问过程

  1. HBase客户端使用 HBase的RPC机制与Master和Region服务器进行通信
  2. 对于管理类操作,客户端与Master进行RPC
  3. 对于数据读写类操作,客户端则会与Region服务器进行RPC

Zookeeper



  • HBase 中可以启动 多个 Master,但是 Zookeeper 可以帮助选举出一个Master作为集群的总管,并保证在任何时刻总有唯一一个Master在运行,这就避免了Master 的“单点失效”问题。
  • Zookeeper中保存了-ROOT-表的地址和Master的地址,客户端可以 通过访问Zookeeper获得-ROOT-表的地址,并最终通过“三级寻址”找到
    所需的数据。Zookeeper中还存储了HBase的模式,包括有哪些表、每个表有哪些列族。

Master

主服务器Master主要负责表和Region的管理工作

  1. 管理用户对表的增加、删除、修改、查询等操作。
  2. 实现不同Region服务器之间的负载均衡。
  3. 在Region分裂或合并后,负责重新调整Region的分布。
  4. 对发生故障失效的Region服务器上的Region进行迁移。
  5. 客户端访问HBase上数据的过程并不需要Master的参与,Master 仅仅维护着表和Region的元数据信息,因此负载很低

注意:

  • 任何时刻,一个Region只能分配给一个Region服务器
  • Master维护 了当前可用的Region服务器列表,以及当前哪些Region分配给了哪些 Region服务器,哪些Region还未被分配

Region

Region服务器是 HBase中最核心的模块,负责维护分配给自己的 Region,并响应用户的读写请求

  • HBase 自身并不具备数据复制和维护数据副本的功能,而 HDFS 可以为HBase 提供这些支持

Region服务器内部管理了一系列Region对象和一个HLog文件

  • HLog : 是磁 盘上面的记录文件,它记录着所有的更新操作。

  • Region对象 : 是由 多个 Store 组成的

    • Store : 对应了表中的一个列族的存储,包含了一个 MemStore和若干个StoreFil
      • MemStore是在 内存中的缓存,保存最近更新的数据
      • StoreFile是磁盘中的文件,这些 文件都是B树结构的,方便快速读取

StoreFile在底层的实现方式是 HDFS文件系统的HFile,HFile的数据块通常采用压缩方式存储,压缩之后可以大大减少网络I/O和磁盘I/O

安装好后hbase启动没有进程 hbase安装问题_hbase_12

用户读写数据的过程

写入数据(三步):

  1. 当用户写入数据时,会被分配到相应的 Region 服务器去执行操作。
  2. 用户数据首先被写入到MemStore和HLog中,
  3. 当操作写入HLog之后,commit()调用才会将其返回给客户端

读入数据:
当用户读取数据时,Region服务器会首先访问MemStore缓存,如
果数据不在缓存中,才会到磁盘上面的StoreFile中去寻找。

缓存的刷新

MemStore 缓 存 的 容 量 有 限 , 系 统 会 周 期 性 地 调 用Region.flushcache()把MemStore缓存里面的内容写到磁盘的StoreFile文件 中,清空缓存

同时在HLog文件中写入一个标记,用来表示缓存中的内 容已经被写入StoreFile文件中

每次缓存刷新操作都会在磁盘上生成一个新的StoreFile文件,因此每个Store会包含多个StoreFile文件

注意:
每个Region服务器都有一个自己的HLog文件,在启动的时候,每 个Region服务器都会检查自己的HLog文件

  • 如果没有更新,说明所有数据已 经被永久保存到磁盘的StoreFile文件中
  • 如果发现更新,就先把这些更 新写入MemStore,然后再刷新缓存,写入到磁盘的StoreFile文件中

最后,删除旧的HLog文件,并开始为用户提供数据访问服务

Store原理

MemStore是排序的内存缓冲区。
用户写入数据过程步骤:

  1. 系统首先把 数据放入MemStore缓存
  2. 当MemStore缓存满时,就会刷新到磁盘中的 一个StoreFile文件中。
  3. 随着StoreFile文件数量的不断增加,当达到事先 设定的数量时,就会触发文件合并操作,多个StoreFile文件会被合并成 一个大的StoreFile文件。
  4. 当多个StoreFile文件合并后,会逐步形成越来 越大的StoreFile文件,当单个StoreFile文件大小超过一定阈值时,就会 触发文件分裂操作。
  5. 同时,当前的1个父Region会被分裂成2个子 Region,父Region会下线,新分裂出的2个子Region会被Master分配到相应的Region服务器上

安装好后hbase启动没有进程 hbase安装问题_服务器_13

HLog原理

在分布式环境下,必须要考虑到系统出错的情形,比如当Region服 务器发生故障时,MemStore缓存中的数据(还没有被写入文件)会全部丢失。因此,HBase采用HLog来保证系统发生故障时能够恢复到正确的状态。

HBase系统为每个Region服务器配置了一个HLog文件,它是一种预写式日志(Write Ahead Log),也就是说,用户更新数据必须首先被记
入日志后才能写入 MemStore 缓存
,并且直到MemStore缓存内容对应的日志已经被写入磁盘之后,该缓存内容才会被刷新写入磁盘

关键点:

  1. 每个 Region 服务器只需要维 护一个 HLog 文件,所有Region 对象共用一个 HLog,而不是每个 Region 使用一个 HLog
  2. 多个Region对象的更新操作所发生的日志修改,只需要不断把日志记录 追加到单个日志文件中
  3. 如果一个 Region 服务器发生故障,为了恢复其上的Region
    对象,需要将Region服务器上的HLog按照其所属的Region对象进行拆
    分,然后分发到其他Region服务器上执行恢复操作

错误处理过程

分步骤来:

  1. Zookeeper会实时监测每个Region服务器的状态,当某个Region服务 器发生故障时,Zookeeper会通知Master。
  2. Master首先会处理该故障 Region服务器上面遗留的HLog文件。由于一个Region服务器上面可能会 维护着多个Region对象,这些Region对象共用一个HLog文件,因此这个遗留的 HLog 文件中包含了来自多个 Region 对象的日志记录。
  3. 系统会 根据每条日志记录所属的Region对象对HLog数据进行拆分,分别放到 相应Region对象的目录下
  4. 然后再将失效的Region重新分配到可用的 Region服务器中,并把与该Region对象相关的HLog日志记录也发送给相 应的Region服务器。
  5. Region服务器领取到分配给自己的Region对象以及 与之相关的HLog日志记录以后,会重新做一遍日志记录中的各种操 作,把日志记录中的数据写入MemStore 缓存,然后刷新到磁盘的 StoreFile文件中,完成数据恢复
Hbase编程

启动hbase :hbase shell

create

#1.创建表t1,列族为f1,列族版本号为5
create 't1',{NAME => 'f1',VERSIONS => 5}
#2.创建表t1,和三个列族
create 't1',{NAME => 'f1'},{NAME => 'f2'},{NAME => 'f3'}
create 't1','f1','f2','f3'

#3.依据表分割算法HexStringSplit分布在15个Region里
create 't1','f1',{NUMREGIONS => 15,SPLITALGO => 'HexStringSplit'}
#4.指定分割点
create 't1','f1',{SPLITS => ['10','20','30','40']}

list

put

表名-行名-列名-值-时间戳
put 't1','row1','f1:c1','value1',1421987

get

表名-行名-列名-时间戳范围-版本号
get 't1','r1',{COLUMN => 'c1',TIMERANGE =>[ts1, ts2],VERSIONs=>4}

get 't1','r1','c1','c2'

scan

限制选项:
TIMERANGE 、 FILTER 、 LIMIT 、 STARTROW 、 STOPROW、TIMESTAMP、MAXLENGTH、COLUMNS、CACHE

scan 't1',{COLUMNS => 'c1',TIMERANGE => [start,stop]}

alter

alter 't1',NAME=>'f1'
alter 't1' ,NAME=>'f1',METHOD=>'delete'
NoSQL

NoSQL是非关系型数据库的统称,采取类似键/值、文档、列族等非关系型数据库的关系模型

概述

NoSQL的3大特点

  1. 灵活可扩展性
  2. 灵活的数据模型
  3. 与云计算紧密融合

NoSQL的缺点

  1. 缺乏数学理论
  2. 复杂查询性能不高
  3. 一般不能实现事务强一致性
  4. 技术不成熟

SQL的优点:

  1. 严格的关系代数理论
  2. 事务ACID四性
  3. 索引查询非常高效

SQL的缺点

  1. 海量数据的低效查询效率
  2. 无法满足高并发
  3. 可扩展性和可用性差

四种数据库:

  • 键值数据库
  • 列族数据库
  • 文档数据库
  • 图数据库

三大基石

CAP、BASE、最终一致性

CAP

  • Consistency :一致性, 任何一个读操作都能读到写操作的结果
  • Availability :可用性,快速获取数据
  • P(Tolerance of Paratition):分区容忍性,网络分区有节点中断,系统仍能正常运行

ACID

Atomicity : 原子性,事务必须是原子工作单元
Consistency:一致性,事务在完成时必须使所有数据保持一致状态
Isolation:隔离性,并发事务的修改必须与任何其他并发所做的修改一致
Durability:事务完成后对系统的影响是永久性的

BASE

基本可用:

  • 一个分布式系统的一部分发生问题,变成不可用时,其他部分仍然可以正常使用,运行分区失败

软状态:

  • 硬状态即数据一致性,数据必须一直正确。软状态可以有一段时间后不同步,具有时间滞后性

最终一致性:

强一致性/弱一致性:在高并发数据访问下,后续操作能够获取到最新的数据

最终一致性属于弱一致性,允许后续的访问操作暂时读不到最新的数据,但过一段时间最终可以读取到,非实时性