首页  >  文章  >  后端开发  >  使用 EFS 在 AWS Lambda 上安装 Python 依赖项

使用 EFS 在 AWS Lambda 上安装 Python 依赖项

Mary-Kate Olsen
Mary-Kate Olsen原创
2024-11-24 21:21:12821浏览

Installing Python Dependencies on AWS Lambda Using EFS

使用 AWS Lambda 时,开发人员面临的常见挑战之一是管理大型 Python 依赖项。 PandasShapelyGeoPandas 等库对于地理空间分析等任务至关重要,通常会超过 Lambda 的 250 MB 解压层限制。一个实用的解决方案?将您的依赖项存储在 EFS(弹性文件系统) 上并将其挂载到您的 Lambda 函数。

在这篇文章中,我们将逐步介绍其设置过程,包括先决条件、主要优势和分步实施。


先决条件

这篇文章面向具有高级 AWS 经验的用户。它假设您对 Lambda、EFS、VPC 和安全组等 AWS 服务有深入的了解,并且熟悉管理基础设施和在云中部署可扩展的解决方案。
在我们深入设置之前,请确保您具备以下条件:

  1. AWS Lambda 函数:您将使用 EFS 配置的已部署 Lambda 函数。
  2. EFS 文件系统:在同一 AWS 区域中创建的弹性文件系统。
  3. EFS 访问点:在同一 AWS 区域中创建的 EFS 访问点,根目录路径为 /data ,确保正确设置 POSIX 权限和目录创建权限,如下所示,1101 和 1001,次要组ID 1002 和权限 0755。
  4. VPC 和网络:确保 Lambda 函数与 EFS 位于同一 VPC 中,并正确配置子网和安全组。
  5. IAM 权限:您的 Lambda 函数需要访问 EFS 的权限。附加适当的策略(例如,elasticfilesystem:ClientMount、elasticfilesystem:ClientWrite)。

用于安装软件包的处理程序代码

处理程序直接在挂载到 AWS Lambda 函数的 Amazon EFS 存储上安装 Python 依赖项。这种方法绕过了 Lambda 层的大小限制,使其适用于地理空间数据处理通常需要的重依赖项,例如 pandas、geopandas 和 shapely。它确保 /mnt/data 目录中提供所需的库,供 Lambda 在执行期间使用:

import os
import subprocess

PACKAGE_DIR = "/mnt/data/lib/{}/site-packages/"

def get_python_version_tag():
    """Generates a Python version tag like 'python3.11'."""
    return f"python{os.sys.version_info.major}.{os.sys.version_info.minor}"

def install_package(package):
    """Installs a Python package into the EFS-mounted directory."""
    target_dir = PACKAGE_DIR.format(get_python_version_tag())
    os.makedirs(target_dir, exist_ok=True)
    try:
        subprocess.run(
            [
                "pip",
                "install",
                package,
                "--target",
                target_dir,
                "--upgrade",
                "--no-cache-dir",
            ],
            check=True,
        )
        print(f"Package {package} installed successfully!")
    except subprocess.CalledProcessError as e:
        print(f"Failed to install package {package}: {e}")

def handler(event, context):
    """AWS Lambda Handler for installing packages."""
    try:
        # List of packages to install from the event input
        packages = event.get("packages", [])
        for package in packages:
            install_package(package)
        #optional for see packages installed
        #os.system(f"ls -la {PACKAGE_DIR.format(get_python_version_tag())}")
        return {"statusCode": 200, "body": "Packages installed successfully!"}
    except Exception as e:
        print(f"Error: {e}")
        return {"statusCode": 500, "body": f"An error occurred: {e}"}

测试步骤

调用 Lambda 函数时,传递以下 JSON 负载:

{
    "packages": ["requests", "pandas"]
}

验证软件包安装

使用 SSH 会话或 AWS CLI 导航到您的 EFS 挂载点(例如 /mnt/data/lib/)。
检查 site-packages/ 目录下已安装的软件包。
或者简单地使用 a 查看已安装的软件包

import os
import subprocess

PACKAGE_DIR = "/mnt/data/lib/{}/site-packages/"

def get_python_version_tag():
    """Generates a Python version tag like 'python3.11'."""
    return f"python{os.sys.version_info.major}.{os.sys.version_info.minor}"

def install_package(package):
    """Installs a Python package into the EFS-mounted directory."""
    target_dir = PACKAGE_DIR.format(get_python_version_tag())
    os.makedirs(target_dir, exist_ok=True)
    try:
        subprocess.run(
            [
                "pip",
                "install",
                package,
                "--target",
                target_dir,
                "--upgrade",
                "--no-cache-dir",
            ],
            check=True,
        )
        print(f"Package {package} installed successfully!")
    except subprocess.CalledProcessError as e:
        print(f"Failed to install package {package}: {e}")

def handler(event, context):
    """AWS Lambda Handler for installing packages."""
    try:
        # List of packages to install from the event input
        packages = event.get("packages", [])
        for package in packages:
            install_package(package)
        #optional for see packages installed
        #os.system(f"ls -la {PACKAGE_DIR.format(get_python_version_tag())}")
        return {"statusCode": 200, "body": "Packages installed successfully!"}
    except Exception as e:
        print(f"Error: {e}")
        return {"statusCode": 500, "body": f"An error occurred: {e}"}

最终使用 Lambda 中安装的依赖项

更新 Lambda 函数的处理程序以包含安装在 EFS 上的依赖项,这里的关键是将 efs 中的依赖项路径挂载到 lambda 处理程序的 PYTHONPATH:

重要提示

所有希望使用已安装依赖项的 Lambda 函数都必须将 EFS 附加到 Lambda。如果没有此附件,Lambda 将无法访问 EFS 上存储的所需依赖项。

{
    "packages": ["requests", "pandas"]
}

主要优点

虽然直接在 EFS 中安装 Python 依赖项并不常见,但在 Lambda 的默认限制(例如 250 MB 解压缩层大小)受到限制的情况下,它提供了某些优势。这种方法对于需要使用诸如 PandasShapelyGeoPandas 等繁重库进行地理空间计算的应用程序特别有用,这些库通常超出层大小限制。

使用 EFS 进行依赖项的好处:

  • 绕过 Lambda 层大小限制:安装和使用库,无需担心打包限制。
  • 启用大规模地理空间处理:在无服务器环境中处理复杂的空间计算。
  • 简化依赖关系管理:动态添加或更新库,无需重新部署 Lambda 函数。

该解决方案非常适合高级数据处理任务,例如地理空间分析,还可以根据需要轻松扩展存储,同时保持无服务器架构的灵活性。

以上是使用 EFS 在 AWS Lambda 上安装 Python 依赖项的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn