在Hadoop Streaming作业中引入Python包nltk失败的问题求助
解决Hadoop Streaming中Python导入nltk失败的问题
我之前在Hadoop Streaming里部署Python第三方依赖时也踩过类似的坑,给你几个经过验证的解决方案:
方案1:通过sys.path引入打包好的nltk依赖包
你当前用了zipimport,其实更简单的方式是把nltk打包成zip文件,然后直接添加到Python的搜索路径里,这样代码更简洁也更容易排查问题:
步骤1:正确打包nltk
首先找到你的本地nltk安装目录:
python -c "import nltk; print(nltk.__file__)"
输出类似/usr/local/lib/python3.x/site-packages/nltk/__init__.py,那么我们需要把上层的nltk文件夹打包成zip:
zip -r nltk.zip /usr/local/lib/python3.x/site-packages/nltk
步骤2:修改mapper代码
把zip包路径加入sys.path,再导入nltk:
#!/usr/bin/env python ''' trainingMapper1_test.py ''' import sys # 将nltk.zip添加到Python模块搜索路径最前面 sys.path.insert(0, 'nltk.zip') import nltk from nltk.tokenize import WordPunctTokenizer def getToken(input): tokenizer = WordPunctTokenizer() allTokens = tokenizer.tokenize(input) return allTokens def read_input(file): for line in file: # 补全你截断的逻辑,比如处理每行文本并输出 tokens = getToken(line.strip()) print(' '.join(tokens)) if __name__ == '__main__': read_input(sys.stdin)
方案2:通过Hadoop Streaming的-file参数分发依赖
Hadoop Streaming的-files参数可以把本地文件(包括脚本、依赖包)分发到每个任务节点的工作目录,确保mapper能找到nltk.zip:
提交作业的命令示例:
hadoop jar $HADOOP_HOME/share/hadoop/tools/lib/hadoop-streaming.jar \ -files trainingMapper1_test.py,nltk.zip \ -mapper trainingMapper1_test.py \ -reducer your_reducer_script.py \ -input /hdfs/input/path \ -output /hdfs/output/path
额外注意事项(若用到nltk数据文件)
如果你的后续逻辑需要用到nltk的数据(比如语料库、模型),还要把nltk_data目录也打包,并用-files参数提交,同时在代码里指定数据路径:
import nltk # 指向任务节点上的nltk_data目录 nltk.data.path.append('./nltk_data')
常见问题排查
- 避免用
nltk.mod这类非常规的文件名,保持nltk.zip的命名更规范,减少识别问题 - 检查zip包的目录结构:解压后应该直接看到
nltk文件夹及其子文件,不要嵌套额外的目录层级 - 确保zip包和脚本有可读权限,避免节点上的Hadoop进程无法读取
内容的提问来源于stack exchange,提问作者Min Chen
相关产品推荐
相关产品推荐

