我正在寻找关于这个项目的一些建议。我的想法是使用Python和Lambda来聚合数据并响应网站。主要参数是日期范围,可以是动态的。
项目要求:
问题我面对 我已经在AWS Lambda中成功实现了这一点,但是在测试20年数据的请求时(是的,我得到它们),我开始在AWS Lambda中达到内存限制。
我使用的流程: 所有文件都存储在S3中,因此我使用boto3库来获取文件,将它们读入内存。这仍然很小,没有任何实际意义。
我使用json.loads
将文件转换为pandas数据帧。我正在将所有文件加载到一个大型数据框中。 - 这是内存耗尽的地方。
然后,我使用groupby
将数据框传递给自定义聚合,以获得我的结果。这部分并不像我想的那么快,但是能够得到我需要的东西。
最终结果数据帧然后转换回JSON并且小于500 MB。
当它在lambda外部工作时的整个过程大约是40秒 我尝试用线程运行它并同时处理单个帧但性能降低到大约1分30秒。
虽然我宁愿不废弃一切并重新开始,但如果有更有效的方法来解决这个问题,我愿意这样做。旧进程在没有使用lambda的情况下完成了node.js中的所有内容,并且花了将近3分钟来生成。
目前使用的代码 我不得不清理这一点以取出一些项目,但这里是使用的代码。 将数据从S3读入JSON,这将产生一个字符串数据列表。
while not q.empty():
fkey = q.get()
try:
obj = self.s3.Object(bucket_name=bucket,key=fkey[1])
json_data = obj.get()['Body'].read().decode('utf-8')
results[fkey[1]] = json_data
except Exception as e:
results[fkey[1]] = str(e)
q.task_done()
循环访问JSON文件以构建工作的数据框
for k,v in s3Data.items():
lstdf.append(buildDataframefromJson(k,v))
def buildDataframefromJson(key, json_data):
tmpdf = pd.DataFrame(columns=['ticker','totalReturn','isExcluded','marketCapStartUsd',
'category','marketCapBand','peGreaterThanMarket', 'Month','epsUsd']
)
#Read the json into a dataframe
tmpdf = pd.read_json(json_data,
dtype={
'ticker':str,
'totalReturn':np.float32,
'isExcluded':np.bool,
'marketCapStartUsd':np.float32,
'category':str,
'marketCapBand':str,
'peGreaterThanMarket':np.bool,
'epsUsd':np.float32
})[['ticker','totalReturn','isExcluded','marketCapStartUsd','category',
'marketCapBand','peGreaterThanMarket','epsUsd']]
dtTmp = datetime.strptime(key.split('/')[3], "%m-%Y")
dtTmp = datetime.strptime(str(dtTmp.year) + '-'+ str(dtTmp.month),'%Y-%m')
tmpdf.insert(0,'Month',dtTmp, allow_duplicates=True)
return tmpdf