Hadoop Streaming示例程序(wordcount)

run_hadoop_word_counter.sh

$HADOOP_BIN streaming \
-input "${INPUT}" \
-output "${OUT_DIR}" \
-cacheArchive "${TOOL_DIR}/python2.7.2.tgz""#." \
-file "mapper_word_counter.py" \
-file "reducer_word_counter.py" \
-file "filter_word_counter.py" \
-mapper "./python2.7.2/bin/python mapper_word_counter.py" \
-combiner "./python2.7.2/bin/python reducer_word_counter.py" \
-reducer "./python2.7.2/bin/python reducer_word_counter.py" \
-jobconf abaci.job.base.environment="centos6u3_hadoop" \
-jobconf mapred.job.priority="NORMAL" \
-jobconf mapred.job.name="${TASK_NAME}" \
-jobconf mapred.map.tasks="${MAP_NUM}" \
-jobconf mapred.reduce.tasks="${REDUCE_NUM}" \
-jobconf mapred.map.memory.limit="1000" \
-jobconf mapred.reduce.memory.limit="1000" \
-jobconf mapred.job.map.capacity="3000" \
-jobconf mapred.job.reduce.capacity="2500" \
-jobconf mapred.job.keep.files.hours=12 \
-jobconf mapred.max.map.failures.percent=1 \
-jobconf mapred.reduce.tasks.speculative.execution="false"

mapper_word_counter.py

import sys 

for line in sys.stdin:
fields = line.strip().split('\t')
try:
cnt = 1
dateval = fields[1]
sys.stdout.write('%s\t%d\n' %(dateval, cnt))
except Exception as exp:
sys.stderr.write("exp:%s, %s" %(str(exp), line))

reducer_word_counter.py

import sys 

word_pre = None
counter_pre = 0 for line in sys.stdin:
try:
word, cnt = line.strip().split('\t')
cnt = int(cnt)
except Exception as exp:
sys.stderr.write('Exp:%s,line:%s' %(str(exp), line.strip()))
continue if word == word_pre:
counter_pre += cnt
else:
if word_pre:
print('%s\t%d' %(word_pre, counter_pre))
word_pre = word
counter_pre = cnt if word_pre:
print('%s\t%d' %(word_pre, counter_pre))

纯文本输入格式

  • 每个mapper输入若干行

    -inputformat "org.apache.hadoop.mapred.TextInputFormat" \
  • 指定每个mapper输入的行数

    -inputformat "org.apache.hadoop.mapred.lib.NLineInputFormat"

    -jobconf mapred.line.input.format.linespermap="5" \

注意:输入给mapper的内容会在每行前新增一行偏移的数字

文件分发方式:

-file将客户端本地文件打成jar包上传到HDFS然后分发到计算节点;

-cacheFile将HDFS文件分发到计算节点;

-cacheArchive将HDFS压缩文件分发到计算节点并解压;

分桶&排序

Hadoop默认会把map输出行中遇到的第一个分隔符(默认为\t)前面的部分作为key,后面的作为value,如果输出行中没有指定的分隔符,则整行作为key,value被设置为空字符串。mapper输出的key经过partition分发到不同的reduce里。

  • 应用示例
${HADOOP_BIN} streaming \
-input "${INPUT}" \
-output "${OUT_DIR}" \
-mapper cat \
-reducer cat \
-partitioner org.apache.hadoop.mapred.lib.KeyFieldBasedPartitioner \
-jobconf mapred.output.key.comparator.class=org.apache.hadoop.mapred.lib.KeyFieldBasedComparator \
-jobconf stream.num.map.output.key.fields=4 \
-jobconf stream.map.output.field.separator=. \
-jobconf map.output.key.field.separator=. \
-jobconf mapred.text.key.partitioner.options=-k1,2 \
-jobconf mapred.text.key.comparator.options="-k3,3 -k4nr" \
-jobconf stream.reduce.output.field.separator=. \
-jobconf stream.num.reduce.output.key.fields=4 \
-jobconf mapred.reduce.tasks=5

说明:

  • 设定mapper输出的key

    stream.map.output.field.separator 设置map输出的字段分隔符

    stream.num.map.output.key.fields 设置map输出的前几个字段作为key
  • 设定根据key进行分桶的规则

    org.apache.hadoop.mapred.lib.KeyFieldBasedPartitioner partition类

    map.output.key.field.separator 设置key内的字段分隔符(KeyFieldBasedPartitioner和KeyFieldBasedComparator所特有)

    num.key.fields.for.partition 设置key内前几个字段用来做partition

    mapred.text.key.partitioner.options 可单独指定key中哪些字段做partition,和num.key.fields.for.partition一起使用以num.key.fields.for.partition为准
  • 设定根据key进行排序的规则

    KeyFieldBasedComparator 可灵活设置的高级比较器,默认使用Text的基于字典序或者通过-n来基于数字比较

    mapred.text.key.comparator.options 设置key中需要比较的字段或字节范围
  • 设定reducer输出的key

    stream.reduce.output.field.separator 设置reduce输出的字段分隔符

    stream.num.reduce.output.key.fields 设置reduce输出的前几个字段作为key

多路输出

Hadoop支持多路输出,可以将MapReduce的处理数据输出到多个part-xxxxx-X文件中(X是A-Z共26个字母中的一个)。程序需要在maper(正对仅有mapper的MR任务)/reducer(针对包含reducer的任务)程序中将输出形式由<key,value>变为<key, value#X>,以便输出特定后缀的文件中。其中#X仅仅用做指定输出文件后缀, 不会出现在输出内容中。

启动脚本中需要指定

-outputformat org.apache.hadoop.mapred.lib.SuffixMultipleTextOutputFormat

或者

-outputformat org.apache.hadoop.mapred.lib.SuffixMultipleSequenceFileOutputFormat

  • 应用示例

    run_hadoop.sh
${HADOOP_BIN} streaming \
-input "${INPUT}" \
-output "${OUT_DIR}" \
-cacheArchive "${TOOL_DIR}/python2.7.2.tgz""#." \
-file "mapper_worker.sh" \
-file "reducer_worker.py" \
-mapper "sh mapper_worker.sh" \
-reducer "python2.7.2/bin/python reducer_worker.py" \
-inputformat "org.apache.hadoop.mapred.TextInputFormat" \
-outputformat "org.apache.hadoop.mapred.lib.SuffixMultipleTextOutputFormat" \
-jobconf mapred.job.priority="NORMAL" \
-jobconf mapred.job.name="${TASK_NAME}" \
-jobconf mapred.map.tasks="${MAP_NUM}" \
-jobconf mapred.reduce.tasks="${REDUCE_NUM}" \
-jobconf mapred.max.split.size=134217728 \
-jobconf mapred.map.memory.limit="800" \
-jobconf mapred.reduce.memory.limit="500" \
-jobconf mapred.job.map.capacity="3500" \
-jobconf mapred.job.reduce.capacity="2000" \
-jobconf mapred.job.keep.files.hours=12 \
-jobconf mapred.max.map.failures.percent=1 \
-jobconf mapred.reduce.tasks.speculative.execution="false"

reducer_worder.py

for line in sys.stdin:
record = line.strip()
fields = record.split('\t')
if len(fields) != 7:
continue
vcpurl, playurl, title, poster, duration, pubtime, accept = fields
duration = int(duration)
pubtime = int(pubtime)
accept = int(accept)
if duration < 60:
sys.stdout.write('%s#A\n' %(record))
elif duration < 300:
sys.stdout.write('%s#B\n' %(record))
else:
sys.stdout.write('%s#C\n' %(record))

本地调试

为避免在启动MR任务后才发现程序bug,最好提前在本地模拟MR的运行流程,验证结果是否符合预期

cat inputfile | ./mapper_task.sh | sort -t$'\t' -k1,1 | ./reducer.sh

压缩输出

Hadoop默认支持gzip压缩, streaming作业中指定以下参数即可使输出以gzip形式压缩.

-D mapreduce.output.fileoutputformat.compress=true
-D mapreduce.output.fileoutputformat.compress.codec=org.apache.hadoop.io.compress.GzipCodec

Hadoop 是可自行读取gzip压缩的数据,无需特殊指明输入是 Gzip 压缩。Gzip 的特点是压缩比较高,Hadoop 原生支持,缺点是压缩效率并不是很高,压缩比和效率不可兼得,需要考虑其他压缩方式。

Hadoop常用配置项

配置名 说明
abaci.job.base.environment centos6u3_hadoop 如果系统环境需要升级,可以指定为 centos6u3_hadoop 支持更高版本的 glibc
stream.memory.limit 单个map/reduce最高使用内存,默认800M
mapred.map.memory.limit 单个map最高使用内存,优先级高于stream.memory.limit
mapred.reduce.memory.limit 单个reduce最高使用内存,优先级高于stream.memory.limit
mapred.map.capacity.per.tasktracker 每台机器最多同时启动map个数
mapred.reduce.capacity.per.tasktracker 每台机器最多同时启动reduce个数
mapred.job.map.capacity map并发数目
mapred.job.reduce.capacity reduce并发数目
abaci.job.map.max.capacity map并发限制,默认10000
abaci.job.reduce.max.capacity reduce并发限制,默认3000
mapred.map.tasks map数目
mapred.reduce.tasks reduce数目
mapred.job.reuse.jvm.num.tasks 1表示不reuse,-1表示无限reuse,其他数值表示每个jvm reuse次数。reuse的时候,map结束时不会释放内存
mapred.compress.map.output 指定map的输出是否压缩。有助于减小数据量,减小io压力,但压缩和解压有cpu成本,需要慎重选择压缩算法
mapred.map.output.compression.codec map输出的压缩算法
mapred.output.compress reduce输出是否压缩
mapred.output.compression.codec 控制mapred的输出的压缩的方式
io.compression.codecs 压缩算法
mapred.max.map.failures.percent 容忍map错误百分比,默认为0
mapred.max.reduce.failures.percent 容忍reduce错误百分比,默认为0
stream.map.output.field.separator map输出分隔符,默认Tab
stream.reduce.output.field.separator reduce输出分隔符,默认Tab
mapred.textoutputformat.separator 设置TextOutputFormat的输出key,value分隔符,默认Tab
mapred.textoutputformat.ignoreseparator 设置为true后,当只有key没有value会去掉自动补上的Tab
mapred.min.split.size 指定map最小处理数据量,单位B
mapred.max.split.size 指定map最多处理数据量,单位B,同时设置inputformat=org.apache.hadoop.mapred.CombineTextInputFormat
mapred.combine.input.format.local.only 是否只合并本节点,默认true,设置为false可以跨节点合并数据
abaci.job.map.cpu.percent map消耗cpu占比,参数默认值40(表示1个cpu的40%,即0.4个cpu)
abaci.job.reduce.cpu.percent reduce消耗cpu占比,参数默认值40(表示1个cpu的40%,即0.4个cpu)
mapred.map.capacity.per.tasktracker 表示每个节点最多并行跑几个该job的map任务(请根据内存情况适当增减该参数,默认是8)
mapred.reduce.capacity.per.tasktracker 表示每个节点最多并行跑几个该job的reduce任务(请根据内存情况适当增减该参数,默认是8)
mapred.map.tasks.speculative.execution 开启map预测执行,默认true
mapred.reduce.tasks.speculative.execution 开启reduce预测执行,默认true

Hadoop环境下系统变量

  • 变量名列表
变量名 变量说明
HADOOP_HOME 计算节点上配置的Hadoop路径
LD_LIBRARY_PATH 计算节点上加载库文件的路径列表
PWD 当前工作目录
dfs_block_size 当前设置的HDFS文件块大小
map_input_file mapper正在处理的输入文件路径
mapred_job_id 作业ID
mapred_job_name 作业名
mapred_tip_id 当前任务的第几次重试
mapred_task_id 任务ID
mapred_task_is_map 当前任务是否为map
mapred_output_dir 计算输出路径
mapred_map_tasks 计算的map任务数
mapred_reduce_tasks 计算的reduce任务数

https://hadoop.apache.org/docs/r1.2.1/mapred_tutorial.html#Configured+Parameters

  • 应用示例:

    Shell版
#!/bin/bash

set -o pipefail
HOST="localhost"
PORT=$((1000 + ${mapred_task_partition})) awk '{print $2}' \
| ./access_remote_data ${HOST} ${PORT} outdata.gz hdfs_outfile=${mapred_work_output_dir}/${mapred_task_partition}.pack
cat outdata.gz \
| gzip -d \
| python ../postprocess.py
| ${HADOOP_HOME}/bin/hadoop fs -D hadoop.job.ugi="username,pwd" -copyFromLocal - ${hdfs_outfile}

Python版

import os

input_file = os.environ['mapreduce_map_input_file']
#do something else

References

Hadoop Streaming相关官方文档:https://hadoop.apache.org/docs/r3.1.2/hadoop-streaming/HadoopStreaming.html

Hadoop Streaming入门:http://icejoywoo.github.io/2015/09/28/introduction-to-hadoop-streaming.html

Hadoop排序工具用法小结:http://www.dreamingfish123.info/?p=1102

Hadoop压缩选项权衡:https://www.slideshare.net/Hadoop_Summit/singh-kamat-june27425pmroom210c

Hadoop常用操作汇总的更多相关文章

  1. Hadoop常用操作

    Hadoop常用操作 1.Hadoop安装 略 2.Hadoop配置 略 3.Hadoop多目录配置 namenode和datanode节点下都可以进行多个目录的配置,但是意义不同.namenode的 ...

  2. Kotlin——初级篇(八):关于字符串(String)常用操作汇总

    在前面讲解Kotlin数据类型的时候,提到了字符串类型,当然关于其定义在前面的章节中已经讲解过了.对Kotlin中的数据类型不清楚的同学.请参考Kotlin--初级篇(三):数据类型详解这篇文章. 在 ...

  3. Kotlin——关于字符串(String)常用操作汇总

    在前面讲解Kotlin数据类型的时候,提到了字符串类型,当然关于其定义在前面的章节中已经讲解过了.对Kotlin中的数据类型不清楚的同学.请参考Kotlin——初级篇(三):数据类型详解这篇文章. 在 ...

  4. Git常用操作汇总(转)

    如果一个文件被删除了,可以使用切换版本号进行恢复.恢复方法: 先确定需要恢复的文件要恢复成哪一个历史版本(commit),假设那个版本号是: commit_id,那么 git checkout com ...

  5. ListControl常用操作汇总

    本文根据本人在项目中的应用,来谈谈CListCtrl的部分用法及技巧.当初学习时,查了很多资料,零零碎碎的作了些记录,现在主要是来做个总结,方便以后查阅.主要包括以下十三点内容:基本操作.获取选中行的 ...

  6. ssh下常用操作汇总(good)

    1. 安装git,从程序目录打开 "Git Bash"  2. 键入命令:ssh-keygen -t rsa -C "email@email.com"   &q ...

  7. ElasticSearch 集群基本概念及常用操作汇总(建议收藏)

    内容来源于本人的印象笔记,简单汇总后发布到博客上,供大家需要时参考使用. 原创声明:作者:Arnold.zhao 博客园地址:https://www.cnblogs.com/zh94 目录: Elas ...

  8. Hadoop常用命令汇总

    启动Hadoop 进入HADOOP_HOME目录. 执行sh bin/start-all.sh 关闭Hadoop 进入HADOOP_HOME目录. 执行sh bin/stop-all.sh 1.查看指 ...

  9. Linux下常用操作汇总

    查看linux操作系统位数 (1) 终端输入: file /sbin/init 如 显示: /sbin/init: ELF 32-bit LSB executable, Intel 80386, ve ...

随机推荐

  1. Linux Centos7配置mysql8.0数据库

    本文转至:672530440 在此感谢博主,撒花!!! 本文主要从以下几个方面对自己在centos7 下安装mysql8过程做如下总结: CentOS7 安装mysql8 步骤: window下的Na ...

  2. SpringBoot mysql出现The server time zone value '�й���׼ʱ��' is unrecogni

    MySql :8.0.18 引入的mysql驱动: SpringBoot整合Mybatis的框架,在访问Controller的时候 : ava.sql.SQLException: The server ...

  3. Mysql基础学习_Windows版(一)

    1.Mysql简介 Mysql是一种关系数据库管理系统,关系数据库将数据保存在不同的表中,而不是将所有数据放在一个大仓库内,这样就增加了速度并提高了灵活性.所谓的关系型数据库,是建立在关系模型基础上的 ...

  4. 【转载】Android性能优化之渲染篇

    下面是渲染篇章的学习笔记,欢迎大家一起学习交流! 1)Why Rendering Performance Matters 现在有不少App为了达到很华丽的视觉效果,会需要在界面上层叠很多的视图组件,但 ...

  5. adb使用时出现unanthorized问题

    adb使用时出现unanthorized问题 ADB 启动时,adb devices出现unanthorized问题. 检查USB调试是否开启. 重新拔插USB数据线是否有授权提示 重启adb :ad ...

  6. 《形式化分析工具Scyther性能研究》------摘抄整理

    本篇论文的主要创新点在--------使用 Scyther工具发现对部分 KCI攻击搜索出现漏报的现象,并给出了存在的原因, 介绍了 形式化分析工具   AVispa全称是   Automated V ...

  7. LAMP源码编译安装

    php加速器 XCache 快速而且稳定的PHP opcode缓存,经过严格测试且被大量用于生产环境. 项目地址:http://xcache.lighttpd.net/,收录EPEL源 实现XCach ...

  8. VUE 单选下拉框Select中动态加载 默认选中第一个

    <lable>分类情况</lable> <select v-model="content.tid"> <option v-for=&quo ...

  9. PHP基础知识 - session和cookie的区别

    session:存储用户访问全局的唯一变量,在服务器上的PHP指定的目录中(session_dir)的位置进行存放 修改session的生存时间: (1)修改PHP.ini配置    修改php.in ...

  10. 《流畅的Python》Data Structures--第3章 dict 和 set

    dict and set 字典数据活跃在所有的python程序背后,即使你的源码里并没有直接使用它. 和dict有关的内置函数在模块builtins的__dict__内. >>> _ ...