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

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 程序就可以运行了

抱歉!评论已关闭.

  • 马上背!十九大报告中的四个“新” 2019-02-16
  • 蒲县工商质监局非公党委举办2018元旦文艺会 2019-02-16
  • 人民网评:建设数字中国时不我待 2019-02-16
  • 618史上最壕“买家”现身 Google以 5.5亿美元投资京东 2019-02-15
  • 雍正官窑:朕就是这样的品味(图) 2019-02-15
  • 西安司法考试将试点机考 2019-02-15
  • 人民日报新媒体矩阵聚焦十九大 融媒报道"给你好看" 2019-02-14
  • 社会主义是过渡阶段,最终实现共产主义才是其目的。社会主义是在消灭私有制,建立公有制直至无私,实现共产主义。 2019-02-14
  • 四轮电动车销售火爆存安全隐患 专家:需建国家标准 2019-02-14
  • 看懂汽车三元催化器工作原理后还能当金子卖?难为非洲兄弟了! 2019-02-14
  • 周杰伦昆凌为儿子庆生 小小周帅气入镜 2019-02-13
  • 都以为机器人普及了,一切都不是问题了?机器人不需要不断升级?机器人生产啥?不需要人设计? 2019-02-13
  • 价值-热门标签-华商生活 2019-02-13
  • 上合组织引领发展 吉中合作稳步前行——访吉尔吉斯斯坦总统热恩别科夫 2019-02-13
  • 互联网金融协会提示:防范变相“现金贷”业务风险 2019-02-12
  • 730| 737| 905| 531| 917| 125| 561| 703| 75| 84|