아이고, AWS Lambda의 프로세서는 SQL이죠

17243 단어 AWSSQLLambdatech

개시하다


현재 AWS Lambda는 SQL 설명 프로세서를 사용할 수 있습니다.
AWS Lambda의 콘솔에 이러한 SQL이 기술되어 있다고 가정합니다.

실행하면 그렇습니다.

SQL 결과가 출력됩니다.

설명


처음 조회를 확인해 보세요.
index.sql
SELECT 'Hello World' body, 200 statusCode;
이 질의를 AWS Lambda 프로세서로 설정하면 AWS Lambda는 다음 JSON 문자열을 출력합니다.
output
{
  "body": "Hello World",
  "statusCode": 200
}
SELECT 키 및 가치 구조를 사용하여 JSON 문자열을 내보냅니다.
JSON 형식으로 답장하면 이벤트 소스에 API Gateway를 설정하면 간단한 WEB API를 만들 수 있다고 해도 과언이 아니다.
이로써'SQL은 쓸 수 있으나 프로그래밍 언어는 사용할 수 없다'는 사람도 간단한 람바다 함수를 만들 수 있어 요구의 난이도를 하나 더 낮췄다.
한편 이 기사는 4월 1일 기고한 것으로, 실제로 AWS 람다에는 SQL로 프로세서를 기술하는 기능이 존재하지 않는다.......

이런 만우절 멘트를 투고하고 싶어요.


지난해 2021년 만우절 단락에서'시대에 순응하는 MysQ 레이의 새로운 기능: PLEASE 문장'이라는 블로그를 배독했습니다.
https://sakaik.hateblo.jp/entry/20210401/mysql_please_clause_in_aprilfool
당시에 저는 상술한 블로그에 매우 흥미를 느꼈고 개인 블로그에 비슷한 내용을 투고하고 싶었지만 여러 가지 이유로 개인 블로그가 개방되지 않았기 때문에 실현하지 못했습니다.
따라서 정보공유 커뮤니티 젠에 투고하는 것에 대해 논의했지만 사용 약관에 위조 불허라고 기재했다.당연하다

제 4 조 (금지사항)


사용자는 본 서비스를 사용할 때 다음과 같은 행위를 할 수 없습니다.
10. 다른 사용자와 제3자를 기만하는 허위 내용을 기재하는 행위
그럼, 이 기사를 어떻게 투고할까요?
답은 간단하다.가짜가 아니면 돼.그냥 솔직하게 거짓말을 했죠.
따라서 모든 사람이 성실할 수 있도록 SQL로 프로세스를 기술하는 메커니즘을 마련했습니다.

실제 제작


토론 사항


실현하기 위해 다음과 같은 항목을 연구하였다.
  • AWS Lambda에서 임의의 환경 사용
  • 외부 RDBMS 서버가 필요 없는 SQL
  • 설치
  • SQL에서 AWS Lambda의 이벤트를 획득한 구조
  • AWS Lambda에서 임의의 환경 사용


    이번 목적은 AWS Lambda의 프로세서를 SQL로 기술하는 것이다
    원래 AWS 람보는 코드만 준비하면 무의식적으로 백엔드를 만들 수 있는 AWS 서비스다.기본적인 사용 방법을 사용하려면 AWS가 제공하는 실행 시간 (언어와 버전) 을 선택하고 그 기록 코드에 따라 사용해야 한다.
    그렇다면 AWS Lambda는 AWS가 준비한 언어와 버전만 사용할 수 있습니까🤔
    그런 일 없습니다.
    AWS Lambda는 환경에 상관없이 두 가지 메커니즘을 사용합니다.
  • 맞춤형 실행 시간 모드
  • Docker 이미지 활용 모드

  • 후자 Docker 이미지를 사용하는 모드는 AWS에서 제공하지 않은 언어를 사용할 때 우선적으로 고려해야 할 일반적인 선택입니다.
    그러나 "Docker 이미지를 사용하고 AWS Lambda로 SQL을 이동했다!"이런 기사를 기고했는데 열람자가 뭐가 재미있겠어요."그건 그냥 람바다부터 SQL을 실행하는 거죠?"이렇게 토로하면 끝이죠.
    물론 실용적인 기사로는 가치가 있지만, 이번에는 실용성이 아닌 독특성을 추구해 규칙을 설정하기로 했다.
    !
    규칙: 관리 콘솔을 통해 코드 편집 가능
    네, 그렇습니다.
    Docker 이미지로 움직이는 AWS Lambda는 관리 콘솔에서 코드를 볼 수 없어 SQL로 프로세서를 쓰는 것처럼 보이지 않는다.
    SQL만 움직이는 것처럼 보이기 위해 이번에는 사용자 정의 운행 시간을 사용하기로 했다.

    사용자 정의 런타임 사용


    그러면 사용자 정의 실행 시간을 사용하기로 결정했지만 사용자 정의 실행 시간을 사용하려면 먼저 사용자 정의 실행 시간 API를 설치해야 한다.
    런타임 API는 다음 작업으로 구성된 AWS Lambda 호출 프로세서의 구조입니다.
  • 초기화 작업
  • 설정 가져오기
  • 함수의 초기화
  • 초기화 오류 처리
  • 작업 처리
  • 수령 이벤트
  • 추적 헤더의 전파
  • 컨텍스트 객체 작성
  • 함수 처리 프로그램의 호출
  • 응답 처리
  • 호출 오류 처리
  • 정리
  • 사용자 정의 실행 시간을 사용하려면 실행 가능한 파일을 임의로 준비해야 합니다.
    구체적으로 말하면 이런 실현이다.
    sequenceDiagram
        autonumber
        
        rect rgb(191, 223, 255)
            Note over AWS Lambda,自分が実装する部分: 初期化タスク
            AWS Lambda->>+自分が実装する部分: Init
            自分が実装する部分->>自分が実装する部分: 初期化処理
            自分が実装する部分->>自分が実装する部分: 関数の初期化
            opt エラー発生
                自分が実装する部分->>AWS Lambda: 初期化エラーハンドリング
            end
        end
        rect rgb(224, 247, 250)
            Note over AWS Lambda,自分が実装する部分: 処理タスク
            loop
                自分が実装する部分->>+AWS Lambda: イベントの取得
                AWS Lambda-->>-自分が実装する部分: event
                自分が実装する部分->>自分が実装する部分: トレースヘッダーの伝播
                自分が実装する部分->>自分が実装する部分: コンテキストオブジェクトの作成
                自分が実装する部分->>自分が実装する部分: 関数ハンドラの呼び出し
                opt エラー発生
                    自分が実装する部分->>AWS Lambda: 呼び出しエラーハンドリング
                end
                自分が実装する部分->>+AWS Lambda: レスポンスの処理
            end
            自分が実装する部分->>自分が実装する部分: クリーンアップ
            自分が実装する部分-->>-AWS Lambda: Shutdown
        end

    これらを実装していくと分かりますが少々手間がかかります。
    この手間を解消するため、ランタイムAPIを実装しやすくするフレームワークaws-lambda-custom-runtime-kitを作成しました。aws-lambda-custom-runtime-kitを使うとGo言語で簡単にカスタムランタイムが実装できるようになります。

    使い方は簡単で、次のインターフェースを満たす構造体を作成してaws-lambda-custom-runtime-kitの提供するエントリーポイントへ渡すだけです。

    type AWSLambdaRuntime interface {
    	Setup(env *AWSLambdaRuntimeEnvironemnt) error
    	Invoke(event []byte, context *Context) (interface{}, error)
    	Cleanup(env *AWSLambdaRuntimeEnvironemnt)
    }
    
    aws-lambda-custom-runtime-kit는 이런 구조입니다.Custom runtime kit 오른쪽은 실장 인원이 책임지는 구역이다.
    sequenceDiagram
        autonumber
        participant AWS Lambda
        participant Custom runtime kit
        actor Your runtime
        AWS Lambda->>+Custom runtime kit: Init
        Custom runtime kit->>+Your runtime: Setup()
        Your runtime-->>-Custom runtime kit: error
        opt return error
            Custom runtime kit->>AWS Lambda: Initilize error
        end
        loop
            Custom runtime kit->>+AWS Lambda: Get an event
            AWS Lambda-->>-Custom runtime kit: event
            Custom runtime kit->>+Your runtime: Invoke()
            Your runtime->>+Any: any logic
            Any-->>-Your runtime: result
            Your runtime-->>-Custom runtime kit: result, error
            opt return error
                Custom runtime kit->>AWS Lambda: Invoke error
            end
            Custom runtime kit->>+AWS Lambda: send result
        end
        Custom runtime kit->>Your runtime: Cleanup()
        Custom runtime kit-->>-AWS Lambda: Shutdown

    ランタイムAPIを実装するのに必要な処理がグっと減ったのが分かりますね。

    なお、aws-lambda-custom-runtime-kitはGitHubにて公開していますので、ご覧になっている方もこちらを使ってクレイジーなカスタムランタイムを是非実装してみてください。

    https://github.com/WinterYukky/aws-lambda-custom-runtime-kit

    외부 RDBMS 서버가 필요 없는 SQL 설치

    次にSQLを解釈する方法です。
    はっきり言ってジョーク記事のためにオレオレパーサーは作りたくなかったのでSQLiteを採用し、素直にmattnさんのgo-sqlite3を利用することにしました。

    https://github.com/mattn/go-sqlite3

    先ほど紹介したaws-lambda-custom-runtime-kit上で構築すると次のようなアーキテクチャになります。

    sequenceDiagram
        autonumber
        participant AWS Lambda
        participant Custom runtime kit
        actor SQL runtime
        AWS Lambda->>+Custom runtime kit: Init
        Custom runtime kit->>+SQL runtime: Setup()
        SQL runtime->>SQL runtime: SQLファイルを読み取る
        SQL runtime-->>-Custom runtime kit: error
        opt return error
            Custom runtime kit->>AWS Lambda: Initilize error
        end
        loop
            Custom runtime kit->>+AWS Lambda: Get an event
            AWS Lambda-->>-Custom runtime kit: event
            Custom runtime kit->>+SQL runtime: Invoke()
            SQL runtime->>+sqlite3: query
            sqlite3-->>-SQL runtime: result
            SQL runtime-->>-Custom runtime kit: result, error
            opt return error
                Custom runtime kit->>AWS Lambda: Invoke error
            end
            Custom runtime kit->>+AWS Lambda: send result
        end
        Custom runtime kit->>SQL runtime: Cleanup()
        Custom runtime kit-->>-AWS Lambda: Shutdown

    SQL에서 AWS Lambda의 Event 패브릭 가져오기

    最後にEventを取得する仕組みです。
    これがなければ実行時における動的なインプットがなく、常に同じ結果を返すことになってしまい実用性がありません。
    実用性は求めないと記述した気がしますが気のせいです。

    では、どうするか。
    他にも案はありましたが、今回はSQLiteのUDFで実装することにしました。

    UDFはUser-Defined Functionの略称で、SQLiteに限らず様々なRDBMSで実装されている『ユーザーがプログラミング言語で定義した任意の関数をSQLで使用する』機能です。go-sqlite3では次のように記述できます。

    // 関数を定義
    eventUDF := func(path string) string {
      if path == "" {
        return string(event)
      }
      value := gjson.Get(string(event), path)
      return value.String()
    }
    
    // 関数を登録
    sql.Register(driverName, &sqlite3.SQLiteDriver{
      ConnectHook: func(conn *sqlite3.SQLiteConn) error {
        if err := conn.RegisterFunc("event", eventUDF, false); err != nil {
          return err
        }
        return nil
      },
    })
    
    이번에 gjson를 이용하여 event 함수로 교부된 JSON 키의 값을 얻었다.
    https://github.com/tidwall/gjson
    SQL에서 Event까지 활용할 수 있는 방법을 살펴보겠습니다.
    예컨대 SQL 람다에는 소풍 때 챙길 수 있는 간식을 확인하는 API가 설치됐다.
    Lambda 프로세서에 등록된 SQL
    SELECT
      CASE
        WHEN
          event('おやつ') = 'バナナ' THEN 400
        ELSE 200
      END statusCode,
      CASE
        WHEN
          event('おやつ') = 'バナナ' THEN 'バナナを持ってきた人は遠足に連れていきません'
        ELSE '300円までならOKです'
      END body;
    
    다음 이벤트를 위 프로세서에 맡기면
    소풍 간식.json
    { 
      "おやつ": "バナナ"
    }
    
    이렇게 하면 이벤트 정보를 이용한 분기 처리를 확인할 수 있다.
    호응하다
    {
      "statusCode": 400,
      "body": "バナナを持ってきた人は遠足に連れていきません"
    }
    

    완성


    마지막으로 여기에 소개된 코드를 만들어 람바다 층으로 등록한다
    완성🎉

    소스는 여기서 공개한다.최신 버전에서 구축된 바이너리 정보를 얻을 수 있으므로 SQL로 AWS Lambda를 이동하려는 사람은 사용하십시오.안전성은 전혀 고려하지 않았으니 절대 게임 이외의 곳에서 사용하지 마세요.
    https://github.com/WinterYukky/aws-lambda-sql-runtime

    최후


    이번 실행시간 API를 통해 AWS Lambda에 대해 배웠습니다.
    예를 들면 Node입니다.js 실행 시간을 사용할 때, 초기화 처리는 프로세서 이외에서 실행하는 것을 권장하지만, 구체적으로는 초기화 작업에서 require() 프로세서 원본을 가져오고, 프로세서의 함수를 호출하면 이벤트의 대기열을 계속 반복하기 때문이라고 상상할 수 있다.
    다시 한 번 말씀드리지만, 여러분은 미친 듯이 점심시간을 정해 주십시오.클라우드 포메이션 기술로 움직이면 재밌을 거야.
    https://github.com/WinterYukky/aws-lambda-custom-runtime-kit
    참고 자료
    https://sakaik.hateblo.jp/entry/20210401/mysql_please_clause_in_aprilfool
    https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/runtimes-custom.html

    좋은 웹페이지 즐겨찾기