AWS EventBridge 사용 시 발생한, Firestore 읽기 횟수 초과

kukjunLEE·2023년 9월 16일
1

Trouble Shooting

목록 보기
3/5
post-thumbnail

본 내용은 AWS EventBridge 사용시에 발생한 문제를 해결하는 과정을 다루고 있습니다. AWS EventBridge, Lambda, Firestore에 대한 기본적인 지식을 요하고 있습니다.



개요


이번에 사용자가 Excel File을 업로드하면, Lambda, EventBridge, Firestore를 이용해서 Excel File의 정보들을 Database에 넣어주는 기능을 개발하게 되었는데, 이때 발생한 이슈가 있어서 공유하고자 글을 남깁니다.

바로 한번 수행에 100회 미만의 읽기가 발생해야 하는 로직을 10번 미만으로 수행했는데, Firestore에 일일 제한 읽기 횟수인 50000만회를 채우는 일이 발생한 것이었습니다. 😇

FireStore 읽기 횟수 제한 도달



해당 Issue는 다행히 Firestore를 유료 플랜으로 결제하지 않은 상태라서 비용적인 문제는 발생하지 않았지만,
만약 Firestore를 유료플랜으로 결제했다면 큰 비용 손실이 있었을 건으로 간주되었고, 그래서 중요도를 높게 선정해서 Hotfix로 처리하고자 하였습니다.




기능에 대한 분석


먼저 문제를 분석 하기 전, 어떤 기능이었는지 간단하게 살펴보도록 하겠습니다.

  1. 사용자가 Excel File Upload 요청을 보냅니다.
  2. Excel 파일에 대한 입출력 처리를 Backend에서 처리하는것보다 따로 관리하자는 내부 규약에 따라, 환경 정보와 함께, Lambda로 처리를 위임합니다.
  3. Lambda를 통해 Excel 파일을 Firestore에 Document로 저장하고, 작업이 종료되면 다음 Lambda를 수행하기 위한 EventBridge를 활성화합니다.
  4. Event가 활성화되면, Lambda가 수행되는데, 해당 Lambda는 Firestore에 저장된 document를 가져와, key, value 정보를 WAS로 보내주는 역할을 합니다. 모든 데이터 전송이 완료되면 EventBridge의 Event를 종료합니다.
  5. 들어온 데이터로, 데이터 처리 작업을 진행합니다.


그럼 이제 어디에서 문제가 발생했는지 차근차근 분석해보도록 하겠습니다.





Trouble Shooting


FireStore 정보 분석


FireStore 읽기 횟수 제한 도달

가장 먼저 문제가 발생했던 Fire Store 읽기 횟수 초과에 대해서 알아보면, 특정 시간을 기점으로, 읽기 횟수가 계속 증가하고, 결국 최대 한도까지 도달하는 것을 알 수 있었고, 스냅샷 리스너를 통해서, 어떠한 요청이 Firestore에 계속 발생하고 있다는 것도 알 수 있었습니다.

표 이해를 위해 밑에 설명을 추가했습니다.

  1. 스냅샷 리스너 (Snapshot Listeners):
    • Firestore에 저장된 데이터의 변화를 실시간으로 감지하고자 할 때 사용하는 리스너입니다.
    • 예를 들면, 특정 문서나 컬렉션에 변화가 발생할 때마다 알림을 받아 즉시 UI를 업데이트하는 등의 작업을 할 수 있습니다.
    • 이 리스너는 데이터가 추가, 수정, 삭제될 때마다 콜백을 실행하여 변화를 감지합니다.
  2. 활성 연결 수 (Active Connections):
    • Firestore는 클라이언트와 서버 간에 지속적인 연결을 유지하기 위해 웹소켓을 사용합니다.
    • 활성 연결 수는 현재 Firestore 데이터베이스에 연결된 클라이언트의 수를 나타냅니다.
    • 애플리케이션의 사용자가 많아질수록 활성 연결 수도 증가합니다.


그러니까 Firestore에 정보를 요약하자면, FireStore에 저장된 정보들을 연결된 Lambda가 계속 읽고 있다는 것이다. 심지어 사용자 수가 계속 늘어나기까지 하는 것을 알 수 있습니다..

하지만 나는 FireStore에 저장된 데이터를 가져와서 WAS에 보내주고 나서는 저장된 데이터를 이벤트를 종료하도록 설정해놨는데 왜 이런일이 생겼을까요?


Firestore 정보를 분석해본 결과, 이벤트가 꺼지지 않아 Lambda가 계속 실행된다는 것을 의미하므로 AWS Lambda를 분석 해보도록 하겠습니다.




AWS Lambda 분석


Log 분석

로그 및 정보들을 제공할 수는 없지만, AWS Lambda의 Log들을 분석해본 결과 Lambda에 시간초과가 발생해서 정상적으로 종료되지 않는다는 것을 알 수 있었습니다.

정상적인 종료가 이루어지지 않기 때문에 Lambda 끝에 설정한, 저장된 Document 삭제 로직과 이벤트 삭제 로직이 동작하지 않았던 것입니다. 🤪

그리고 정상적인 종료가 이루어지지 않는 Lambda는, 재시작되고 있었습니다. 이로 인해 이벤트가 활성화되면 람다가 동작하는데 람다가 예기치 않는 오류로 종료되고 다시 시작하고, 이벤트가 꺼지지 않았으므로 이벤트에 의해 Lambda는 또 시작되고 ... 이렇게 반복되면서 FireStore에 읽기 횟수를 초과하게 되는 것입니다.

예를 들어서, Lambda 시간제한이 1분, Event는 3분에 한번씩 람다를 키도록 설정해놓고, Lambda가 1분 시간초과를 발생시킨다면
Event로 첫 람다가 시작되고, 15분이 지나면 동일한 Lambda가 6개 켜지고, 각각의 람다는 또 실패하고 다시 켜지는 과정을 반복하게 될 것입니다.

그럼 이제 Lambda code를 분석해보도록 하겠습니다.




Lambda 분석

전체 코드를 제공할 수는 없지만 문제가 된 부분은 다음 부분입니다.


const result = await Promise.all(funcs);

해당 Promise.all() 는 비동기 병렬처리를 하는 함수입니다. Lambda에서 Promise.all()을 사용하는 경우에는 몇가지 고려할 사항이 있는데, 그 내용은 다음과 같습니다.

  1. Timeout: 병렬로 많은 프로미스를 실행하면 Lambda의 최대 실행 시간을 초과할 수 있습니다.
  2. 병렬 처리 제한: Lambda에서 동시에 너무 많은 연결을 열거나 리소스를 사용하려고 하면, 리소스나 연결 제한에 도달할 수 있습니다.
  3. 메모리 제한: Lambda는 메모리 제한이 있습니다. 너무 많은 작업을 동시에 처리하면 메모리 부족 오류가 발생할 수 있습니다.
  4. 외부 서비스 연결 요청 과다: 외부 서비스 연결 등에서 제한이나 병목 현상이 발생할 수 있습니다.

제 경우는 해당 Promise.all() 실행 시, 최대 100개의 요청을 만들어서 WAS로 요청을 보내고 있었고, 이 때 시간 제한에 걸려 중간에 강제로 종료 되었던 것 입니다.





Solution


이번 Trouble Shooting에서 알게된 핵심 문제는,

Lambda의 Timeout시에는 예외처리 및 종료 시 처리하는 함수가 동작하지 않는다는 것입니다.

그리고 추가적으로 알게 된 주요 내용은,

  1. Lambda에서 병렬 처리를 하기 위해서 Lambda Timeout과, Lambda의 리소스를 신경써야 한다.
  2. Firestore, AWS Lambda에 비용을 고려해서 각각 제한 및 즉각적인 알림을 위한 알람을 설정해야 한다.

는 것을 알게 되었습니다.

그 외에도 문제를 살펴보며, Lambda, EventBridge, Firestore에 더 자세하게 알게 되었습니다. 😇

현재 문제 해결


HotFix였으므로, 지금 당장의 문제를 해결하는 방법은 다음과 같습니다.

  1. Lambda의 Timeout 시간 증가

Lambda의 Timeout 시간을 1분에서 3분으로 증가시켰습니다.


  1. Lambda 병렬 처리를 취소.

Lambda 코드를 수정을 통해 병렬로 수행하던 코드를 병렬로 처리하지 않도록 변경시켰습니다. 그래서 시간초과 오류가 발생하더라도, 수행한 부분까지 firestore의 document가 감소되어, 남은 부분부터 다시 요청 처리를 할 수 있으므로, 같은 읽기를 반복하지 않도록 했습니다.


앞으로 적용할 내용


HotFix이므로, 일단 문제를 해결했지만, 추가적으로 더 찾아보고 적용할 내용들은 다음과 같습니다.

EventBridge 실행 시 조건 설정

Lambda 갯수 제한하기

profile
Backend Developer

0개의 댓글