转载HBase和RegionServer那些事儿——云计算的诅咒

http://blog.sina.com.cn/s/blog_707d72f60100llph.html

题记:近些年来,随着云计算的不断推进和推广,HBase作为为数不多的开源基于云计算的数据存储系统吸引了大量的注意,谁让人家身出名门呢。作为Nutch家族冉冉升起的一个新星,HBase以其良好的扩展性以及巨大的开发潜力被人们广为传颂。本文记述了一个普通的IT民工与开源软件斗智斗勇地真实故事,书写了一段可歌可泣的垒码传奇。

最近在家闲着无聊,遂想调戏一下HBase。

一般来说调戏HBase有两种方法,Cluster的方法和StandAlone的方法。前者算是标准使用方法,但是俺实在没有上得了规模的Cluster;后者一般是让大家认识HBase玩儿的,可以在单机上运行,运行的方式是启动一个Master和一个RegionServer,算是一个标准的ToyApplication吧。

但是我希望能够在一个机器上也能跑多个RegionServer,就像我们CloudDB那篇文章的实验一样,模拟一个更加真实的环境,可以便于很多想法的测试,我觉得这也可能是云计算的未来子方向之一:虚拟化。但是这种部署方式HBase并没有提供,于是我只能翻开毛选找答案,zhuxi说:自立更生,艰苦奋斗。领导说啥就是啥,弄之~

我要提到的这种方法需要对HBase的源代码做一些修改,诸位看官且听我娓娓道来~

1.Cygwin:他拯救了地球

这一步算是准备工作吧,HBase只能在Linux环境下运行,伟大的WIndows不能让他低头,于是我们只能绕道而行:上Cygwin。这里要注意最好把SSH装上,虽然在单机下似乎不需要,不过还是装了的好,以后万一用得着呢。

2.LocalHBaseCluster的崛起

org.apache.hadoop.hbase这个包里有个叫做LocalHBaseCluster的类,这是我们的出发点。从这个类的名字大家也可以看出它似乎应该提供在本地运行HBase的功能,它也确实不会辜负大家,然而,这后面却隐藏着一个惊天的秘密,这里先按下不表。

找到这个LocalHBaserCluster之后,将其初始化,代码如下:

HBaseConfigurationconf=newHBaseConfiguration();

conf.set(HConstants.MASTER_ADDRESS,"local:6000");

Stringpath="file:////home/Owner/master_home";

Filedir=newFile(path);

dir.mkdirs();

conf.set(HConstants.HBASE_DIR,path);

LocalHBaseClustercluster=newLocalHBaseCluster(conf);

cluster.startup();

上面的代码建立了一个LocalCluster,似乎不用费多少功夫嘛,那就先将其跑起来吧~

3.白手起家打天下,各路jar包来助阵。

因为我修改了HBase的源码,所以部署时也选择了可能是比较复杂的方法:重新编译,从头部署。

第一步,将编译后的bin拷贝到Cygwin的home目录下。

第二步,将下载的HBase的src目录下的webapps目录放到刚才copy的bin目录下面,webapps包含了运行需要的jsp文件。

第三步,这是很tricky的一步。我当初修改的源代码是从下载的HBase的src/java下来的,但是这里面其实缺了一个很重要的目录,那就是——generated目录。当初为了寻找因为缺失这个目录所引发的Exception根源,我可是望穿了秋水啊~这位客观问了,那既然src下面都没有,让我去哪儿找啊?哇哈哈,这就是开源软件的阴险之处:自己找去~!……………………………………算了还是我告诉你吧,这个目录需要从你下载的HBase的jar包里找,其实这个目录是将上面提到的jsp文件编译成了class文件。好了,将这个偷来的目录拷贝到home/bin下面它该去的地方。

第四步,jar包!jar包!jar包!HBase运行依赖的包那是相当的多,主要来源是两个:一个是下载的HBase的lib目录下的那些个jar包;第二个是tomcat里的诸多包,为了保险起见,你最好将你能在tomcat的目录下能找到的jar包统统拿走。那么拿了人家这么多jar包,放到哪里去呢?答案有两个配置:勤快人配置:放到一个和bin同级的lib目录里,然后以后在cmd运行程序时指定classpath;懒人配置:统统放到jre的lib/ext目录下,这个目录里的jar包在任何java程序运行时都会首先来这里找,找不到再去classpath里找。你问我用的哪种方法?……今天天气真不错哈~

4.家有LocalCluster初长成,有主有仆乐融融。

有了上面的配置,我们的第一个LocalCluster就要火爆登场了,大家给点儿掌声!

现在就可以运行了,通过Cygwin进入到bin目录下,鼓起全部勇气敲出引领大家进入java殿堂的那一行古老而神秘的命令吧:java-org.apache.hadoop.hbase.test.HBaseTest.

智商较高的朋友们可能已经猜出,没错,HBaseTest就是包含了刚才那一段代码的启动LocalHBaseCluster的类。随着你的拇指或者小指或者食指或者其他某个手指在Enter键上用堪比dxp同志当年画圈圈之气势做出那惊鸿一敲,屏幕在迟钝了一下之后,开始水银泻地一般地输出各种花花绿绿的日志信息,由于我们刚才在jar包人才的引进方面做足了工作,使得这次运行没有爆出任何Exception,你也可以松一口气了:HBase跑起来了~

不过,似乎还缺了些什么……你的心中升起了一股莫名的恐惧~

5.风云突变,祸起端口。

想起来了,我们最初的目的是在一台机器上跑多个RegionServer,现在我们做到了吗?做到了吗?你猜猜?哈哈,做没做到要代码说了算。跟踪LocalHBaseCluster的代码可以发现,刚才用的构造方法是构造了一个包含一个Master和一个RegionServer的实例。什么?费了这么半天劲不就是搞了个StandAlone模式么???你欺骗我的青春!……其实我没有。

那现在这个情况和StandAlone模式有什么区别呢?

StandAlone其实是提供给HBase的EndUser的一种使用模式,用户可以通过终端命令操作HBase,如建立表,插入数据等。而回顾一下我们刚才的部署过程就可以发现,我们做的其实是为开发人员服务的一种模式。其实也不是什么本质的区别,关键问题是:用HBase的StandAlone模式实现不了多个RegionServer的宏伟蓝图。

好吧,既然如此,那LocalHBaseCluster有没有可以指定RegionServer数量的构造方法?你别说,还真有,那好,那我们就指定为2个试试吧。你心中暗爽:java就是TMD简单~

修改程序,重新编译,copy新文件,经历这些之后你再次施展了敲Enter大法,然后等待着满屏幕的日志信息来证明你的伟大以及java的傻瓜。你做到了,果然又是一屏幕的日志,不过在这乱七八糟的日志中,你发现了一丝不详的预兆:Exception!是的,是Exceptoin,java程序员除了老板之外最讨厌的东西!别的不用说,单是他那比别人多缩进一次的排版就可以知道他是个浪荡不羁,鱼肉程序员的坏小子。对付这种敌人怎么办?又一次,我们翻开毛选找答案,这次zhuxi说:一些fd派都是纸老虎~

纸老虎,zhuxi说得轻巧,这只老虎连个形状都没有,抓起来谈何容易,不过既然领导说了,我们就要抱着必胜的信念,排除万难去争取胜利!

俗话说:Throwable生九Exception,九Exception各不同。先来看看我们遇到的是个什么Exception。黑屏白字写的是:BindException:Addressalreadyinuse:JVM_Bind。原来是个地址端口问题,有名有姓就好查了,开狐狸,放狗~!你别说,网上关于这个Exception的报告还真不少,可我们的问题在于Exception中没有提到被占用的是哪个端口,这可怎么办?望着netstat输出的一长溜进程和端口号,我绝望了……

这时,突然有一个飘渺的声音在天空对我喊道:追代码……追代码……一时间,我精神抖擞!对啊,作为一个英勇无畏的java战士,怎么忘了自己的终极武器了?于是我高举着以System.out为核心的追代码策略,团结在以Eclipse为核心的IDE周围,开始了轰轰烈烈的debug工程。

具体流程我就不加赘述了,总结起来就是:把Exceptionstack中所有出现了地址和端口号的地方都打印出来,看看冲突究竟在哪里。加入错误追踪信息的程序又一次起航了,这一次,System.out又立功了!我用在茫茫人海中寻找失散多年的亲人的目光在日志信息中搜寻,终于找到问题了:两个RegionServer占用了同一个端口……并且一举抓获了犯罪代码~

6.要坚持具有应用需要特色的拿来主义一百年不动摇!

为什么会有这个问题呢?分析起来其实很简单,默认的LocalHBaseCluster只启动一个RegionServer,而Cluster应用的RegionServer又是一台机器只跑一个,所以RegionServer占用的端口号是固定的,那么自然就出现了刚才描述的端口冲突的情况。

发现了问题就好办,找到犯罪代码,修改之,让每次增加的RegionServer使用一个新的端口就行了。Apache的东西固然质量好,但是适合不适合应用需求就要具体分析了,而这也和我国领导层确立的坚持有中国特色的社会主义的原则不谋而合,看来天下的事,说到底,也都差不多~

7.经济基础决定上层建筑,内存大小决定Cluster规模。

到这里,大的问题基本就解决了,但是还有最后一个小问题却是不能忽视的。

如果我们将LocalCluster的规模设置为2的话,经过刚才的修改HBase是可以正常运行的。

但是当我修改为5时,也就是有5个RegionServer时,程序却崩溃了,凶手就是我们熟悉的:OutofMemory!

为什么呢?在Cluster应用中,由于每个机器只跑一个RegionServer,所以可以最大程度地利用该机器上的资源,从代码可以看出至少要占用1024*1024*5*4字节,也就是20M的内存,而如果我们在一台机器上运行5个RegionServer,就至少需要100M的内存。问题就在于java运行时如果不加指定,默认的内存使用上限只有64M,所有出现这个问题就不奇怪了。

所以在运行时加入-Xmx参数指定最大内存就可以了。

8.万里雄关真如铁,而今迈步从头越。

到这里,在单机上部署运行多个RegionServer的蓝图我们已经实现了,但是这只是万里长征的第一步。部署起来HBase,我们就可以对自己的一些修改和想法进行实现和评估,这,才是使用HBase更加重要的目的。开源项目从来都不是直接给人用的,更多的,是给大家提供推动IT进步的一个平台。

好了,让我用周润发同学的著名广告词结束本篇吧:成功,我才刚上路~

相关推荐