Как подружить AWS Lambda и PostgreSQL

    С недавних пор в сервисе AWS Lambda появилась нативная поддержка Python 2.7. Для тех, кто не в курсе, что такое AWS Lambda, отсылаю к статье на хабре. Основное преимущество использования сервиса — создание масштабируемой беcсерверной архитектуры. В данной статье я расскажу о способе подружить AWS Lambda и PostgreSQL.

    Основная проблема использования AWS Lambda совместно с кодом на Python возникает из-за того, что окружение, выполняющее код представляет собой короткоживущий instance (виртуальный сервер), в который невозможно доустановить необходимые бинарные компоненты. Более того, использование кода на python требует создания так называемого deployment package. Типичная схема создания такого пакета вкратце такова — в каталог с используемым кодом копируем все содержание $VIRTUAL_ENV/lib/python2.7/site-packages, запаковываем в zip архив, загружаем через AWS консоль или утилиты командной строки в сервис, настраиваем вызов и т.п. Интересующихся отсылаю к документации веб-сервиса, поскольку намерен написать не о детальной настройке, а о конкретной проблеме.

    Если Вы попытаетесь использовать подобную схему работы с sqlalchemy и PostgreSQL, то при попытке вызова кода, использующего запрос к базе, получите примерно следующее:

    START RequestId: 23af180b-7b22-11e5-beac-0b062a6930ba Version: $LATEST
    Unable to import module 'lambda': libpq.so.5: cannot open shared object file: No such file or directory
    
    END RequestId: 23af180b-7b22-11e5-beac-0b062a6930ba
    REPORT RequestId: 23af180b-7b22-11e5-beac-0b062a6930ba	Duration: 0.32 ms	Billed Duration: 100 ms 	Memory Size: 1024 MB	Max Memory Used: 38 MB	
    

    Это происходит из-за того, что psycopg2 — библиотека для работы с PostgreSQL в Python — представляет собой расширение, использующее код на C и shared library libpq.so из состава дистрибутива PostgreSQL.

    Решение в данном случае такое (все действия производились на дистрибутиве Fedora 22):
    1) Качаем исходники PostgreSQL со страницы http://www.postgresql.org/ftp/source

    2) Выполняем команды
    tar xzvf postgresql-9.4.5.tar.gz
    cd postgresql-9.4.5
    ./configure
    make
    

    3) Создаем и активируем virtualenv, которое используем для создания deployment package:
    virtualenv ./env
    source ./env/bin/activate
    

    4) Дальше работаем с репозиторием psycopg2:
    git clone  -b maint_2_6 https://github.com/psycopg/psycopg2
    

    5) Из подкаталога src/interfaces/libpq копируем файл libpq.a в каталог с клонированным дистрибутивом psycopg2. Запускаем сборку:
    cd psycopg2
    python setup.py build_ext -L  ./
    

    Альтернативный вариант -положить libpq.a в каталог /usr/lib64 или иной, определяемый переменной окружения LD_LIBRARY_PATH, и в файле setup.cfg раскомментировать параметр static_libpq=1.
    4) Ставим пакет:
    python setup.py install
    

    Теперь при использовании этого virtualenv для создания deployment package на отсутствие shared library ругани не будет.

    К сожалению, подобный подход никак нельзя назвать универсальным. В частности, мне так и не удалось решить проблему с pillow.См. UPDATE 2

    Буду благодарен, если кто-нибудь из хабражителей выскажет конструктивные мысли по этому поводу.

    UPDATE. Вот альтернативное решение:
    1) При сборке пакета указываем опцию rpath как /var/task/lib:

     python setup.py build_ext -R /var/task/lib
    

    В deployment package создаем подкаталог lib, куда складываем бинарные shared library:
    (env)[random1st@localhost lambda]$ ls lib/
    libpq.so  libpq.so.5  libpq.so.5.7
    


    UPDATE 2. Pip с какой-то версии поддерживает указание опций сборки в requirements.txt. Так что можно и так:
    (env)[random1st@localhost lambda]$ cat requirements.txt |grep option
    Pillow==2.5.1 --global-option="build_ext" --global-option="--rpath=/var/task/lib"
    psycopg2==2.5.3 --global-option="build_ext" --global-option="--rpath=/var/task/lib"
    

    UPDATE 3. В облаке Amazon коннект происходит практически мгновенно, а в течении этого года обещают возможность прикрутить лямбду к вашему VPC.
    UPDATE 4. VPC прикрутили, но ушла возможность коннектится к ресурсам за VPC. Amazon такой Amazon.
    Поделиться публикацией
    Похожие публикации
    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее
    Реклама
    Комментарии 5
    • 0
      Добавил другие варианты. Так куда веселее получается — не надо далеко лезть.
      • –1
        Есть еще проблема — установление соединения с сервером — дорогая операция. А если она будет делаться при каждом вызове лямбды, она может стать «дорогой» в смысле счета от Амазона.
      • 0
        в README рабочий алгоритм как получить рабочий python модуль
        https://github.com/jkehler/awslambda-psycopg2
        • 0
          Это первый вариант, который я использовал. На самом деле мой способ универсальнее и работает для многих пакетов. Статическая линковка прокатывает только для psycopg2, с Pillow такое не прокатит.

        Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.