Amazon Neptune에서의 AWS Lambda 함수 사용 - Amazon Neptune

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

Amazon Neptune에서의 AWS Lambda 함수 사용

AWS Lambda 함수는 Amazon Neptune 애플리케이션에서 많이 사용됩니다. 여기서는 널리 사용되는 Gremlin 드라이버 및 언어 변형과 함께 Lambda 함수를 사용하는 방법에 대한 일반적인 지침과 Java, Python으로 작성된 Lambda 함수의 구체적인 예를 제공합니다. JavaScript

참고

Neptune에서 Lambda 함수를 사용하는 가장 좋은 방법은 최근 엔진 릴리스와 함께 변경되었습니다. Neptune은 Lambda 실행 컨텍스트가 재활용된 후에도 한참 유휴 연결을 열어 두곤 했는데, 이로 인해 서버에서 리소스 유출이 발생할 가능성이 있습니다. 이를 완화하기 위해 Lambda를 간접 호출할 때마다 연결을 열고 닫는 것이 좋습니다. 그러나 엔진 버전 1.0.3.0부터 비활성 Lambda 실행 컨텍스트가 재활용된 후 연결이 유출되지 않도록 유휴 연결 제한 시간이 줄어들어, 이제 실행 컨텍스트 기간 동안 단일 연결을 사용하는 것이 좋습니다. 여기에는 예기치 않게 종료되는 연결을 처리하기 위한 몇 가지 오류 처리 및 back-off-and-retry 상용구 코드가 포함되어야 합니다.

함수의 Gremlin 연결 관리 WebSocket AWS Lambda

Gremlin 언어 변형을 사용하여 Neptune을 쿼리하는 경우 드라이버는 연결을 사용하여 데이터베이스에 연결합니다. WebSocket WebSockets 수명이 긴 클라이언트-서버 연결 시나리오를 지원하도록 설계되었습니다. AWS Lambda반면 는 비교적 수명이 짧고 상태를 저장하지 않는 실행을 지원하도록 설계되었습니다. 이러한 설계 원칙의 불일치로 인해 Lambda를 사용하여 Neptune을 쿼리할 때 예상치 못한 문제가 일부 발생할 수 있습니다.

AWS Lambda 함수는 함수를 다른 함수와 분리하는 실행 컨텍스트에서 실행됩니다. 실행 컨텍스트는 함수를 처음 간접 호출할 때 생성되며 동일한 함수를 이후에 간접 호출할 때 재사용될 수 있습니다.

그러나 함수의 여러 동시 간접 호출을 처리하는 데 실행 컨텍스트를 하나만 사용하지는 않습니다. 여러 클라이언트가 함수를 동시에 간접적으로 호출하는 경우 Lambda는 함수의 각 인스턴스에 대해 추가 실행 컨텍스트를 실행합니다. 이러한 모든 새 실행 컨텍스트는 이후 함수 간접 호출에 차례로 재사용될 수 있습니다.

Lambda는 특히 일정 기간 동안 비활성 상태였던 실행 컨텍스트를 특정 시점에서 재활용합니다. AWS Lambda Init, InvokeShutdown 단계를 포함한 실행 컨텍스트 라이프사이클을 Lambda 확장을 통해 공개합니다. 이러한 확장을 사용하면 실행 컨텍스트가 재활용될 때 데이터베이스 연결과 같은 외부 리소스를 정리하는 코드를 작성할 수 있습니다.

일반적인 모범 사례는 Lambda 핸들러 함수 외부에서 데이터베이스 연결을 열어 각 핸들러 호출에서 재사용할 수 있도록 하는 것입니다. 어느 시점에서 데이터베이스 연결이 끊어지면 핸들러 내부에서 다시 연결할 수 있습니다. 하지만 이 방법을 사용하면 연결 유출이 발생할 위험이 있습니다. 실행 컨텍스트가 제거된 후에도 한참 유휴 연결이 열린 상태로 유지되면 Lambda 간접 호출 시나리오가 간헐적이거나 폭주하는 경우 점차 연결이 누출되어 데이터베이스 리소스가 소진될 수 있습니다.

Neptune 연결 제한 및 연결 제한 시간이 최신 엔진 릴리스에 따라 변경되었습니다. 이전에는 모든 인스턴스가 최대 60,000개의 연결을 지원했습니다. WebSocket 이제 Neptune 인스턴스당 최대 동시 WebSocket 연결 수는 인스턴스 유형에 따라 달라집니다.

또한 엔진 릴리스 1.0.3.0부터 Neptune은 연결의 유휴 제한 시간을 1시간에서 약 20분으로 단축했습니다. 클라이언트가 연결을 끊지 않으면 20~25분의 유휴 제한 시간이 지나면 연결이 자동으로 닫힙니다. AWS Lambda 실행 컨텍스트 수명을 문서화하지는 않지만 실험에 따르면 새로운 Neptune 연결 제한 시간은 비활성 Lambda 실행 컨텍스트 제한 시간에 잘 맞습니다. 비활성 실행 컨텍스트가 재활용될 때쯤이면 Neptune에 의해 연결이 이미 종료되었거나 곧 종료될 가능성이 높습니다.

Amazon Neptune AWS Lambda 그렘린과 함께 사용하기 위한 권장 사항

이제 Lambda 실행 컨텍스트의 전체 수명 주기 동안 함수 간접 호출마다 연결 및 그래프 순회 소스를 하나씩 사용하는 대신 단일 연결 및 그래프 순회 소스를 사용하는 것이 좋습니다(모든 함수 간접 호출은 하나의 클라이언트 요청만 처리함). 동시 클라이언트 요청은 별도의 실행 컨텍스트에서 실행되는 여러 함수 인스턴스에서 처리되므로, 함수 인스턴스 내에서 동시 요청을 처리하기 위해 연결 풀을 유지할 필요가 없습니다. 사용 중인 Gremlin 드라이버에 연결 풀이 있는 경우 하나의 연결만 사용하도록 구성하세요.

연결 실패를 처리하려면 각 쿼리에 대해 재시도 로직을 사용하세요. 실행 컨텍스트의 수명 기간 동안 단일 연결을 유지하는 것이 목표이긴 하지만, 예상치 못한 네트워크 이벤트로 인해 연결이 갑자기 종료될 수 있습니다. 이러한 연결 실패는 사용 중인 드라이버에 따라 다른 오류로 나타납니다. Lambda 함수를 코딩하여 이러한 연결 문제를 처리하고 필요한 경우 재연결을 시도해야 합니다.

일부 Gremlin 드라이버는 자동으로 재연결을 처리합니다. 예를 들어, Java 드라이버는 클라이언트 코드를 대신하여 Neptune에 대한 연결 재설정을 자동으로 시도합니다. 이 드라이버를 사용하면 함수 코드에서 쿼리를 백오프하고 다시 시도하기만 하면 됩니다. 반대로 JavaScript 및 Python 드라이버는 자동 재연결 로직을 구현하지 않으므로 이러한 드라이버를 사용하면 함수 코드가 백오프 후 다시 연결을 시도하고 연결이 다시 설정된 후에만 쿼리를 다시 시도해야 합니다.

여기의 코드 예제는 클라이언트가 재연결을 처리한다고 가정하지 않고 재연결 로직을 포함하고 있습니다.

Lambda에서의 Gremlin 쓰기 요청 사용에 대한 권장 사항

Lambda 함수가 그래프 데이터를 수정하는 경우 다음 예외를 처리하는 전략을 채택해 back-off-and-retry 보십시오.

  • ConcurrentModificationException   –   Neptune 트랜잭션 체계는 쓰기 요청이 때때로 ConcurrentModificationException와 함께 실패한다는 것을 의미합니다. 이러한 상황에서는 지수 재시도 메커니즘을 사용해 보십시오. back-off-based

  • ReadOnlyViolationException   –   계획된 이벤트 또는 예상치 못한 이벤트의 결과로 클러스터 토폴로지가 언제든지 변경될 수 있으므로, 쓰기 책임이 클러스터의 한 인스턴스에서 다른 인스턴스로 이전될 수 있습니다. 함수 코드가 더 이상 기본(라이터) 인스턴스가 아닌 인스턴스에 쓰기 요청을 보내려고 하면 요청이 실패하고 ReadOnlyViolationException이 발생합니다. 이 경우 기존 연결을 닫고 클러스터 엔드포인트에 다시 연결한 다음 요청을 재시도하세요.

또한 쓰기 요청 문제를 처리하는 back-off-and-retry 전략을 사용하는 경우 생성 및 업데이트 요청에 대해 동등한 쿼리를 구현하는 것도 좋습니다 (예: fold () .coalesce () .unfold () 사용).

Lambda에서의 Gremlin 읽기 요청 사용에 대한 권장 사항

클러스터에 하나 이상의 읽기 전용 복제본이 있는 경우 이러한 복제본 간에 읽기 요청의 균형을 맞추는 것이 좋습니다. 한 가지 옵션은 리더 엔드포인트를 사용하는 것입니다. 리더 엔드포인트는 복제본을 추가 또는 제거하거나 복제본을 승격하여 새 기본 인스턴스로 만들 때 클러스터 토폴로지가 변경되더라도 복제본 간의 연결 균형을 유지합니다.

하지만 리더 엔드포인트를 사용하면 경우에 따라 클러스터 리소스가 고르지 않게 사용될 수 있습니다. 리더 엔드포인트는 진입점이 가리키는 호스트를 주기적으로 변경하여 작동합니다. DNS DNS항목이 변경되기 전에 클라이언트가 많은 연결을 열면 모든 연결 요청이 단일 Neptune 인스턴스로 전송됩니다. 처리량이 높은 Lambda 시나리오에서 Lambda 함수에 대한 동시 요청이 많으면 각각 고유한 연결을 가진 여러 실행 컨텍스트가 생성되는 경우가 이에 해당합니다. 이러한 연결이 거의 동시에 생성되는 경우 연결은 모두 클러스터의 동일한 복제본을 가리키고 실행 컨텍스트가 재활용될 때까지 해당 복제본을 계속 가리킬 가능성이 높습니다.

요청을 인스턴스 간에 분산할 수 있는 한 방법은 리더 엔드포인트가 아닌 복제 인스턴스 엔드포인트 목록에서 무작위로 선택한 인스턴스 엔드포인트에 연결하도록 Lambda 함수를 구성하는 것입니다. 이 접근 방식의 단점은 클러스터 구성 요소가 변경될 때마다 Lambda 코드가 클러스터를 모니터링하고 엔드포인트 목록을 업데이트하여 클러스터 토폴로지의 변경을 처리해야 한다는 것입니다.

클러스터의 인스턴스 간 읽기 요청의 균형을 유지해야 하는 Java Lambda 함수를 작성하는 경우, 클러스터 토폴로지를 인식하고 Neptune 클러스터의 인스턴스 세트에 연결과 요청을 공정하게 분배하는 Java Gremlin 클라이언트인 Amazon Neptune용 Gremlin 클라이언트를 사용할 수 있습니다. 이 블로그 게시물에는 Amazon Neptune용 Gremlin 클라이언트를 사용하는 샘플 Java Lambda 함수가 포함되어 있습니다.

Neptune Gremlin Lambda 함수의 콜드 스타트를 늦출 수 있는 요인

AWS Lambda 함수가 처음 호출되는 것을 콜드 스타트라고 합니다. 콜드 스타트의 지연 시간을 증가시킬 수 있는 몇 가지 요인은 다음과 같습니다.

  • Lambda 함수에 충분한 메모리를 할당해야 합니다.   — Lambda 함수의 컴파일은 함수에 할당한 메모리에 비례하여 선형적으로 CPU 사이클을 EC2 AWS Lambda 할당하기 때문에 Lambda 함수가 실행 중일 때보다 훨씬 느릴 수 있습니다. 1,769MB의 메모리를 사용하는 경우 함수는 풀 v 1개 CPU (초당 1v초 크레딧) 를 받는 것과 같습니다. CPU 적절한 CPU 사이클을 수신하기에 충분한 메모리를 할당하지 않을 경우의 영향은 Java로 작성된 대규모 Lambda 함수의 경우 특히 두드러집니다.

  • IAM데이터베이스 인증을 활성화하면 콜드 스타트 속도가 느려질 수 있습니다. AWS Identity and Access Management (IAM) 데이터베이스 인증은 특히 Lambda 함수가 새 서명 키를 생성해야 하는 경우 콜드 스타트를 느리게 할 수 있습니다. IAMDB 인증이 연결 자격 증명을 설정한 후에는 Neptune이 해당 자격 증명이 유효한지 주기적으로 검증하기 때문에 이 지연 시간은 콜드 스타트에만 영향을 주고 후속 요청에는 영향을 주지 않습니다.