本文主要讲解三个问题:
      1 使用Java编写MapReduce程序时,如何向map、reduce函数传递参数。
      2 使用Streaming编写MapReduce程序(C/C++, Shell, Python)时,如何向map、reduce脚本传递参数。
      3 使用Streaming编写MapReduce程序(C/C++, Shell, Python)时,如何向map、reduce脚本传递文件或文件夹。
         (1) streaming 加载本地单个文件
          (2) streaming 加载本地多个文件
         (3) streaming 加载本地目录
         (4) streaming编程时在mapreduce脚本中读 hdfs 文件
         (5) streaming编程时在mapreduce脚本中读 hdfs 目录
 
1.  Java编写MapReduce程序时,如何向map、reduce函数传递参数

我开始使用如下方式进行传递.

在主类中声明两个静态变量, 然后在 main 函数中给变量赋值, 试图在 map和reduce函数中获得变量的值。
代码结构类似如下:
提交到集群运行发现在 map 和 reduce函数中, 静态变量MaxScore的值始终是初值1。
于是试图在主类的静态区中给变量赋值 (因为静态区中的代码比main中的代码要先执行), 仍是不成功, MaxScore的值始终是初值1。
将上述代码在 单机hadoop上运行, 结果正常, map 函数中能获得变量的值。
思考是这个原因: 在提交作业到hadoop集群后,mapper类和reducer类就到各个 tasktracker上去运行了, 与主类独立, 不能交互。
因此,上述往 map 和 reduce 函数传参数的方法实在太天真。
于是想到其它一些方法: 例如将参数写入hdfs文件中, 然后在 mapper 和 reducer 类的 run方法中读取文件, 并将值读到相应变量,这是可行的,但是方法较复杂,代码如下:
上述方法尽管可用, 但是不是常规方法, 下面介绍常用的方法:
(1) 通过 Configuration 来传递参数
在main函数中调用set方法设置参数, 例如:
在mapper中通过上下文context来获取当前作业的配置, 并获取参数, 例如:
注: context 很有用, 能获取当前作业的大量信息,例如上面就获取了任务ID.
 
(2) 利用org.apache.hadoop.io.DefaultStringifier类

示例:

main中:

Configuration conf = new Configuration();

Text maxscore = new Text("12989");

DefaultStringifier.store(conf, maxscore ,"maxscore");

这样,Text对象maxscore就以“maxscore”作为key存储在conf对象中了,然后在map和reduce函数中调用load的方法便可以把对象读出。

mapper获取:

Configuration conf = context.getConfiguration()

Text out = DefaultStringifier.load(conf, "maxscore", Text.class);

需要说明的是,这个需要传递的对象必须要先实现序列化的接口,Hadoop的序列化是通过Writable接口来实现的

(2) 参考自:http://blog.sina.com.cn/s/blog_6b7cf18f0100x9jg.html

2.  编写 Streaming 程序时,如何向map、reduce函数传递参数

可以通过 streaming 的 cmdenv 选项设置环境变量,然后在 map 和 reduce 脚本中获取环境变量。

可参考 << hadoop streaming 高级编程 >>

http://dongxicheng.org/mapreduce/hadoop-streaming-advanced-programming/

(0) 作业提交脚本:

#!/usr/bin/env bash

max_read_count=${array[0]}

min_read_count=${array[1]}

max_write_count=${array[2]}

min_write_count=${array[3]}

hadoop jar $HADOOP_HOME/contrib/streaming/hadoop-0.20.2-streaming.jar \

-D mapred.reduce.tasks=1 \

-input $input \

-output $output  \

-mapper $mapper_script \

-file $map_file  \

-reducer $reducer_script \

-file $reduce_file \

-cmdenv "max_read_count=${array[0]}" \      # 设置环境变量   max_read_count .

-cmdenv "min_read_count=${array[1]}" \       # 多个变量时请多次使用 -cmdenv

-cmdenv "max_write_count=${array[2]}" \

-cmdenv "min_write_count=${array[3]}" \

(1) Python mapper.py

#!/usr/bin/env python

import sys

import os

min_r_count = float(os.environ.get('min_read_count')) # get environment variables.

max_r_count = float(os.environ.get('max_read_count'))

min_w_count = float(os.environ.get('min_write_count'))

max_w_count = float(os.environ.get('max_write_count'))

(2)Shell mapper.sh

#!/usr/bin/env bash

while read line  # 读入行

do

a=$line

done

echo $min_read_count $max_read_count  # get environment variables.

(3)C/C++ mapper.c

#include <stdio.h>

#include <string.h>

int main(int argc, char *argv[], char *env[])

{

double min_r_count;

int i = 0;

for (i = 0; env[i] != NULL; i++) // env[i] 存储了环境变量, 每项的值为此种形式: PATH=******, 所以需要截取变量值

{

if( strstr(env[i], "PATH=") ) {

char *p =NULL;

p = strstr(env[i], "=");

if( (p-env[i]) == 4 )

printf("%s\n", ++p); // 获取 PATH 环境变量

}

if( strstr(env[i], "min_write_count=") ) {

char *p =NULL;

p = strstr(env[i], "=");

if( (p-env[i]) == strlen("min_write_count") )

printf("%s\n", ++p); // 获取  min_write_count  环境变量

}

}

char eachLine[200]={0};

while(fgets(eachLine, 199, stdin)) // read line from stdin

{

printf("%s", eachLine);

}

}


注意:
    Hadoop执行命令时的选项有顺序的, 顺序是 bin/hadoop command [genericOptions] [commandOptions]. 
    对于streaming, -D 属于genericOptions, 即hadoop的通用选项, 所以必须写在前面.
    Streaming 的所有选项可以参考:  
    hadoop jar $HADOOP_HOME/contrib/streaming/hadoop-0.20.2-streaming.jar -info
 
3.  编写 Streaming 程序时,如何向map、reduce函数传递文件或文件夹。

(1) streaming 加载本地单个文件

streaming 支持 -file 选项, 可以把 -file 后面的本地文件(注意是本地文件)打包成作业提交的一部分, 即打包到作业的jar文件当中, 这样在mapreduce脚本中就可以像访问本地文件一样访问打包的文件了.

实例:

作业提交文件 run.sh

mapper.py

注意:在提交作业时使用的是 -file logs/wbscoretest.log 指定需要加载的文件. 在 map 脚本中只需要直接读取文件 wbscoretest.log 即可, 不需要写 logs/wbscoretest.log, 因为只加载了文件 wbscoretest.log, 而不会加载 logs 目录和

wbscoretest.log 文件.

(2) streaming 加载本地多个文件 

(3) streaming 加载本地目录 ( 若加载多个目录,用逗号隔开,-files dir1, dir2, dir3 )

使用streaming的 -file 选项不能加载本地目录, 我实验是如此.

我们可以使用 hadoop 的通用选项 -files 来加载本地目录, 加载成功后在mapreduce脚本中可以像访问本地目录一样访问加载的目录.

实际应用中,我们在编写 分词MapReduce作业时需要加载分词词典,就使用该方法.

作业提交脚本:

map 脚本: 读取目录下的文件.

加载多个目录:

注意:多个目录之间用逗号隔开,且不能有空格,否则会出错,这个限制太蛋疼了。

例如:

(4) streaming编程时在mapreduce脚本中读 hdfs 文件

使用 -files 选项, 后面跟需要读的 hdfs 文件路径. 这样在 mapreduce 脚本中就可以直接通过文件名来访问该文件.

作业提交脚本:

map脚本:

如果需要加载大文件, 我们可以将文件先上传到 hdfs 中, 然后在 mapreduce 脚本中读取 hdfs 文件.

(5) streaming编程时在mapreduce脚本中读 hdfs 目录

使用 -files 选项, 后面跟需要读的 hdfs 目录. 这样在 mapreduce 脚本中就可以像访问本地目录一样访问该目录.

作业提交脚本:

map脚本:  直接读取 tmp_kentzhan 目录.

【hadoop】如何向map和reduce脚本传递参数,加载文件和目录的更多相关文章

  1. 如何向map和reduce脚本传递参数,加载文件和目录

    本文主要讲解三个问题:       1 使用Java编写MapReduce程序时,如何向map.reduce函数传递参数.       2 使用Streaming编写MapReduce程序(C/C++ ...

  2. (转)如何向map和reduce脚本传递参数

    [MapReduce] 如何向map和reduce脚本传递参数,加载文件和目录 分类: hadoop2014-04-28 21:30 1553人阅读 评论(0) 收藏 举报 hadoop 本文主要讲解 ...

  3. python 脚本传递参数

    python查找指定字符 #!/usr/bin/env python import sys import re f = open("log.txt", "rb" ...

  4. PowerShell脚本传递参数

    在编写PowerShell脚本的时候,可以通过给变量赋值的方法输出想要的结果,但这样的话,需要改动脚本内容.其实也可以在脚本中定义参数,然后再在执行脚本的时候对参数赋值,而无需改动脚本内容. 在Pow ...

  5. linux shell编程指南第二十章------向脚本传递参数

    前面已经讲到如何使用特定变量$ 1 . . $ 9向脚本传递参数.$ #用于统计传递参数的个数.可 以创建一个u s a g e语句,需要时可通知用户怎样以适当的调用参数调用脚本或函数. 简单地说,下 ...

  6. shell调用python脚本,并且向python脚本传递参数

    1.shell调用python脚本,并且向python脚本传递参数: shell中: python test.py $para1 $para2 python中: import sys def main ...

  7. 分发系统介绍、expect脚本远程登录、expect脚本远程执行命令、expect脚本传递参数

    7月19日任务 20.27 分发系统介绍20.28 expect脚本远程登录20.29 expect脚本远程执行命令20.30 expect脚本传递参数 20.27 分发系统介绍 公司业务逐渐扩大时, ...

  8. Linux centosVMware运行告警系统、分发系统-expect讲解、自动远程登录后,执行命令并退出、expect脚本传递参数、expect脚本同步文件、指定host和要同步的文件、shell项目-分发系统-构建文件分发系统、分发系统-命令批量执行

    一运行告警系统 创建一个任务计划crontab -e 每一分钟都执行一次 调试时把主脚本里边log先注释掉 再次执行 没有发现502文件说明执行成功了,每日有错误,本机IP 负载不高 二.分发系统-e ...

  9. 学习加密(四)spring boot 使用RSA+AES混合加密,前后端传递参数加解密

      学习加密(四)spring boot 使用RSA+AES混合加密,前后端传递参数加解密 技术标签: RSA  AES  RSA AES  混合加密  整合   前言:   为了提高安全性采用了RS ...

随机推荐

  1. Oracle 11g安装GI后,运行roothas.pl脚本报错libcap.so.1找不到

    环境:RHEL6.4 + Oracle 11.2.0.3问题:需求是文件系统迁移到ASM,在安装GI后,运行roothas.pl脚本报错 1.运行root.sh后,按提示运行roothas.pl报错 ...

  2. WebGIS中利用AGS JS+eChart实现一些数据展示的探索

    文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/. 1.背景 eChart提供了迁徙图.热点图.夜视图等跟地图能够很好的结 ...

  3. 关于C#静态变量初始化问题

    关于这个静态变量,平时自己没有太认真的去认识.最近调项目的bug,让我重新认识了静态变量的特点. 其实,我们一直都在说:静态变量只在类第一次初始化的时候进行初始化,以后都不初始化. 很简单的一句话,但 ...

  4. git安装和初次使用

    为了知道某人安装git,我也是重装啊. 1.下载git并安装 2.打开我的电脑,右键属性,选择高级设置,打开环境变量设置: 3.键盘输入窗口键+r,或者点击开始->运行 输入cmd 在新打开的命 ...

  5. Django 1.10 中文文档------3.2.2 查询操作making queries

    3.2.2 查询操作 6.15章节包含所有模型相关的API解释. 后面的内容基于如下的一个博客应用模型: from django.db import models class Blog(models. ...

  6. Struts2 源码分析——Action代理类的工作

    章节简言 上一章笔者讲到关于如何加载配置文件里面的package元素节点信息.相信读者到这里心里面对struts2在启动的时候加载相关的信息有了一定的了解和认识.而本章将讲到关于struts2启动成功 ...

  7. 糖果 bzoj 2330

    糖果(1s 128MB)candy [题目描述] 幼儿园里有N个小朋友,lxhgww老师现在想要给这些小朋友们分配糖果,要求每个小朋友都要分到糖果.但是小朋友们也有嫉妒心,总是会提出一些要求,比如小明 ...

  8. 流的文件操作(File)

    一.流的分类: 1.流按照方向分类:分为输入流和输出流,流的操作是相对于内存而言. 输入流的定义:当我们从数据源中将数据读取到内存中就称为输入流,也叫读取流. 输出流的定义:当我们将内存中处理好的数据 ...

  9. 搭建自己的apache tomcat php mysql 环境和WordPress站点制作

    无论你是web开发人员,还是程序员,拥有一个自己的站点总没有坏处,下面我们就从搭建wordpress的环境来说吧. 1.首先wordpre是用的php语言,所以需要php环境,最基本的数据库也不能缺少 ...

  10. HTML5自定义属性之data-*

    HTML5 增加了一项新功能是 自定义数据属性 ,也就是  data-* 自定义属性.在HTML5中我们可以使用以 data- 为前缀来设置我们需要的自定义属性,来进行一些数据的存放.当然高级浏览器下 ...