python-map()/reduce()

最近刷leetcode,发现使用map()/reduce()这两个函数往往可以四两拨千金.但是使用起来却不简单,记录下来,免得忘记.

一 map(): 形式是map(function, sequence)
接受两个参数,第一个是函数,第二个是个可迭代对象.返回也是一个可迭代对象
第二个对象的元素依次带入第一个函数里面进行计算:

def func(x):
    return x*x
m=map(func,range(1,4))
print(list(m))
#输出:[1, 4, 9, 16]

如果传入多个对象,则按元素最少的为准:

def func(x,y):
    return x+y
m=map(func,range(1,8),range(3,6))
print(list(m))
#输出:[4, 6, 8]

二 reduce(): 要先导入库 functors .
形式是reduce(function, sequence,[initial])
接受三个参数,第一个是函数,第二个是个可迭代对象,第三个是初始值,返回是一个值
第一个函数必须有两个参数,必需.
第二个序列是个可迭代对象,如tuple ,list ,dictionary, string等,必需.
第三个初始值计算时作为函数第一个参数,如果序列为空,则返回初始值,非必需,如果没有初始值,则函数第一个参数是序列第一个元素,第二个参数是序列第二个元素.(有妙用!)
例如,

from functools import reduce
res = reduce(lambda x, y: x+y, [1, 2, 3, 4, 5])
print(res)
#1+2+3+4+5
#输出:15
from functools import reduce
res = reduce(lambda x, y: x+y, [1, 2, 3, 4, 5],1)
print(res)
#1+1+2+3+4+5
#输出:16
<think>我们面对的是HadoopStreaming任务失败的问题,具体有两个主要错误:1.PipeMapRed.waitOutputThreads():subprocessfailedwithcode1-说明mapper或reducer进程异常退出(返回非0状态码)2.容器因超出虚拟内存限制被YARN杀死(Containerkilledonrequest.Exitcodeis143)根据日志分析:-Mapper任务尝试3次均失败,错误码1(Python脚本执行异常)-Reducer任务因内存超限被终止(虚拟内存使用2.6GB,超过2.1GB限制)==解决思路==1.修复Python脚本异常(确保mapper/reducer能在集群环境运行)2.调整YARN内存参数(解决容器被杀问题)3.优化Python代码内存使用===详细解决方案===1.**诊断Python脚本错误**Mapper失败的根本原因是Python脚本执行异常。通过以下步骤诊断:-在脚本入口添加异常捕获(确保异常信息输出到stderr)```python#my_mapper_csv.py示例改造importsysimporttracebackdefmain():forlineinsys.stdin:#处理逻辑if__name__=="__main__":try:main()exceptExceptionase:sys.stderr.write(f"ERROR:{str(e)}\n")sys.stderr.write(traceback.format_exc())sys.exit(1)```-本地测试脚本:```bashcatinput.csv|python3my_mapper_csv.py```-常见错误:-Python版本不匹配(集群节点可能缺python3)-未安装必需库(如pandas等)-输入数据格式不符合预期(空行、字段不足等)2.**调整内存配置**原始任务内存参数不足,需在命令行或`mapred-site.xml`中增加:```bashhadoopjar...\-Dmapreduce.map.memory.mb=4096\#容器物理内存上限4GB-Dmapreduce.reduce.memory.mb=8192\-Dmapreduce.map.java.opts="-Xmx3072m"\#JVM堆内存(为容器内存留余量)-Dmapreduce.reduce.java.opts="-Xmx6144m"\-Dyarn.nodemanager.vmem-pmem-ratio=4.5\#虚拟内存/物理内存比例调高(默认2.1易超限)...```**参数解释**:-`mapreduce.[map|reduce].memory.mb`:容器分配的物理内存-`mapreduce.[map|reduce].java.opts`:JVM堆大小(通常设为内存的75%)-`yarn.nodemanager.vmem-pmem-ratio`:虚拟内存扩展系数(可调至4-5)3.**Python代码内存优化**即使调整配置,脚本自身也需控制内存:-**避免全量加载数据**(流式处理):```python#错误示例(数据大时内存爆炸)data=[lineforlineinsys.stdin]#正确做法(逐行流式)forlineinsys.stdin:process(line)```-**减少对象引用**(及时释放):```python#大对象用完后立即删除large_list=[...]result=compute(large_list)dellarge_list#主动释放```-**使用生成器代替列表**(reducer分组时尤其关键):```pythonfromitertoolsimportgroupbyforkey,groupingroupby(sys.stdin,key=key_func):process_group(list(group))#注意:groupby要求输入已排序```===任务重启命令示例===综合调整后,完整任务提交:```bashhadoopjar"$HADOOP_HOME/share/hadoop/tools/lib/hadoop-streaming-3.1.3.jar"\-files"hdfs:///absolute/path/to/my_mapper_csv.py,my_reducer_csv.py"\#分发脚本(HDFS路径或本地)-archives"hdfs:///path/python_env.zip#pyenv"\#携带Python环境(若有第三方库)-Dmapreduce.map.memory.mb=4096\-Dmapreduce.reduce.memory.mb=8192\-Dyarn.nodemanager.vmem-pmem-ratio=5\-input/my_input_csv/*\-output/my_output.csv\-mapper"pyenv/bin/pythonmy_mapper_csv.py"\#使用归档中的Python解释器-reducer"pyenv/bin/pythonmy_reducer_csv.py"```注意:-`-files`替换废弃的`-file`参数[^1]-若用`-archives`,集群所有节点无需预装相同Python环境===相关配置参考===在`mapred-site.xml`中永久设置内存参数(避免每次命令行输入):```xml<configuration><!--内存设置--><property><name>mapreduce.map.memory.mb</name><value>4096</value></property><property><name>mapreduce.reduce.memory.mb</name><value>8192</value></property><property><name>yarn.nodemanager.vmem-pmem-ratio</name><value>5</value></property></configuration>```[^1]:引用配置示例</think> ### Hadoop Streaming任务失败分析与解决方案 #### 问题诊断 1. **PipeMapRed.waitOutputThreads()错误** - 日志显示Mapper进程以错误码1退出:`subprocess failed with code 1` - 常见原因: * Python脚本执行异常(未捕获的异常) * 集群节点缺失Python依赖 * 输入数据格式问题(如CSV字段缺失) 2. **内存超限错误** ```log Container [pid=72527...] is running 537983488B beyond the 'VIRTUAL' memory limit Current usage: 168.3 MB of 1 GB physical memory used; 2.6 GB of 2.1 GB virtual memory used ``` - 虚拟内存(2.6GB)超出限制(2.1GB) - Reducer任务因内存超限被杀死(Exit code 143) --- #### 完整解决方案 ##### 第一步:修复Python脚本问题 1. **添加异常处理机制** 在Python脚本中添加全局异常捕获: ```python # my_mapper_csv.py 修改示例 import sys import traceback def process_line(line): # 原数据处理逻辑 return processed_data if __name__ == "__main__": try: for line in sys.stdin: result = process_line(line) print(result) except Exception as e: sys.stderr.write(f"ERROR: {str(e)}\n") sys.stderr.write(traceback.format_exc()) # 输出堆栈 sys.exit(1) # 必须返回非零退出码 ``` 2. **验证脚本本地执行** ```bash cat sample.csv | python3 my_mapper_csv.py | sort | python3 my_reducer_csv.py ``` 检查是否有错误输出 ##### 第二步:解决内存超限问题 1. **调整YARN内存参数** ```bash hadoop jar hadoop-streaming-3.1.3.jar \ -D mapreduce.map.memory.mb=4096 \ # 容器物理内存 -D mapreduce.reduce.memory.mb=8196 \ # Reducer需要更多内存 -D mapreduce.map.java.opts="-Xmx3072m" \ # JVM堆内存 -D mapreduce.reduce.java.opts="-Xmx6144m" \ -D yarn.nodemanager.vmem-pmem-ratio=5 \ # 虚拟/物理内存比(默认2.1) -files my_mapper_csv.py,my_reducer_csv.py \ # 替换-file参数 -mapper "python3 my_mapper_csv.py" \ -reducer "python3 my_reducer_csv.py" \ -input /my_input_csv/* \ -output /my_output.csv ``` 2. **关键参数说明** | 参数 | 推荐值 | 作用 | |------|--------|------| | `yarn.nodemanager.vmem-pmem-ratio` | 4-5 | 解决虚拟内存超限问题 | | `mapreduce.reduce.memory.mb` | ≥4096 | Reducer物理内存 | | `mapreduce.reduce.java.opts` | 物理内存的75% | JVM堆大小 | ##### 第三步:优化Python脚本内存 1. **避免全量加载数据** ```python # 错误做法(内存爆炸): data = [line for line in sys.stdin] # 正确做法(流式处理): for line in sys.stdin: fields = line.strip().split(",") # 立即处理并输出 ``` 2. **使用分组迭代器** ```python # Reducer优化示例 from itertools import groupby def key_func(line): return line.split(",")[0] # 按首字段分组 sorted_data = sorted(sys.stdin, key=key_func) for key, group in groupby(sorted_data, key=key_func): process_group(list(group)) # 分组处理 ``` ##### 第四步:永久配置优化(mapred-site.xml) ```xml <configuration> <!-- 内存参数优化 --> <property> <name>yarn.nodemanager.vmem-pmem-ratio</name> <value>4.5</value> </property> <property> <name>mapreduce.map.memory.mb</name> <value>4096</value> </property> <property> <name>mapreduce.reduce.memory.mb</name> <value>8192</value> </property> <!-- 历史服务器配置(便于调试) --> <property> <name>mapreduce.jobhistory.address</name> <value>master:10020</value> </property> </configuration> ``` #### 调试技巧 1. **查看完整错误日志** ```bash yarn logs -applicationId application_1744881937486_0004 > debug.log grep "Caused by" debug.log -A 15 ``` 2. **监控内存使用** 在Python脚本中添加: ```python import resource # Mapper/Reducer中定期输出 sys.stderr.write(f"MEM USAGE: {resource.getrusage(resource.RUSAGE_SELF).ru_maxrss} KB\n") ``` --- ### 相关问题 1. 如何为Hadoop Streaming任务分发Python虚拟环境? 2. YARN容器被杀(Exit code 143)有哪些具体原因? 3. 如何动态调整MapReduce任务的Reducer数量?[^4] 4. Hadoop Streaming与原生Java任务性能差异如何优化? 5. 如何监控Hadoop集群中各节点的内存使用情况?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值