我使用Python boto模块访问AWS S3文件。 我使用UNLOAD命令从Redshift卸载文件,并自动gzip压缩文件。 Redshift生成一个文件的10个部分。
这是我用来获取文件列表并调用下载功能的代码的一部分:
key_list = bucket.list('folder_on_the_bucket')
pool = ThreadPool(processes=10)
partial_download = partial(download,0)
pool.map(partial_download, key_list)
这是下载功能:
def download(retry_cnt,key):
retry_cnt = retry_cnt
key = key
try:
#make sure that I download only files, not folders
if key.name[-1]=='/' or key.name[-1]=='\\':
pass
else:
log.info("Downloading %s" % local_dir+ntpath.basename(key.name))
key.get_contents_to_filename(local_dir+ntpath.basename(key.name))
if retry_cnt > 0:
#copy all files that needed to be retried to a specific directory (for debugging purposes)
shutil.copyfile(local_dir+ntpath.basename(key.name), 'error_files_folder'+ntpath.basename(key.name))
except:
if retry_cnt < 3:
retry_cnt += 1
log.warning("error downloading file %s, retrying for the %s. time" % (str(key.name),str(retry_cnt)))
log.warning(str(sys.exc_info()[1]))
time.sleep(5)
download(retry_cnt,key)
else:
log.error(sys.exc_info()[1])
sys.exit("Unable to download file")
问题是,有时AWS会返回404错误,该文件不存在。我手动检查了S3存储桶中的文件并且它有数据。 我已经读过,如果变更尚未传播,S3可能会返回此类错误。这就是为什么下载功能看起来像这样的原因。如果文件出现错误,我会尝试再次下载同一个文件。问题是我第二次下载文件时,它是空的,我丢失了一些数据。 (十分之一)。
此问题在不同的存储桶和文件夹中随机出现。
答案 0 :(得分:0)
我设法通过改变下载功能的工作方式来解决它。我从那里删除了try并将其设置在调用它的代码部分周围。
def get_download_files():
global key_list
key_list = bucket.list(s3_full_path)
for f in key_list:
log.info(f)
try:
pool = ThreadPool(processes=10)
pool.map(download, key_list)
except:
log.warning("error occured while downloading")
log.warning(sys.exc_info()[1])
global error_cnt
error_cnt = 1
pass
通过使用此功能,我可以确保如果任何文件因任何原因无法下载,我会将error_cnt设置为1表示存在问题。之后,我有一个功能,重新下载整个文件夹三次,然后抛出系统错误和整个过程失败。