HBase是一个分布式的、非关系型开源数据库。 HBase有如下几个特点:首先HBase是No-SQL的一个典型实现,提升了系统的可扩展性;其次HBase支持线性水平扩展,极大提升了系统的可伸缩性和运算能力;最后HBase和Google的BigTable有异曲同工之妙,底层也是建立在HDFS(Hadoop分布式文件系统)之上,可以搭建在廉价的PC机集群上。No-SQL、云计算、海量数据分析的普及,使我们越来越关注系统的可靠性(High Availability),数据容灾/数据恢复是高可用系统的一个很重要的技术组成,本文由简入深,一步步搭建一个HBase数据集群,并详细说明生产环境如何使用HBase数据容灾方案。
HBase架构简介
HBase在完全分布式环境下,由Master进程负责管理RegionServers集群的负载均衡以及资源分配,ZooKeeper负责集群元数据的维护并且监控集群的状态以防止单点故障,每个RegionServer会负责具体数据块的读写,HBase所有的数据存储在HDSF系统上。
图一 HBase逻辑架构[1]
HBase集群部署
HBase集群物理架构
物理机
1
2
3
4
5
|
192.168.0.105 Master Ubuntu Desktop 11.10 Desktop
192.168.0.102 Slave1 Ubuntu Desktop 11.10 Desktop
192.168.0.103 Slave2 Ubuntu Desktop 11.10 Desktop
192.168.0.104 Slave3 Ubuntu Desktop 11.10 Desktop
192.168.0.101 Recover Ubuntu Desktop 11.10 Desktop
|
图二 集群物理架构
先决条件
SSH协议 [2]Hadoop集群之间的通讯采用的是SSH协议,所以要保证Master、Slave之间可以自由的通讯,一般推荐使用无验证通讯
- 安装SSH
12apt-get
install
openssh-server
apt-get
install
openssh-client
- 创建相同用户名的SSH公钥
在master主机和slave机上创建相同的用户hadoop
1sudo
adduser hadoop
- 在主机上生成公私钥key pair
12ssh
-keygen -t rsa -P
""
cat
$HOME/.
ssh
/id_rsa
.pub >> $HOME/.
ssh
/authorized_keys
- 将key值复制到slave1和slave2上
123scp
$HOME/.
ssh
/id_rsa
.pub hadoop@slave1:
/home/hadoop/
.
ssh
/authorized_keys
scp
$HOME/.
ssh
/id_rsa
.pub hadoop@slave2:
/home/hadoop/
.
ssh
/authorized_keys
scp
$HOME/.
ssh
/id_rsa
.pub hadoop@slave3:
/home/hadoop/
.
ssh
/authorized_keys
这样master就可以自由的访问slave节点了
Java安装
1
|
sudo
apt-get
install
sun-java6-jdk
|
Hadoop部署
Hadoop配置 [3]下载Hadoop 0.20.2版本[4]
- hadoop-env.sh
12export
JAVA_HOME=
/usr/lib/jvm/java-6-sun
export
HADOOP_HOME=
/home/hadoop/hadoop-0
.20.2
- master,slaves
1Master, Slave1, Slave2, Slave3
- core-site.xml
12345678<
property
>
<
name
>fs.default.name</
name
>
</
property
>
<
property
>
<
name
>hadoop.tmp.dir</
name
> //临时文件目录
<
value
>/data/tmp/hadoop</
value
> //注意不要放到/tmp目录下
</
property
>
- hdfs-site.xml
1234<
property
>
<
name
>dfs.replication</
name
> //备份文件
<
value
>1</
value
>
</
property
>
- mapred.xml
1234<
property
>
<
name
>mapred.job.tracker</
name
>
<
value
>master:9001</
value
>
</
property
>
hadoop namenode format //首先需要格式化namenode
1
|
bin
/start-all
.sh
|
验证服务:MapReduce管理界面http://master:50030/jobtracker.jsp
HBase部署
HBase配置下载HBase 0.90.50版本[5]
- HBase-env.sh
12export
JAVA_HOME=
/usr/lib/jvm/java-6-sun
export
HBase_MANAGES_ZK=
true
//zookeeper
随HBase启动
- HBase-site.xml
1234567891011121314151617181920<
property
>
<
name
>HBase.rootdir</
name
>
</
property
>
<
property
>
<
name
>HBase.cluster.distributed</
name
>
<
value
>true</
value
>
</
property
>
<
property
>
<
name
>dfs.replication</
name
>
<
value
>1</
value
>
</
property
>
<
property
>
<
name
>HBase.master</
name
>
<
value
>master</
value
>
</
property
>
<
property
>
<
name
>HBase.zookeeper.quorum</
name
>
<
value
>slave1,slave2,slave3</
value
>
</
property
>
Master主机上执行 $HBase_HOEM/bin/start-HBase.sh
验证:使用jps命令查看HBase的集群进程
HBase数据容灾
前面我们已经介绍过,如果HBase单个节点出现故障,Zookeeper会通知master主进程,master会将HLog日志进行拆分,分发到其他RegionServer上进行数据恢复。HBase对于单点故障的容错能力还是不错的,但是如果发生多点故障,现有的基本容错功能是远远不够的 (会造成数据丢失)。
HBase Replication机制[6]
HBase 0.90以后开始支持Replication机制,该机制设计的主导思想是基于操作日志(put/get/delete)做数据同步,这点很像MySQL基于Binary Log做statement-based replication[7]。
如下图所示,客户端的put/delete操作会被RegionServer写入本地的HLog中去,与此同时每个RegionServer会将 Hlog放入对应znode上的Replication队列,HBase集群会有一个独立的线程,根据固定大小的buffer值,将HLog内容推送到 Slave Cluster集群中的某个RegionServer上(当前版本只支持单个Slave Cluster复制),并在将当前复制的偏移量保存在ZooKeeper上,整个过程是异步完成的。
图三 HBase数据同步[8]
HBase Replication启动
- HBase-env.sh
12export
JAVA_HOME=
/usr/lib/jvm/java-6-sun
export
HBase_MANAGES_ZK=
false
//ZooKeeper
独立启动
- HBase-site.xml
master集群和slave集群的配置需要同时修改
1234<
property
>
<
name
>HBase.replication</
name
>
<
value
>true</
value
>
</
property
>
- Shell启动复制功能
123add_peer disable
'my_table_name'
//
表名字
alter
' my_table_name '
, {NAME =>
'family_name'
, REPLICATION_SCOPE =>
'1'
}
//
修改表schema
enable
' my_table_name'
1
2
3
|
Considering 1 rs, with ratio 0.1
Getting 1 rs from peer cluster
# 1
Choosing peer 192.168.0.101:62020
|
数据校验
为了保证数据一致性,生产环境上做异地容灾需要增加数据校验/数据监控。HBase的Replication机制,根据官方的文档提供了数据比对的工具类VerifyReplication[9]。我们可以将其功能包装起来,做自动化校验。下面是代码片段:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
final
String[] argumentsArray =
new
String[] {
"--starttime=xxxxxxxxxxx"
,
//开始时间戳根据具体的业务需要
"--stoptime="
+
new
Date().getTime(),
//选取当前时间戳作为结束的时间戳
"1"
,
//peer node id
"my_table_name"
//表名
};
final
Timer timer =
new
Timer();
timer.schedule(
new
TimerTask() {
@Override
public
void
run() {
try
{
Configuration conf = HBaseConfiguration.create();
Job job = VerifyReplication.createSubmittableJob(conf, argumentsArray);
job.waitForCompletion(
true
);
long
value = job.getCounters().findCounter(VerifyReplication.Verifier.Counters.BADROWS).getValue();
if
(value >
0
) {
Logger.getLogger(
"Finding Unmatched Rows! "
+ value);
}
}
catch
(Exception e) {
//异常处理策略
final
String msg =
"Comparing Job Error!"
;
Logger.getLogger(
this
.getClass()).error(msg, e);
try
{
SMTPClientWrapper.send(
"xxx@xxx.com"
,
"HBase replication error!"
, msg);
}
catch
(Exception e1) {
//考虑邮件服务器down机, failover
Logger.getLogger(
this
.getClass()).error(
"send alarm email error!"
, e);
}
}
}
},
0
,
600000
);
//十分钟校验一次
|
小结与展望
HBase的Replication机制,为增强系统可靠性提供了有力支持,但目前单节点Slave Cluster复制会增加系统的负荷并间接形成Slave Cluster的数据热点,期待HBase后续的版本支持多节点Slave Clusters复制。
引用
[1] http://ofps.oreilly.com/titles/9781449396107/intro.html
[2] http://en.wikipedia.org/wiki/Secure_Shell
[3] http://hadoop.apache.org/common/docs/current/cluster_setup.html
[4] http://hadoop.apache.org/common/releases.html#Download
[5] http://www.apache.org/dyn/closer.cgi/HBase/
[6] http://HBase.apache.org/replication.html
[7] http://dev.mysql.com/doc/refman/5.1/en/replication-formats.html
[8] http://HBase.apache.org/replication.html
[9] http://HBase.apache.org/xref/org/apache/hadoop/HBase/mapreduce/replication/VerifyReplication.html
作者:李湃 来源:Infoq中文