记hadoop故障一例:BlockAlreadyExistsException

hive版本:0.7.0 hadoop版本:0.20.2
在线上跑了一个季度了,基本上没什么问题,今天突然出了问题。

在hive执行时留下的蛛丝马迹:

Failed with exception org.apache.hadoop.hdfs.server.namenode.NotReplicatedYetException: Not replicated yet:/tmp/hive-root/hive_2011-08-15_00-31-02_332_247809173824307798/-ext-10000/access_bucket-2011-08-14_00004
at org.apache.hadoop.hdfs.server.namenode.FSNamesystem.getAdditionalBlock(FSNamesystem.java:1257)
at org.apache.hadoop.hdfs.server.namenode.NameNode.addBlock(NameNode.java:422)
at sun.reflect.GeneratedMethodAccessor2037.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.apache.hadoop.ipc.RPC$Server.call(RPC.java:508)
at org.apache.hadoop.ipc.Server$Handler$1.run(Server.java:959)
at org.apache.hadoop.ipc.Server$Handler$1.run(Server.java:955)
at java.security.AccessController.doPrivileged(Native Method)
at javax.security.auth.Subject.doAs(Subject.java:396)
at org.apache.hadoop.ipc.Server$Handler.run(Server.java:953)

FAILED: Execution Error, return code 1 from org.apache.hadoop.hive.ql.exec.CopyTask

在DN中发现:

2011-08-15 00:47:09,138 INFO org.apache.hadoop.hdfs.server.datanode.DataNode: writeBlock blk_8964076545845199727_216399 received exception org.apache.hadoop.hdfs.server.datanode.BlockAlreadyExistsException: Block blk_8964076545845199727_216399 is valid, and cannot be written to.
2011-08-15 00:47:09,138 ERROR org.apache.hadoop.hdfs.server.datanode.DataNode: DatanodeRegistration(192.168.1.23:50010, storageID=DS-52195649-192.168.1.23-50010-1299427987620, infoPort=50075, ipcPort=50020):DataXceiver
org.apache.hadoop.hdfs.server.datanode.BlockAlreadyExistsException: Block blk_8964076545845199727_216399 is valid, and cannot be written to.
at org.apache.hadoop.hdfs.server.datanode.FSDataset.writeToBlock(FSDataset.java:983)
at org.apache.hadoop.hdfs.server.datanode.BlockReceiver.(BlockReceiver.java:98)
at org.apache.hadoop.hdfs.server.datanode.DataXceiver.writeBlock(DataXceiver.java:259)
at org.apache.hadoop.hdfs.server.datanode.DataXceiver.run(DataXceiver.java:103)
at java.lang.Thread.run(Thread.java:662)

2011-08-15 00:47:15,366 WARN org.apache.hadoop.util.Shell: Could not get disk usage information
org.apache.hadoop.util.Shell$ExitCodeException: du: cannot access `/data/hadoop/data/dfs.data.dir/tmp/blk_-1540848236479330018_216371.meta': No such file or directory
du: cannot access `/data/hadoop/data/dfs.data.dir/tmp/blk_-1540848236479330018': No such file or directory

at org.apache.hadoop.util.Shell.runCommand(Shell.java:195)
at org.apache.hadoop.util.Shell.run(Shell.java:134)
at org.apache.hadoop.fs.DU.access$200(DU.java:29)
at org.apache.hadoop.fs.DU$DURefreshThread.run(DU.java:84)
at java.lang.Thread.run(Thread.java:662)


看着像是DN写入的时候遇到了服务不响应,追了一把,发现DN上全都忘记设置ulimit了,汗:
ulimit -SHn 18912

参考: http://www.cloudera.com/blog/2009/03/configuration-parameters-what-can-you-just-ignore/
http://www.michael-noll.com/blog/2011/04/09/benchmarking-and-stress-testing-an-hadoop-cluster-with-terasort-testdfsio-nnbench-mrbench/
http://sudhirvn.blogspot.com/2010/07/hadoop-error-logs-orgapachehadoophdfsse.html

Redmine极速安装手记

redmine install ubuntu Redmine是用Ruby开发的基于基于web的项目管理软件,是用ROR框架开发的一套跨平台项目管理系统,系统通过“项目(Project)”的形式把成员、任务(问题)、文档、讨论以及各种形式的资源组织在一起,大家参与更新任务、文档等内容来推动项目的进度,同时系统利用时间线索和各种动态的报表形式来自动给成员汇报项目进度。

机器环境:

ubuntu 10.04 dell optiplex 380
root权限下作

1)apt-get install mysql-client mysqld-server

2)进mysql:

create database redmine_default;
GRANT all ON redmine_default.* TO root@'%' IDENTIFIED BY 'miliao';
FLUSH PRIVILEGES ;

3)apt-get install redmine redmine-mysql subversion libapache2-mod-passenger

4)ln -s /usr/share/redmine/public /var/www/redmine

5)a2enmod passenger

6)chmod a+x /usr/share/redmine/public

7)/etc/apache2/sites-available/default
增加:

<Directory /var/www/redmine>
RailsBaseURI /redmine
PassengerResolveSymlinksInDocumentRoot on
</Directory>

8)/etc/init.d/apache2 restart
9)打开 http://xxx/redmine

排查问题:
1) /var/log/redmine下有500的原因
2)中文乱码问题:

上述第8步时,不要着急做配置。把redmine_default整个数据库导出来,替换其中的charset=laitin1为charset=utf8,清空原表重新导入后再用admin/admin登录重新配置。

Hive 0.7.0代码分析解读

hadoop hive

入口: bin/hive脚本中,环境检查后执行ext中的cli.sh,进入主类:CliDriver.main。

CliDriver.main: 把分号隔开命令进cli.processLine,再进processCmd。

processCmd: 处理quit/exit,再处理source,处理!,处理list;else建立CommandProcessor(实现有Driver和各种Processor),set/dfs/add/delete命令有单独的Processor,剩下的走Driver。

如果是Driver类型的Processor: 把cmd发到这个driver的run,再进到compile,在compile中,用一个parseDriver去生成ASTNode(生成使用了antlr,主要过程:经过文法分析器切割,进解析器,出来一个TREE),这里有细节的compile的过程说明 http://fromheartgo.wordpress.com/2010/04/02/hive%E7%9A%84compile%E8%BF%87%E7%A8%8B%EF%BC%881%EF%BC%89/ ;
根据得到的ASTNode,开始语义分析,把结果设置到一个QueryPlan对象中,初始化一些task放在QueryPlan中;

run里的test only代码读了test.serialize.qplan的设置,test状态会把这些查询记录写到文件里;权限检查。

退出complie,在Driver的run中分解执行MR后,退出来到了processCmd:
如果装填一切正常,通过getResults取到MR运行结果。

插一句,54chen最近在各处只谈,不谈技术,罪过罪过,只因看不下去了。

全过程如下:

CliDriver.main > processLine > processCmd >> Driver.run(cmd) > compile >> BaseSemanticAnalyzer >> xxxSemanticAnalyzer(常规select走SemanticAnalyzer) > analyze(sem.analyze) >> SemanticAnalyzer的analyzeInternal方法 >> new Optimizer.optimize(进行列剪裁等优化后生成Task) > genMapRedTasks >> 返回到Driver.run(cmd) >>ret = execute() >> launchTask >> TaskRunner.run > Task.executeTask > ExecDriver.execute > 执行MR(submitJob) >> getResults.

Spring配合easymock搞定不依赖环境的测试用例

spring easymock tutorial

在写java的test case的时候,往往有太多依赖环境的情况,WEB项目更甚,如果每次测试都要准备数据库或者其他环境,相当麻烦,换一个人就入手困难,在这种情况下,mock就是最好的选择。
Mock 对象能够模拟领域对象的部分行为,并且能够检验运行结果是否和预期的一致。领域类将通过与 Mock 对象的交互,来获得一个的测试环境。

入门

//准备一个mock
IMocksControl mocksControl = EasyMock.createStrictControl();
//创建录像
aDAO = mocksControl.createMock(AnalyzeResultDAO.class);
//录制 输入 期望输出
EasyMock.expect(aDAO.getARByLimit(type)).andReturn(ar);
//重放 表示录制结束
EasyMock.replay(aDAO);

//调用相关的类 验证结果是否正常
Assert.assertNotNull(analyzeResultBiz.getLastAR(type));

//验证是否使用了上面录制的DAO
EasyMock.verify(aDAO); 提高

* 配合spring如何做?

int type = 1;
AnalyzeResult ar = new AnalyzeResult();
ar.setName("123");
IMocksControl mocksControl = EasyMock.createStrictControl();
analyzeResultBiz = new AnalyzeResultBiz();
aDAO = mocksControl.createMock(AnalyzeResultDAO.class);
EasyMock.expect(aDAO.getARByLimit(type)).andReturn(ar);
EasyMock.replay(aDAO);
// 用spring提供的方法注入aurowired的字段
ReflectionTestUtils.setField(analyzeResultBiz, "analyzeResultDAO", aDAO, AnalyzeResultDAO.class);
Assert.assertNotNull(analyzeResultBiz.getLastAR(type));
EasyMock.verify(aDAO); 这样一录一用,看起来简单方便,实用美观大方,54chen强力推荐。

Ps:
所使用的包:

<dependency>
<groupId>org.easymock</groupId>
<artifactId>easymock</artifactId>
<version>2.4</version>
</dependency>