Hbase

本文介绍Hbase。但本文的前提是假设你已经读过Google的BigTable论文。

Introduction

Hbase 是基于Google Big Table用java实现的分布式,列式存储的数据库。传统的关系型数据库虽然已经存在了很多年,并且有很多成熟的解决方案,但是对大数据的支持略显不做。虽然关系型数据库也有一些集群,分布式等方案来处理大数据,但从关系型数据库从最初的设计上就不是为大数据而生的,所以都有其局限性。

Building Blocks

这一段将概述Hbase的架构。将从以下几个方面来讲:

Table row column Cell

Auto-Sharding

Storage API

Implementation


总结

Table , row, column, cell

Hbase 的table 是一个多维表。 表中的每一行数据都是由(rowkey,column,timestamp) 到 value的映射。或者说是rowkey,column映射到cell,而cell中的数据则保存着不同timestamp的不同版本。具体请参考BigTable的数据模型。
column 和 BigTable中一样,有column family的概念。column family 在创建表的时候就要指定。不同的一个column family下可以创建任意个column。而且不同的行可以有多个不同的column。

Auto-Sharding

Sharding 是数据库中一个通用的概念。Sharding的基本思想就要把一个数据库切分成多个部分放到不同的数据库(server)上,从而缓解单一数据库的性能问题。我们知道BigTable中rowkey 按字典顺序排序,一个大的table 根据rowkey的范围分割成很多区域叫tablet。 Hbase中这个概念叫region。Hbase中的region和 BigTable中的tablet几乎没有区别。 一个表根据rowkey的范围分割成多个region。region 由region server负责管理。当region过大了,region server负责split region。 region 是hbase集群中负载均衡的单位,当一个region server有太多的region, hbase会通过负载均衡让压力较小的region server去承担工作。

Storage API

和BigTable 一样。Hbase提供的API能够

create / delete  table和column family

操作table column family的metadata

操作table去读写数据

implementation

BigTable 中有一个SSTable。 在Hbase中叫做 HFile。和SSTable一样,HFile用来存储Hbase 的 column family数据。HFile中存储的数据也是键值对。在HFile的最底层有一个索引。因为HFile物理上也是一个个data block组成的,该索引用来查找对应的data block。 HFile对外提供接口可以根据key快速查找value,也可以对一个给定的Key范围对相应的 key-value 迭代。

HFile存储在HDFS中。在写入HFile之前,对数据的操作要写入一个redo log,在Hbase中这个redo log叫做 write-ahead-log WAL. 写入 WAL后,数据被写入内存中一个叫memstore的内存结构。当一个memstore满了后,该memstore flush到硬盘变成HFile。flush 后WAL 就可以丢弃了。memstore就是HFile的内存形式。 这一段和BigTable 的原理是一样的,不过名词略有不同。下面是一个名词对照表:

SSTable : HFile

commit log : WAL

GFS : HDFS

memtable : memstore

minor compaction : flush

HFile 和 SSTable 一样是不可变的。所以当做Delete 操作的时候 只能是写入一个带有delete 标记的记录,这样在读的时候该标记确保客户端读不到被删除的数据。

read的操作需要把memstore 和 对应的HFile 读入内存并merge。 WAL 在读操作中永远不会用到。WAL只有在server down掉的时候用来恢复 HFile。

Hbase中有mincompaction和major compaction。因为memstore定期flush到硬盘所以小的HFile会很多。minor compaction会定期的合并一些。 要注意这和BigTable中的minor compaction有点不一样。 BigTable 中的minor compaction和这里的flush对应。 还有一种majro compaction和BigTable中的概念一样。就是把同一个region下的同一个column family的HFile合并成唯一的一个。而且在合并的过程中会把之前标记为删掉的数据真正删掉。

和BigTable一样 Hbase 也由三部分组成, Master , region server 和 client library 。
Master 负责管理整个集群,负责region 的分配, 负责region server的负载均衡节点添加等操作。 Region server 管理若干个region。 client 直接和region server进行通信I/O。 这样减少了Master 的负载。 集群间协调工作用ZooKeeper。

Install

Hbase在安装前要先规划。Hbase中有Master 和 region server的概念。我们知道region server 负责I/O 所以region server的要求就是网速要好,硬盘容量要充足,并且I/O要好。 而 Master的CPU处理速度要高。 同时我们知道 Hbase基于HDFS。所以还要为安装HDFS 做一些规划。 HDFS 分name node 和data node。 data node 的要求和region server差不多,而name node 的要求和master server类似。我们的实验中用三台机器,Master和namenode 装在一台机器上,而region server和data node 装在一起。 规划如下:

名称

ip

role

s1

192.168.1.81

name node && data node

s2

192.168.1.82

data node

s3

192.168.1.83

data node

在安装Hbase 之前要安装 HDFS。 安装HDFS之前则有一些通用的工作要做:

install java
配置s1 无密码访问s1,s2,s3
配置3台服务器使用统一的NTP 服务器

这些操作是比较通用的操作,这里不介绍。 在做完这些操作后开始第一步

Install HDFS

安装HDFS之前要配置一些环境变量如下:

export HADOOP_PREFIX="/opt/hadoop/hadoop-2.7.1"
export HADOOP_HOME=$HADOOP_PREFIX
export HADOOP_COMMON_HOME=$HADOOP_PREFIX
export HADOOP_CONF_DIR=$HADOOP_PREFIX/etc/hadoop
export HADOOP_HDFS_HOME=$HADOOP_PREFIX
export HADOOP_MAPRED_HOME=$HADOOP_PREFIX
export HADOOP_YARN_HOME=$HADOOP_PREFIX

然后去官网下载你想安装的hadoop版本。注意是hadoop而不是hdfs。因为hdfs是集成在hadoop的package中的。

wget http://apache.mirrors.spacedump.net/hadoop/common/stable/hadoop-2.7.1.tar.gz

把package放到之前指定的hadoop_prefix目录下解压缩。
三台机器的配置都一样
在$HADOOP_PREFIX/etc/hadoop/hdfs-site.xml中做如下配置:

<configuration>
    <property>
        <name>dfs.datanode.data.dir</name>
        <value>file:///opt/hadoop/hadoop-2.7.1/hdfs/datanode</value>
        <description>Comma separated list of paths on the local filesystem of a DataNode where it should store its blocks.</description>
    </property>

    <property>
        <name>dfs.namenode.name.dir</name>
        <value>file:///opt/hadoop/hadoop-2.7.1/hdfs/namenode</value>
        <description>Path on the local filesystem where the NameNode stores the namespace and transaction logs persistently.</description>
    </property>
</configuration>

在$HADOOP_PREFIX/etc/hadoop/core-site.xml中做如下配置:

<configuration>
    <property>
        <name>fs.defaultFS</name>
        <value>hdfs://s1/</value>
        <description>NameNode URI</description>
    </property>
</configuration>

启动停止

## Start HDFS daemons
# Format the namenode directory (DO THIS ONLY ONCE, THE FIRST TIME)
# ONLY ON THE NAMENODE NODE
$HADOOP_PREFIX/bin/hdfs namenode -format
# Start the namenode daemon
# ONLY ON THE NAMENODE NODE
$HADOOP_PREFIX/sbin/hadoop-daemon.sh start namenode
# Start the datanode daemon
# ON ALL SLAVES
$HADOOP_PREFIX/sbin/hadoop-daemon.sh start datanode

Install Hbase

hbase的安装其实也是解压。去官网下载你需要的package解压到/opt/hbase下。注意java要提前安装并且配置JAVA_HOME
三个节点的配置都一样,所以只要在一个节点上配置完成然后把文件copy到其他节点即可。 编辑conf/hbase-env.sh 在开始部分加入source /root/.bash_profile。 这是为了加载你之前设置的环境变量。 如果你把环境变量写入了不同文件, 那么这里需要加载对应的profile 文件。

编辑conf/regionservers ,内容如下:

s1
s2  
s3

编辑conf/backup-masters(如果没有则创建),内容如下:

s2

编辑配置文件conf/hbase-site.xml ,增加内容如下:

<property>
  <name>hbase.cluster.distributed</name>
  <value>true</value>
</property>
<property>
  <name>hbase.rootdir</name>
  <value>hdfs://s1/hbase</value>
</property>
<property>
  <name>hbase.zookeeper.quorum</name>
  <value>s1,s2,s3</value>
</property>
<property>
  <name>hbase.zookeeper.property.dataDir</name>
  <value>/usr/local/zookeeper</value>
</property>
<property>
        <name>
                hbase.regionserver.port
        </name>
        <value>
                18020
        </value>
        <source>
                hbase-default.xml
        </source>
</property>

这里修改了region server的监听地址指定为18020而不是采用默认, 因为master其实也是region server。 所以如果不修改,那么master以及backup master无法与region server起在同一台机器上。

在s1上启动 start-hbase.sh 会启动cluster中所有节点。
启动后可以通过http://s1:16010/ 访问master的web ui。
进入hbase安装目录的bin

./start-hbase.sh
swapness

region presplit

wal