现在的位置: 首页 > 搜索技术 > 黄专家专栏 > 正文

Hadoop Local 模式运行 Pipes 程序

2014年10月30日 搜索技术, 黄专家专栏 ⁄ 共 2024字 ⁄ 字号 评论关闭

秒速赛车公式 www.l19l7.cn 现在用的 hadoop 的版本是 0.20.2-cdh3u6。 cdh 是 Cloudera 的开源版本。

使用 local 模式的时候,会出现几个错误,记录如下:

1. java.lang.NullPointerException 异常

1
2
3
4
5
6
7
java.lang.Exception: java.lang.NullPointerException
  at org.apache.hadoop.mapred.LocalJobRunner$Job.run(LocalJobRunner.java:349)
Caused by: java.lang.NullPointerException
  at org.apache.hadoop.mapred.pipes.Application.<init>(Application.java:103)
  at org.apache.hadoop.mapred.pipes.PipesMapRunner.run(PipesMapRunner.java:68)
  at org.apache.hadoop.mapred.MapTask.runOldMapper(MapTask.java:390)
  ... ...

追踪以上错误的代码,我们可以知道,空指针异常是由于 jobToken 引起的,深入代码可以知道,hadoop pipes 从 TokenCache 中读入一个叫 “ShuffleAndJobToken” 的 token,然后写入一个 jobTokenPassword 文件。但是在 local 模式下并没有这个 key 对应的 token, 也就无从写入。 所以,修改代码

1
2
Token<JobTokenIdentifier> jobToken = TokenCache.getJobToken(conf.getCredentials());
byte[]  password = jobToken.getPassword();

1
2
3
4
5
Token<JobTokenIdentifier> jobToken = TokenCache.getJobToken(conf.getCredentials());
byte[] password = "no password".getBytes();
if (jobToken != null) {
  password = jobToken.getPassword();
}

2. jobTokenPassword 的文件权限

修改 jobTokenPassword 的文件权限

1
2
FSDataOutputStream out = FileSystem.create(localFs, localPath,
  new FsPermission("400"));

改为

1
2
FSDataOutputStream out = FileSystem.create(localFs, localPath,
  new FsPermission("666"));

3. userlog 目录的生成

在 src/mapred/org/apache/hadoop/mapred/pipes/Application.java 文件中,一下代码会将标准输入和标准错误重定向到你的日志文件中。

一般日志文件是在 ${hadoop.log.dir}/userlog/${jobid}/${taskid}/stdout 这样的方式出现的,但是在 local 模式中,不会为你建立这样的目录,所以导致执行 pipes 的 c++ 进程失败。

修改代码建立日志目录即可

1
2
3
File stdout = TaskLog.getTaskLogFile(taskid, false, TaskLog.LogName.STDOUT);
File stderr = TaskLog.getTaskLogFile(taskid, false, TaskLog.LogName.STDERR);
long logLength = TaskLog.getTaskLogLength(conf);

加入建立目录的代码

1
2
3
4
5
6
7
8
9
10
11
File stdout = TaskLog.getTaskLogFile(taskid, false, TaskLog.LogName.STDOUT);
File stderr = TaskLog.getTaskLogFile(taskid, false, TaskLog.LogName.STDERR);
long logLength = TaskLog.getTaskLogLength(conf);

String[] dirs = new String[1];
dirs[0] = TaskLog.getAttemptDir(taskid, false).toString();
try {
  TaskLog.createTaskAttemptLogDir(taskid, false, dirs);
} catch (IOException e) {
  LOG.info("Creation of failed.");      // 日志目录已经存在
}

现在 local 模式的 pipes 程序就可以运行了

抱歉!评论已关闭.

  • 听,盲童唱出心底的阳光 2018-12-17
  • 老婆告老公索债780万 原是二人自导自演 2018-12-17
  • 井冈山交警开展重点车辆严重交通违法行为有奖举报工作 2018-12-17
  • 停车收费新政首日举报量攀升 2018-12-17
  • 这是世界杯开赛当晚的广西 2018-12-16
  • 【理上网来·喜迎十九大】建设世界一流军队的科学指南 2018-12-16
  • 第六届北京农业嘉年华--北京频道--人民网 2018-12-16
  • 【专题】节能降耗 保卫蓝天——浙江省暨杭州市2018年节能宣传周 2018-12-15
  • 【奋斗在新时代】劳道“歹猫”增色互联网“表情” 2018-12-15
  • 驾车撞倒城管队员反复碾压 义乌暴力摊贩被刑拘 2018-12-15
  • 《中国汽车报》2018“西部温暖计划”公益试驾活动即将启程 2018-12-14
  • 奇瑞新能源瑞虎3xe上市 售价8.98万 2018-12-14
  • 几家性价比超高的烤肉店 赶紧去试试 2018-12-14
  • 和“看着就想笑”说说你的“8421” 2018-12-13
  • 中共十八大以来藏语新词术语发布 2018-12-13
  • 293| 765| 855| 514| 107| 642| 81| 700| 992| 871|