我正试图在亚马逊的EMR上运行一个mrjob。我已使用内联转轮在本地测试了该作业,但在亚马逊上运行时失败了。我已将故障范围缩小到依赖于外部数据文件zip_codes.txt
。如果我使用硬编码的邮政编码数据运行没有那种依赖,它就可以正常工作。
我尝试使用upload file参数包含必要的数据文件。当我查看S3时,该文件确实存在,但显然出现了问题,因此我无法在本地访问它。
这是我的mrjob.conf
文件:
runners:
emr:
aws_access_key_id: FOOBARBAZQUX
aws_secret_access_key: IAMASECRETKEY
aws_region: us-east-1
ec2_key_pair: mapreduce
ec2_key_pair_file: $ENV/keys/mapreduce.pem
ssh_tunnel_to_job_tracker: true
ssh_tunnel_is_open: true
cleanup_on_failure: ALL
cmdenv:
TZ: America/Los_Angeles
这是我的MR_zip.py
文件。
from mrjob.job import MRJob
import mrjob
import csv
def distance(p1, p2):
# d = ...
return d
class MR_zip(MRJob):
OUTPUT_PROTOCOL = mrjob.protocol.JSONProtocol
zip_codes = {int(zip_code): (float(latitude), float(longitude)) for zip_code, latitude, longitude in csv.reader(open("zip_codes.txt", "r"))}
def mapper(self, _, line):
zip_code_1, poi = line.split(",")
zip_code_1 = int(zip_code_1)
lat1, lon1 = self.zip_codes[zip_code_1]
for zip_code_2, (lat2, lon2) in self.zip_codes.items():
d = distance((lat1, lon1), (lat2, lon2))
yield zip_code_2, (zip_code_1, poi, d)
def reducer(self, zip_code_1, ds):
result = {}
for zip_code_2, poi, d in ds:
if poi not in result:
result[poi] = (zip_code_2, d)
elif result[poi][1] > d:
result[poi] = (zip_code_2, d)
yield zip_code_1, result
if __name__ == '__main__':
MR_zip.run()
最后,我使用以下命令运行它:
python MR_zip.py -r emr --conf mrjob.conf --file zip_codes.txt < poi.txt
zip_codes.txt的位置如下:
...
62323,39.817702,-90.66923
62324,39.988988,-90.94976
62325,40.034398,-91.16278
62326,40.421857,-90.80333
...
poi.txt看起来像:
...
210,skate park
501,theatre
29001,theatre
8001,knitting club
20101,food bank
...
答案 0 :(得分:3)
此外,您可能会发现有用的MRJob.add_file_option
例程。例如,指定
self.add_file_option('--config-file', dest='config_file',
default=None, help='file with labels', action="append")
您可以通过self.options.config_file
路径列表引用上传的文件。
答案 1 :(得分:1)
<强>概述强>
我的代码中有两个错误:
步骤初始化
每一步都有相应的初始化方法。例如,mapper
具有mapper_init
,可用于初始化映射器中使用的数据。函数reducer
和combiner
具有类似的初始化方法。如果使用steps
函数定义自己的步骤,则还可以定义使用的初始化函数。阅读有关初始化程序here的更多信息。
注意Python版本
截至今天,EMR默认使用Python 2.6.6版。因此,对更高版本的任何依赖都可能在本地运行,但在EMR上存在问题。
修复
要修复上述代码,有必要删除zip_codes
MR_zip.py
的行
zip_codes = {int(zip_code): (float(latitude), float(longitude)) for zip_code, latitude, longitude in csv.reader(open("zip_codes.txt", "r"))}
而是在mapper_init
内定义它,而不使用字典理解。
def mapper_init(self):
self.zip_codes = {}
for zip_code, latitude, longitude in csv.reader(open("zip_codes.txt", "r")):
self.zip_codes[int(zip_code)] = (float(latitude), float(longitude))
其他文件和命令行保持不变。