Hadoop常用操作汇总
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常用操作汇总的更多相关文章
- Hadoop常用操作
		
Hadoop常用操作 1.Hadoop安装 略 2.Hadoop配置 略 3.Hadoop多目录配置 namenode和datanode节点下都可以进行多个目录的配置,但是意义不同.namenode的 ...
 - Kotlin——初级篇(八):关于字符串(String)常用操作汇总
		
在前面讲解Kotlin数据类型的时候,提到了字符串类型,当然关于其定义在前面的章节中已经讲解过了.对Kotlin中的数据类型不清楚的同学.请参考Kotlin--初级篇(三):数据类型详解这篇文章. 在 ...
 - Kotlin——关于字符串(String)常用操作汇总
		
在前面讲解Kotlin数据类型的时候,提到了字符串类型,当然关于其定义在前面的章节中已经讲解过了.对Kotlin中的数据类型不清楚的同学.请参考Kotlin——初级篇(三):数据类型详解这篇文章. 在 ...
 - Git常用操作汇总(转)
		
如果一个文件被删除了,可以使用切换版本号进行恢复.恢复方法: 先确定需要恢复的文件要恢复成哪一个历史版本(commit),假设那个版本号是: commit_id,那么 git checkout com ...
 - ListControl常用操作汇总
		
本文根据本人在项目中的应用,来谈谈CListCtrl的部分用法及技巧.当初学习时,查了很多资料,零零碎碎的作了些记录,现在主要是来做个总结,方便以后查阅.主要包括以下十三点内容:基本操作.获取选中行的 ...
 - ssh下常用操作汇总(good)
		
1. 安装git,从程序目录打开 "Git Bash" 2. 键入命令:ssh-keygen -t rsa -C "email@email.com" &q ...
 - ElasticSearch 集群基本概念及常用操作汇总(建议收藏)
		
内容来源于本人的印象笔记,简单汇总后发布到博客上,供大家需要时参考使用. 原创声明:作者:Arnold.zhao 博客园地址:https://www.cnblogs.com/zh94 目录: Elas ...
 - Hadoop常用命令汇总
		
启动Hadoop 进入HADOOP_HOME目录. 执行sh bin/start-all.sh 关闭Hadoop 进入HADOOP_HOME目录. 执行sh bin/stop-all.sh 1.查看指 ...
 - Linux下常用操作汇总
		
查看linux操作系统位数 (1) 终端输入: file /sbin/init 如 显示: /sbin/init: ELF 32-bit LSB executable, Intel 80386, ve ...
 
随机推荐
- 【vue开发】vue指令Vue.directive使用教程
			
1.指令的注册 指令跟组件一样需要注册才能使用,同样有两种方式,一种是全局注册: ? 1 2 3 4 5 Vue.directive('dirName',function(){ //定义指令 ...
 - Django中使用xadmin作为后台管理页面
			
xadmin后台管理 安装:luffy虚拟环境下 # >: pip install https://codeload.github.com/sshwsfc/xadmin/zip/django2 ...
 - GNS3
			
什么是GNS? GNS Graphical Network Simulator Simulator or Emulator? 尽管GNS全拼包含simulator,但实际上是emulator.我们说其 ...
 - maven jar 包不在项目中
			
maven update project maven build
 - linux tar打包压缩排除某个目录或文件
			
用tar打包时想剔除打包目录中的某个子目录或文件: 比如你想打包/home这个目录,但是/home/afish/目录和/home/www/afish.php文件你都不想打包,方法是: tar -zcv ...
 - devops发展历程
			
第一阶段:只有 Dev ,没有 Ops ,Dev 是全栈工程师 如何理解?最初的时候,产品和业务形态都处于摸索期,业务复杂度不高,访问量不大,软件能够尽快跑起来推向市场是最重要的,所以架构上不设计的很 ...
 - 部署kibana节点
			
部署Kibana节点 1.查看系统环境: [root@Kibana ~]# hostname Kibana [root@Kibana ~]# cat /etc/redhat-release CentO ...
 - 【翻译】PATH究竟是什么?
			
最近,我试图向一个朋友解释他电脑上PATH变量是用来做什么的.我在我们所交流的平台‘the Slack group"写了一篇比较长的消息之后,我意识到这个主题可以写成一个很好的博客,所以开始 ...
 - 如何查看float在内存中存储方式
			
float fla = -1000; unsigned int *pfla = (unsigned int*)&fla; printf("fla=%X\n",*pfla); ...
 - position:absolute 按钮左右分布:left:0  和 right:0 以及雪碧图
			
问题:把两个a标签按钮 垂直居中,并且分别把两个按钮放在水平左右两边顶部1,祖父元素设定:position:relative2,把.arrow 设定上下垂直居中 position:absolute; ...