Lambda 함수에서 Embulk 명령을 실행해보십시오.

소개



이 기사는 BeeX Advent Calendar 2020 의 12/16 기사입니다.

==

이전 기사에서 Lambda의 컨테이너 이미지에서 실행을 시도했습니다.
  • Lambda 함수를 컨테이너 이미지로 움직여 보았습니다.

  • 이번에는 그 외에도 최근 자주 사용하는 Embulk 명령을 사용할 수 없는지 시도해 보았습니다.

    환경



    PC: Windows 10
    Docker: Docker version 19.03.13, build 4484c46d9d

    전제


  • Docker 초기 설정 완료
  • Python3이 설치되었습니다 (Lambda 런타임과 동일하거나 그 이상)
  • AWS 계정이 생성되었습니다
  • Amazon ECR 리포지토리가 생성됨

  • 실제 조작



    lambda function 만들기



    @ Shiro 01 님의 기사를 참고하여 Lambda Function을 만듭니다.
    이번에는 Embulk 실행 확인이므로 간단히 도움말 명령을 실행해 보겠습니다.

    lambda_function.py
    import subprocess
    
    def lambda_handler(event, context):
        cmd = ['/usr/bin/embulk','help']
        out = subprocess.run(cmd,shell=True , stdout=subprocess.PIPE)
        print(out.stdout.decode())
    

    하나의 주의점으로서 subprocess.run의 인수에 "shell=True"를 추가하고 있습니다.
    이것을 추가하지 않으면 OSError가 발생합니다.

    참고


  • AWS Lambda의 Python에서 Linux 명령 실행
  • subprocess 서브 프로세스 관리

  • Dockerfile 만들기



    그런 다음 Dockerfile을 만듭니다.
    Embulk는 미리 설치하고 실행 파일을 생성합니다.
    Dockerfile의 COPY에서 Embulk 및 lambda_function을 컨테이너에 복사합니다.
    FROM amazon/aws-lambda-python:3.7
    
    COPY lambda_function.py ./
    COPY embulk /usr/bin
    
    RUN chmod +x /usr/bin/embulk
    
    CMD [ "lambda_function.lambda_handler" ]
    

    이미지 빌드



    다음 명령으로 이미지를 빌드합니다.
    $ cd [DockerFile格納先DIR]
    $ docker build -t lambda_embulk .
    

    이미지가 생성됩니다.
    $ docker images
    REPOSITORY    TAG       IMAGE ID       CREATED              SIZE
    lambda_embulk latest    472005da7cf7   About a minute ago   980MB
    

    로컬 테스트



    다음 명령으로 로컬에서 Lambda를 실행할 수 있습니다.
    $ docker run -p 9000:8080 lambda_embulk:latest
    time="2020-12-15T06:11:57.95" level=info msg="exec '/var/runtime/bootstrap' (cwd=/var/task, handler=)"
    

    다른 창을 열고 다음 명령을 실행합니다.
    curl 명령의 응답으로 null이 반환됩니다.
    $ curl -XPOST "http://localhost:9000/2015-03-31/functions/function/invocations" -d '{}'
    null
    

    컨테이너를 실행하는 창을 확인하면 실행된 결과가 콘솔에 표시됩니다.
    "embulk help"명령이 실행 중이므로 로컬 테스트가 문제가 될 것 같습니다.
    $ docker run -p 9000:8080 lambda_embulk:latest
    time="2020-12-15T06:13:53.604" level=info msg="exec '/var/runtime/bootstrap' (cwd=/var/task, handler=)"
    START RequestId: 0ed577b3-6a07-447a-bccb-c03d255c0201 Version: $LATEST
    time="2020-12-15T06:13:57.601" level=info msg="extensionsDisabledByLayer(/opt/disable-extensions-jwigqn8j) -> stat /opt/disable-extensions-jwigqn8j: no such file or directory"
    time="2020-12-15T06:13:57.601" level=warning msg="Cannot list external agents" error="open /opt/extensions: no such file or directory"
    Embulk v0.9.23
    Usage: embulk [-vm-options] <command> [--options]
    Commands:
       mkbundle   <directory>                             # create a new plugin bundle environment.
       bundle     [directory]                             # update a plugin bundle environment.
       run        <config.yml>                            # run a bulk load transaction.
       cleanup    <config.yml>                            # cleanup resume state.
       preview    <config.yml>                            # dry-run the bulk load without output and show preview.
       guess      <partial-config.yml> -o <output.yml>    # guess missing parameters to create a complete configuration file.
       gem        <install | list | help>                 # install a plugin or show installed plugins.
       new        <category> <name>                       # generates new plugin template
       migrate    <path>                                  # modify plugin code to use the latest Embulk plugin API
       example    [path]                                  # creates an example config file and csv file to try embulk.
       selfupdate [version]                               # upgrades embulk to the latest released version or to the specified version.
    
    VM options:
       -E...                            Run an external script to configure environment variables in JVM
                                        (Operations not just setting envs are not recommended nor guaranteed.
                                         Expect side effects by running your external script at your own risk.)
       -J-O                             Disable JVM optimizations to speed up startup time (enabled by default if command is 'run')
       -J+O                             Enable JVM optimizations to speed up throughput
       -J...                            Set JVM options (use -J-help to see available options)
       -R--dev                          Set JRuby to be in development mode
    
    Use `<command> --help` to see description of the commands.
    
    END RequestId: 0ed577b3-6a07-447a-bccb-c03d255c0201
    REPORT RequestId: 0ed577b3-6a07-447a-bccb-c03d255c0201  Init Duration: 1.03 ms  Duration: 591.61 ms     Billed Duration: 600 mMemory Size: 3008 MB     Max Memory Used: 3008 MB
    

    ECR 리포지토리에 푸시



    AWS 콘솔에서 리포지토리를 생성합니다.


    다음 명령으로 만든 ECR 리포지토리에 이미지를 푸시합니다.
    이쪽은 이전 기사를 거의 동일합니다.
    Embulk가 조금 사이즈가 있기 때문에, 전회보다 Push에 시간이 걸립니다.
    $ docker tag lambda_embulk:latest XXXXXXXXXXXXX.dkr.ecr.ap-northeast-1.amazonaws.com/lambda-embulk
    $ docker images
    REPOSITORY                                                                     TAG       IMAGE ID       CREATED          SIZE
    941996685139.dkr.ecr.ap-northeast-1.amazonaws.com/lambda-embulk                latest    472005da7cf7   11 minutes ago   980MB
    
    $ aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin XXXXXXXXXXXXX.dkr.ecr.ap-northeast-1.amazonaws.com
    Login Succeeded
    
    $ docker push XXXXXXXXXXXXX.dkr.ecr.ap-northeast-1.amazonaws.com/lambda-embulk:latest
    The push refers to repository [XXXXXXXXXXXXX.dkr.ecr.ap-northeast-1.amazonaws.com/lambda-embulk]
    5f70bf18a086: Pushed
    65f9fe7cdd01: Pushed
    1965e83122e7: Pushed
    701bdcbf3b47: Pushed
    6e660533f001: Pushed
    069cd8bd11dd: Pushed
    6e191121f7ea: Pushed
    d6fa53d6caa6: Pushed
    1fb474cee41c: Pushed
    b1754cf6954d: Pushed
    464c816a7003: Pushed
    latest: digest: sha256:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX size: 2624
    

    무사히 업로드할 수 있었습니다.


    Lambda 작성 및 실행



    AWS 콘솔에서 Lambda 함수를 생성합니다.


    Lambda 함수가 생성되었습니다.


    실행 결과 확인



    timeout에서 오류가 발생했습니다.


    Lambda의 기본 설정에서 타임아웃 값이 3초가 되었으므로, 우선 3분으로 변경합니다.


    조금 시간이 걸렸지만 정상적으로 종료되었습니다.
    출력 내용을 보는 한 Embulk의 help 명령도 실행되고있는 것 같습니다.


    사이고에게



    이것이 좋은지 여부를 제외하고 무사히 Lambda에서 Embulk를 실행할 수있었습니다.
    어쩌면 실제 운용한다면 Lambda의 스펙이라든지 diff 파일 어디에서 보관 유지하는지 여러가지 검토해야 할 일이 있습니다만, 우선 s3에 두고 거기로부터 소규모의 처리를 움직이면 괜찮을까요? 모르겠지만.

    단지 Embulk의 처리는 Lambda의 실행 시간에 들어가는 것 별로 없기 때문에, 그 주변은 어려운 곳일지도 모릅니다.

    좋은 웹페이지 즐겨찾기