아마존 극광: 트리거에서 lambda 호출

11340 단어 triggerawslambda
RDS 데이터베이스가 다른 AWS 서비스와 상호 작용하기를 원할 수도 있습니다.예를 들어 클라우드 관찰 경보에서'끌어당기기'방법이 아니라'밀어넣기'방법을 사용하여 업무나 관리 상황에 대한 통지를 발송한다.데이터베이스 변경 시 이 호출을 터치하도록 설계할 수도 있습니다.Amazon Aurora는 mysql을 호출하여 데이터베이스에서 lambda를 실행할 가능성을 제공합니다.MySQL 트리거의 lambda async()입니다.이것은 흥미로운 특성이지만, 나는 그것의 작업 원리를 이해하는 것이 그것을 정확하게 사용하는 데 매우 중요하다고 생각한다.
이것은 화이트보드나 파워포인트에서 보기에 매우 좋은 기능입니다. DML 이벤트 (예: 업데이트) 는 lambda를 호출하는 트리거를 실행합니다. 이 모든 것은 이벤트 드라이브입니다.그러나 이것도 위험하다. 업데이트할 때마다 이 과정을 실행해야 한다고 확신하십니까?응용 프로그램이 발표하거나 가져오거나 논리적으로 대상을 복제하는 동안 업데이트를 저장합니까?지금 상상해 보세요. 응용 프로그램에 오류가 있습니다. 잘못된 데이터가 설정되어 있습니다. 긴급한 상황에서 생산 데이터베이스에서 복구해야 합니다. 압력 속에서 수동으로 업데이트를 하고 트리거를 모르거나 이런 상황에서 잊어버려야 합니다.너는 이 위험을 무릅쓰고 싶니?그 주요 목적은 일부 외부 서비스를 운행하는 것이기 때문에 그 후의 결과가 매우 뚜렷하고 복구하기 어려울 것이다. 예를 들어 모든 사용자에게 스팸메일을 보내거나 제3층 응용 프로그램에 대한 DDoS 공격을 자기도 모르게 하는 것이다.
DML과 lambda 호출을 명확한 이름과 설명에 봉인하는 것을 강력히 권장합니다.예를 들어, 사용자가 자신의 주소를 업데이트할 때, '당신의 주소가 변경되었습니다' 메시지를 보내는 어리석은 예를 들자.'메시지 보내기' 호출을 업데이트 후 트리거에 두지 마십시오.왜냐하면 의미를 갱신하는 것은 갱신이기 때문이다.메시지를 보내지 마세요.UPDATE ADDRESS () 와 같은 저장 프로세스를 작성해서 업데이트를 하고'send 메시지 'lambda를 호출할 수 있습니다.메시지를 사용하거나 보내지 않으려면 볼 파라미터를 제공할 수도 있습니다.그리고 저장 프로세스를 호출하는 사람은 무슨 일이 일어날지 안다.그 업데이트만 하는 사람은...업데이트만 하면 돼요.실제로 DML을 응용 프로그램에서 직접 실행하는 것은 대개 오류입니다.데이터베이스는 응용 프로그램 체계 구조의 많은 다른 구성 요소와 같이 업무와 관련된 데이터 서비스를 공개해야 한다. 이것이 바로 저장 과정의 목표이다.
Aurora MySQL에서 lambda를 호출하는 테스트를 공유합니다.

데이터베이스를 lambdas에 연결


lambda는 프로그램에 끼워 넣는 간단한 과정이 아닙니다.이 서비스는 액세스를 제어해야 하는 서비스입니다.
  • lambda 만들기(함수 만들기, ARN 배치하기 및 가져오기)
  • 이 lambda를 호출하기 위한 IAM 정책을 정의했습니다
  • 이 정책을 적용할 IAM 역할 정의
  • RDS 클러스터 매개 변수 그룹
  • 에서 이 캐릭터를aws default lambda 캐릭터로 설정합니다.
  • 클러스터에 이 역할 추가(RDS-> 데이터베이스 클러스터-> IAM 역할 관리)
  • 이것은 나의 lambda입니다. 이것은 내가 테스트한 이벤트만 기록합니다.
    
    import json
    
    def lambda_handler(event, context):
        print('Hello.')
        print(event)
        return {
            'statusCode': 200,
            'body': json.dumps('Hello from Lambda!')
        }
    
    

    테스트 데이터베이스 만들기

    
     drop database if exists demo;
     create database demo;
     use demo;
     drop table if exists t;
     create table t ( x int, y int );
     insert into t values ( 1, 1 );
    
    나는 여기에 간단한 표가 하나 있고, 간단한 줄이 하나 있다.
    
    delimiter $$
    create trigger t_bufer before update on t for each row
    begin
     set NEW.y=OLD.x;
     call mysql.lambda_async(
        'arn:aws:lambda:eu-central-1:802756008554:function:log-me',
        concat('{"trigger":"t_bufer","connection":"',connection_id(),'","old": "',OLD.x,'","new":"',NEW.x,'"}'));
    end;
    $$
    delimiter ;
    
    이것은 메시지에서 새 값을 사용하여 업데이트할 때 lambda를 호출하는 트리거입니다.
    
    MYSQL_PS1="Session 1 \R:\m:\s> " mysql -v -A --host=database-1.cluster-ce5fwv4akhjp.eu-central-1.rds.amazonaws.com --port=3306 --user=admin --password=ServerlessV2
    
    첫 번째 세션에 연결합니다. 알림에 시간과 세션을 표시합니다.
    
    Session 1 23:11:55> use demo;
    Database changed
    
    Session 1 23:12:15> truncate table t;
    -------------------
    truncate table t
    -------------------
    
    Query OK, 0 rows affected (0.09 sec)
    
    Session 1 23:12:29> insert into t values ( 1, 1 );
    -------------------
    insert into t values ( 1, 1 )
    -------------------
    
    Query OK, 1 row affected (0.08 sec)
    
    테스트 용례를 다시 실행하고 싶을 때, 이것은 그것을 리셋합니다.
    
    Session 1 23:12:36> start transaction;
    -------------------
    start transaction
    -------------------
    
    Query OK, 0 rows affected (0.07 sec)
    
    Session 1 23:12:48> update t set x = 42;
    -------------------
    update t set x = 42
    -------------------
    
    Query OK, 1 row affected (0.11 sec)
    Rows matched: 1  Changed: 1  Warnings: 0
    
    Session 1 23:12:55> rollback;
    -------------------
    rollback
    -------------------
    
    Query OK, 0 rows affected (0.02 sec)
    
    나는 한 줄을 갱신하고 업무를 되돌렸다.이것은 lambda를 호출하는 것이 관계 데이터베이스의 산성 보호에서 나온다는 것을 알아야 한다는 것을 보여 줍니다.업데이트 과정에서 트리거를 실행합니다. 업무를 제출할지 여부를 알 수 없습니다. (자발적이거나 이상이 발생했기 때문입니다.)데이터베이스에서 다른 테이블에 쓰기 같은 일만 할 때 문제가 없습니다. 왜냐하면 이것은 업무에서 발생하기 때문입니다.트랜잭션이 롤백되면 트리거가 완료한 모든 DML도 롤백됩니다.설령 그것이 발생한다 하더라도, 전체 업무를 제출하기 전에 현재 세션을 제외하고는 아무도 그들의 효과를 보지 못했다.
    단, 동기화 또는 비동기화 방식으로 lambda를 호출할 때, 호출은 실행되고, 작업이 완료되지 않으면, 그 효과는 굴러가지 않습니다.어떤 경우, 실행된 내용이 업데이트의 의도와 관련이 있는 것이지, 업데이트의 완성과 관련이 있는 것이 아니라면, 이것은 가능하다.또는, 이 이상을 lambda에서 관리해야 합니다. 데이터베이스에서 업무가 발생했는지 확인해야 할 수도 있습니다.그러나 이런 상황에서 귀하는 귀하의 구조를 진정으로 의심해야 합니다. (서비스에 대한 호출, 호출자에 대한 호출...)
    그래서...조심해.데이터베이스 작업이 끝났을 때 lambda를 실행하려면 제출한 후에 업무를 수행하는 과정 코드에서 실행해야 할 수도 있습니다.

    또 다른 테스트...


    이런 비산성 집행은 내가 강조하고 싶은 중요한 부분이기 때문에 네가 원한다면 여기에 멈출 수 있다.또 다른 테스트는 Oracle 데이터베이스만 사용하는 사람들에게 재미있을 수도 있습니다.일반적으로 트리거 작업이 트리거를 한 번만 실행할 수 있도록 보장할 수 있는 것은 아무것도 없다.서열화 이상이 발생하고 데이터베이스가 이 조작을 다시 시도할 수 있을 때, 우리는 내부에서 위에서 본 (스크롤) 을 실행할 수 있다.Oracle 데이터베이스에는 선택뿐 아니라 업데이트된 읽기 단계에서도 읽기 차단이 되지 않습니다.술어를 검증하기 위해 많은 줄을 읽어야 할 수도 있고, 소수의 줄만 업데이트해야 할 수도 있으며, 읽은 모든 줄만 잠그고, 업데이트된 줄만 잠그고 싶지 않을 수도 있습니다.수동 작업에서는 트랜잭션 시리얼화를 사용하여 이 작업을 수행하고 MVCC 스냅샷과 현재 업데이트 시간 사이에 수정된 행이 있을 때 다시 시도할 수 있습니다.그러나 성명 차원에서 갑골문은 당신을 위해 이 점을 해냈습니다.
    Aurora MySQL과 PostgreSQL에서는 이러한 상황이 발생하지 않을 것 같습니다. 읽기 잠금이 더욱 공격적이기 때문입니다. 그러나 Oracle에서 업데이트를 다시 시작하는 것과 같은 장면을 테스트하지 않도록 합니다.
    
    Session 1 23:13:00> start transaction;
    -------------------
    start transaction
    -------------------
    
    Query OK, 0 rows affected (0.06 sec)
    
    Session 1 23:13:09> update t set x = x+1;
    -------------------
    update t set x = x+1
    -------------------
    
    Query OK, 1 row affected (0.02 sec)
    Rows matched: 1  Changed: 1  Warnings: 0
    
    Session 1 23:13:16> select * from t;
    -------------------
    select * from t
    -------------------
    
    +------+------+
    | x    | y    |
    +------+------+
    |    2 |    1 |
    +------+------+
    1 row in set (0.01 sec)
    
    Session 1 23:13:24>
    
    
    나는 이미 X치를 증가시키는 거래를 시작했지만, 그 거래는 여전히 진행 중이다.내가 다음에 해야 할 일은 또 다른 부분이다.
    이것은 두 번째 수업이다.
    
    Session 2 23:13:32> use demo;
    
    Database changed
    Session 2 23:13:34>
    Session 2 23:13:35> select * from t;
    -------------------
    select * from t
    -------------------
    
    +------+------+
    | x    | y    |
    +------+------+
    |    1 |    1 |
    +------+------+
    1 row in set (0.01 sec)
    
    물론, 업무 격리 때문에, 제출하지 않은 변경 사항을 볼 수 없습니다.
    
    Session 2 23:13:38> update t set x = x+1 where x > 0;
    -------------------
    update t set x = x+1 where x > 0
    -------------------
    
    이 단계에서 업데이트는 잠긴 줄에 걸립니다.
    이제 첫 수업으로 돌아갑니다.
    
    Session 1 23:13:49>
    Session 1 23:13:50>
    Session 1 23:13:50>
    Session 1 23:13:50> commit;
    -------------------
    commit
    -------------------
    
    Query OK, 0 rows affected (0.02 sec)
    
    나는 방금 이곳에서 나의 변경 사항을 제출했기 때문에 X는 이미 값 2로 증가했다.
    다음은 제 두 번째 세션에서 일어난 일입니다. 첫 번째 세션에서 자물쇠가 풀렸습니다.
    
    Query OK, 1 row affected (11.42 sec)
    Rows matched: 1  Changed: 1  Warnings: 0
    
    Session 2 23:13:58> commit;
    -------------------
    commit
    -------------------
    
    Query OK, 0 rows affected (0.01 sec)
    
    Session 2 23:14:10> select * from t;
    -------------------
    select * from t
    -------------------
    
    +------+------+
    | x    | y    |
    +------+------+
    |    3 |    2 |
    +------+------+
    1 row in set (0.01 sec)
    
    Session 2 23:14:18>
    
    
    이것은 올바른 행위다.select에서 X=1의 값을 보더라도 첫 번째 세션에서 업무를 제출하기 전에 업데이트를 완료할 수 없습니다.이것이 바로 그것이 기다리는 이유이다. X=2의 제출 값을 읽고 그것을 3으로 증가시켰다.
    마지막으로, 이것은 화면 캡처와 텍스트로 나의 lambda가 기록한 내용입니다.
    
    2020-12-13T23:12:55.558+01:00   START RequestId: 39e4e41f-7853-4b11-a12d-4a3147be3fc7 Version: $LATEST  2020/12/13/[$LATEST]25e73c8c6f9e4d168fa29b9ad2ba76d8
    2020-12-13T23:12:55.561+01:00   Hello.  2020/12/13/[$LATEST]25e73c8c6f9e4d168fa29b9ad2ba76d8
    2020-12-13T23:12:55.561+01:00   {'trigger': 't_bufer', 'connection': '124', 'old': '1', 'new': '42'}    2020/12/13/[$LATEST]25e73c8c6f9e4d168fa29b9ad2ba76d8
    2020-12-13T23:12:55.562+01:00   END RequestId: 39e4e41f-7853-4b11-a12d-4a3147be3fc7 2020/12/13/[$LATEST]25e73c8c6f9e4d168fa29b9ad2ba76d8
    2020-12-13T23:12:55.562+01:00   REPORT RequestId: 39e4e41f-7853-4b11-a12d-4a3147be3fc7 Duration: 1.16 ms Billed Duration: 2 ms Memory Size: 128 MB Max Memory Used: 51 MB   2020/12/13/[$LATEST]25e73c8c6f9e4d168fa29b9ad2ba76d8
    2020-12-13T23:13:16.620+01:00   START RequestId: 440128db-d6de-4b2c-aa98-d7bedf12a3d4 Version: $LATEST  2020/12/13/[$LATEST]25e73c8c6f9e4d168fa29b9ad2ba76d8
    2020-12-13T23:13:16.624+01:00   Hello.  2020/12/13/[$LATEST]25e73c8c6f9e4d168fa29b9ad2ba76d8
    2020-12-13T23:13:16.624+01:00   {'trigger': 't_bufer', 'connection': '124', 'old': '1', 'new': '2'} 2020/12/13/[$LATEST]25e73c8c6f9e4d168fa29b9ad2ba76d8
    2020-12-13T23:13:16.624+01:00   END RequestId: 440128db-d6de-4b2c-aa98-d7bedf12a3d4 2020/12/13/[$LATEST]25e73c8c6f9e4d168fa29b9ad2ba76d8
    2020-12-13T23:13:16.624+01:00   REPORT RequestId: 440128db-d6de-4b2c-aa98-d7bedf12a3d4 Duration: 1.24 ms Billed Duration: 2 ms Memory Size: 128 MB Max Memory Used: 51 MB   2020/12/13/[$LATEST]25e73c8c6f9e4d168fa29b9ad2ba76d8
    2020-12-13T23:13:58.156+01:00   START RequestId: c50ceab7-6e75-4e43-b77d-26c1f6347fec Version: $LATEST  2020/12/13/[$LATEST]25e73c8c6f9e4d168fa29b9ad2ba76d8
    2020-12-13T23:13:58.160+01:00   Hello.  2020/12/13/[$LATEST]25e73c8c6f9e4d168fa29b9ad2ba76d8
    2020-12-13T23:13:58.160+01:00   {'trigger': 't_bufer', 'connection': '123', 'old': '2', 'new': '3'} 2020/12/13/[$LATEST]25e73c8c6f9e4d168fa29b9ad2ba76d8
    2020-12-13T23:13:58.160+01:00   END RequestId: c50ceab7-6e75-4e43-b77d-26c1f6347fec 2020/12/13/[$LATEST]25e73c8c6f9e4d168fa29b9ad2ba76d8
    2020-12-13T23:13:58.160+01:00   REPORT RequestId: c50ceab7-6e75-4e43-b77d-26c1f6347fec Duration: 0.91 ms Billed Duration: 1 ms Memory Size: 128 MB Max Memory Used: 51 MB   2020/12/13/[$LATEST]25e73c8c6f9e4d168fa29b9ad2ba76d8
    
    우선, 우리는 23:12:55에 내가 잠시 후에 굴러간 X=1에서 X=42까지의 업데이트를 보았다.이것은 lambda에 대한 호출이 사무적인 것이 아니라는 것을 증명했다.이것은 분명히 들릴 수 있지만, Oracle 데이터베이스에서 온 경우, 고급 대기열을 사용하여 RDBMS 테이블에 대기열을 저장하고 제출자와 같은 업무를 공유할 수 있습니다.
    나의 업데이트는 23:12:48에 발생했지만, 이 호출은 비동기적이기 때문에 로그가 좀 늦게 발생한다는 것을 기억하십시오.
    그리고 제 두 번째 테스트입니다. 저는 23:13:09에 X를 업데이트했습니다. 1부터 2까지 이 업데이트 기록이 23:13:16에 있는 것을 보았습니다. 이것은 업데이트된 후에 비동기적인 이유입니다. 그러나 제출하기 전에 제 세션 로그에 따라 제출은 23:13:50에 발생했습니다.그렇다면, lambda의 실행은 그 업무를 촉발하기를 기다리지 않는다는 것은 의심할 여지가 없다.
    다음은 세션 2의 업데이트입니다. 이 업데이트는 23:13:38에 실행되었지만 23:13:50에 되돌아왔습니다. 첫 번째 세션이 끝날 때까지 기다리고 있기 때문입니다.23:13:58의 lambda 로그는 그것을 표시하고, 이전 값은 X=2로 표시합니다. 이것은 첫 번째 세션이 변경된 후에 업데이트가 완료되었을 때 기대한 것입니다.Oracle에서 우리는 두 가지 항목을 볼 수 있습니다. 하나는 X=1에서 업데이트된 것입니다. 이것은 잠기지 않은 상태에서 읽은 다음 X=2에서 스크롤해서 업데이트를 다시 시작합니다.하지만 MySQL이 읽기 단계에서 줄 자물쇠를 얻었기 때문에 이 문제는 없습니다.
    그러나 내부 스크롤 + 재부팅이 없다는 보장은 없다.어쨌든 스크롤이 발생하는 데는 여러 가지 이유가 있습니다. 디자인 과정에서 lambda에 대한 호출이 DML을 위한 것인지 DML을 위한 것인지 고려해야 합니다.예를 들어 특정 이벤트 원본에 사용하면 비동기 지연을 받아들일 수 있지만 실제 발생하지 않은 이벤트를 받지 않으려고 할 수도 있습니다.

    좋은 웹페이지 즐겨찾기