在Python中达到AWS Lambda内存限制

在Python中达到AWS Lambda内存限制,python,pandas,amazon-web-services,amazon-s3,aws-lambda,Python,Pandas,Amazon Web Services,Amazon S3,Aws Lambda,我正在寻找一些关于这个项目的建议。我的想法是使用Python和Lambda来聚合数据并响应网站。主要参数是日期范围,可以是动态的 项目要求: 从存储在JSON中的月报文件读取数据(每个文件包含大约3000个证券,大小为1.6MB) 将数据聚合到不同的存储桶中,显示每个存储桶的计数和回报(出于我们的目的,假设存储桶是可以变化的部门和市值范围) 在网站上显示聚合数据 我面临的问题 我已经在AWS Lambda中成功地实现了这一点,但是在测试20年数据的请求时(是的,我得到了它们),我开始达到AW

我正在寻找一些关于这个项目的建议。我的想法是使用Python和Lambda来聚合数据并响应网站。主要参数是日期范围,可以是动态的

项目要求:

  • 从存储在JSON中的月报文件读取数据(每个文件包含大约3000个证券,大小为1.6MB)
  • 将数据聚合到不同的存储桶中,显示每个存储桶的计数和回报(出于我们的目的,假设存储桶是可以变化的部门和市值范围)
  • 在网站上显示聚合数据
我面临的问题 我已经在AWS Lambda中成功地实现了这一点,但是在测试20年数据的请求时(是的,我得到了它们),我开始达到AWS Lambda中的内存限制

我使用的流程: 所有文件都存储在S3中,因此我使用boto3库获取文件,并将其读入内存。这仍然很小,没有任何实际意义

我使用
json.loads
将文件转换为数据帧。我正在将所有文件加载到一个大数据框中。-这就是内存不足的地方

然后,我使用
groupby
将数据帧传递给自定义聚合以获得结果。这部分并没有我想要的那么快,但却能满足我的需要

最终结果数据帧,然后转换回JSON,小于500 MB

当它在lambda外部本地工作时,整个过程大约为40秒。
我尝试过用线程运行这个程序,并一次处理单个帧,但性能下降到1分30秒左右

虽然我不愿意放弃一切重新开始,但如果有更有效的方法来处理这件事,我愿意这样做。旧流程在node.js中完成了所有工作,而不使用lambda,并且花了近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

不幸的是,没有办法绕过3GB的Lambda内存限制,特别是如果您使用的是
pandas
,这是一个内存巨人。一个解决方法是,您在某个地方有一个EC2实例,您可以使用
ssm
在EC2实例上使用Lambda触发器代码。我们确实无法根据一般描述优化您的代码。首先,我认为我们需要您的先决条件。您可以检查应用程序需要多少内存吗?根据具体情况,您应该能够增加lambda所需的内存,或者只在适当的实例上部署代码,并使用VPC端点通过lambda调用运行代码。感谢您对EC2的考虑,我可能能够做到这一点,但不确定我的公司在使用方面有何限制@Alex,这是一个理论问题,不是代码优化问题。对不起,如果不清楚的话。我的意思是,也许你的计算可以在不同时保存所有数据的情况下完成。您是否可以使用数据库进行聚合?