Я neet в AWS Lambda, и я пишу функцию, которая должна иметь возможность анализировать многострочный CSV и писать его как однострочный CSV. Лямбда-скрипт запускается после сдачи файла S3.
Я уже написал скрипт, и он корректно работал с тестовыми файлами (некоторые КБ).
import boto3
import botocore
import csv
import os
import sys
import datetime
import uuid
field_number = 29
s3_client = boto3.client('s3')
def lambda_handler(event, context):
start=datetime.datetime.now()
for record in event['Records']:
# get the event time
event_time = record['eventTime']
# get the event name (e.g. filePUT, ...)
event_name = record['eventName']
# get the principal_id (i.e. the user who performed the action)
principal_id = record['userIdentity']['principalId']
# get the name of the bucket on which event is performed
bucket_name = record['s3']['bucket']['name']
# get the name of the object affected by the action
object_name = record['s3']['object']['key']
destination_path='test_multiline/'+object_name.split("/")[len(object_name.split("/"))-1]
# get the file from S3
try:
response = s3_client.get_object(Bucket=bucket_name,Key=object_name)
print('object correctly read from S3')
except:
print('Error in reading file from S3')
file_content = response['Body'].read().decode('utf-8')
file_content = file_content.replace('""','')
file_content = file_content.replace(',\n',',""\n')
while(',,' in file_content):
file_content = file_content.replace(',,',',"",')
# get the elements of the file separated by comma
file_content_csv = csv.reader(file_content,delimiter=",")
list=[]
csv_line=""
index=0
row_num=0
for element in file_content_csv:
# if this condition is met, it means a new row is just started
if len(element)==0:
csv_line = ""
index = 0
else:
# if this condition is met, it means that this is an element of
# the csv (not a comma)
if(len(element)==1):
# check if this is the last element of the row
if(index==field_number-1):
csv_line = csv_line +""+ str(element[0].replace(',',''))
csv_line = csv_line.replace('\n',' ')
list.append(csv_line)
row_num = row_num+1
else:
csv_line = csv_line +""+ str(element[0].replace(',',''))+","
csv_line = csv_line.replace('\n',' ')
index = index + 1
try:
with open("/tmp/local_output.csv", "w+") as outfile:
for entries in list:
outfile.write(entries)
outfile.write("\n")
print('/tmp/local_output.csv correctly written to local')
outfile.close()
except IOError:
print('Error in writing file in local')
# upload the new file to S3
try:
s3_client.upload_file('/tmp/local_output.csv', 'multiline', destination_path)
print('test_multiline/s3_output.csv correctly written to S3')
except:
print('Error in writing file to S3')
# get time lamdba function stop
stop=datetime.datetime.now()
Как только что было сказано, скрипт корректно работает с файлом в несколько килобайт.
Тем не менее, мой файл в работе составляет около 800 МБ, и когда я загружаю его на S3, я получил эту ошибку:
REPORT RequestId: e8c6103f-1287-11e9-a1cf-8fcf787319ca Duration: 9117.51 ms Billed Duration: 9200 ms Memory Size: 3008 MB Max Memory Used: 3008 MB
Как вы можете видеть, я уже увеличил MaxMemory до 3008 МБ, а время выполнения до 900 с (максимальное).
Затем я попытался разделить файл размером 800 МБ на 8 фрагментов по 100 МБ каждый. Когда я пытаюсь загрузить на S3 8 файлов, вычисления для первого файла работают хорошо, но начиная со второго, я выделил проблему, выделенную выше.
Можете ли вы помочь мне решить эту проблему? Я думал, что разделение файла на более мелкие порции решило бы проблему.