AWS Serverless architecture을 응용한 안정적인 DW 플랫폼 구현

Posted on Posted in HOME, Tech

해줌에서는 태양광 발전소에 관한 여러 서비스(발전량 예측, 모니터링 등)를 제공하기 위해 태양광 발전소의 발전량 데이터를 수집하고 있습니다. 현재 IT 사업실 내에서는 온프레미스 환경(클라우드가 아닌 회사 내부에 자체 구축한 서버 환경)을 아마존 웹서비스(AWS)로 이관을 진행하고 있습니다. 그 중에서 발전소의 발전량 데이터를 수집하는 DW(Data Warehouse의 약자로서, 방대한 데이터의 집합소를 뜻함) 플랫폼을 이관하는 부분에 대해 글을 써보려고 합니다. AWS에서 사용한 서비스들에 대한 설명, 기존 온프레미스 환경에서의 문제점과 AWS로 이관을 진행하면서 있었던 문제점, 해결점에 대해서 글을 써보겠습니다.

 

 


 

 

| 아마존 웹서비스(AWS)

 

아마존 웹서비스(AWS)는 대량의 서버, 스토리지, 네트워크 장비 인프라를 제공하는 클라우드 서비스입니다.

요즘 AWS 커뮤니티에서 많이 거론되는 단어 중 하나가 Serverless Architecture입니다. Serverless Architecture란 서버를 따로 띄우지 않고, 코드를 업로드 하여 기존 서버에서 문제점이였던 관리, 스케일링과 같은 이슈 등을 해결해줍니다. 여기에서 빠짐없이 등장하는 AWS의 서비스 중 하나가 바로 Lambda입니다.

 

 

 

 

| AWS Lambda

 

AWS Lambda is a compute service that lets you run code without provisioning or managing serverless.

– 출처: https://aws.amazon.com/lambda

 

 

 

| AWS Lambda 특징

 

 

AWS Lambda에는 여러가지 특징이 있습니다.

 

 

  1. 사용한 만큼만 요금이 부과됩니다.(100ms 당 요금이 부과된다.)
  2.  서버 관리가 불필요합니다.
  3. 스케일링 이슈가 없습니다.
  4. 각 트리거에 대한 응답으로 코드를 실행하여 애플리케이션을 자동으로 확장하거나 축소가 가능합니다.

또한 아래와 같은 일들이 가능합니다.
출처: https://aws.amazon.com/ko/lambda/

 

 

  • 실시간 파일 처리

 

 

실시간으로 파일 처리가 가능합니다. Amazon S3를 사용하여 업로드하는 즉시 데이터를 처리하도록 AWS Lambda를 트리거할 수 있습니다. 예를 들어, Lambda를 사용하여 실시간으로 이미지를 썸네일하고, 동영상을 트랜스코딩하고, 파일을 인덱싱하고, 로그를 처리하고, 콘텐츠를 검증하고, 데이터를 수집 및 필터링할 수 있습니다.

 

  • 실시간 스트림 처리

스트림 처리가 가능합니다. AWS Lambda 및 Amazon Kinesis를 사용하여 애플리케이션 활동 추적, 트랜잭션 주문 처리, 클릭 스트림 분석, 데이터 정리, 로그 필터링, 인덱싱, 소셜 미디어 분석을 위한 실시간 스트리밍 데이터를 처리할 수 있습니다.

 

 

  • 서버리스 웹앱

서버리스 웹앱을 구성할 수 있습니다. AWS Lambda를 다른 AWS 서비스와 결합하면, 확장성, 백업 또는 여러 데이터 센터 중복에 필요한 별도의 관리 작업 없이 개발자가 자동으로 확장 및 축소되고 여러 데이터 센터에 걸쳐 가용성이 높은 구성에서 실행되는 강력한 웹 애플리케이션을 구축할 수 있습니다.

 

 

 

| 기존 발전량 데이터 수집의 문제점

 

 

온프레미스 환경에서는 데이터를 수집을 하던 logic은 다음과 같은 문제점이 있습니다.

  1. 온프레미스 환경이기 때문에, 내부 혹은 외부의 위험에 노출되어 있습니다. script가 실행이 되고 있는 컴퓨터에 많은 작업들이 실행이 될 시, 메모리, cpu 등 자원에 과부하가 생기게 됩니다. 이것은 발전량 데이터 수집에 영향을 미칠 수 있습니다. 또한 건물에 정전 등과 같은 외부 위험이 생길 시, 네트워크가 되지 않거나 컴퓨터가 꺼져 버리는 문제가 발생하며 이 또한 발전량 데이터 수집에 영향을 미칠 수 있습니다.
  2. Scalibility 이슈에 취약합니다. 클라우드에 비해 제한된 온프레미스 환경에서 발전량 데이터 수집을 하기 때문에, 후에 지금보다 더 많은 데이터를 수집할 시 문제가 생길 수 있습니다.

 

 

 

 

| AWS Serverless architecture을 응용한 안정적인 DW 플랫폼 구현

 

 

 

온프레미스 환경의 DW 플랫폼을 위와 같은 구성으로 AWS로 이관하였습니다. CloudWatch로 time-based event를 발생시켜 Raw 발전량 데이터를 수집 및 S3에 저장하는 Lambda를 trigger 시킵니다. Raw 발전량 데이터는 추가적으로 파싱이 필요한 데이터입니다. S3에 Raw 발전량 데이터를 저장함으로써, 후에 데이터 Parsing 혹은 다른 문제가 생길 시, 추적이 가능하도록 합니다. S3에 발전량 데이터가 수집이 되면 여기서 S3의 ObjectCreated Event가 생성이 되며 이 Event에 의해 S3에 저장된 Raw 발전량 데이터를 parsing하는 Lambda가 trigger됩니다. 그리고 이 Lambda는 parsing한 결과를 DynamoDB에 저장합니다.

 

 

 

 

| 하지만 timeout…

 

 

위 구조로 데이터 수집을 할 시 문제가 없을 것 같았으나,  timeout 문제가 발생하였습니다.

Lambda 사용을 하다 보니 여러 이슈가 있었지만, 이 timeout이 가장 골치가 아팠는데요.

Lambda에서 최대 timeout은 5분입니다. 한 Lambda instance의 작업이 최대 5분 안에는 이루어 져야 한다는 점이죠. 그래서 5분 이상이 걸리는 기존 코드를 그대로 Lambda에 옮겨 놓으면 timeout이 발생할 수 있습니다. (제가 이번에 그랬죠..) 또한 구조적으로 한 Lambda instace에서 많은 일을 담당하므로 scalibility 이슈에도 대응을 할 수가 없습니다.

 

 

물론 Lambda의 성능을 높이면 되긴 합니다. 위 그림을 살펴보시면 Lambda instance 성능에 따른 요금 책정을 알 수 있습니다. 128MB가 제일 낮은 성능이고, 최고는 3008MB 입니다. 100ms당 요금이 과금이 되는 형식입니다.

하지만 성능을 높일수록 가격이 기하급수적으로 높아지게 됩니다. 또한 데이터 수집에는 고성능의 Lambda instance가 전혀 필요하지 않습니다.

어떻게 해결을 할까 여러 고민을 하였습니다. Lambda에서 하는 일이 ec2로도 가능은 하지만, 서버 관리 시간, 노력이 많이 들어갈 것 같았습니다. 또한 ec2의 요금은 Lambda에 비해 상대적으로 비쌉니다.

 

 

 

| 시스템 구성 변경

 

 

그래서 다음과 같은 방법으로 구조를 변경하였습니다.

 

 

 

한 Lambda instance에서 실행되는 코드에서 loop는 없도록 코드를 refactoring하고, loop에서 실행되는 한 작업 당 한 Lambda instance가 담당하도록 구성하였습니다.

발전소 데이터를 수집하는 것은 async한 프로세스이기 때문에 충분히 가능하였습니다.

원래는 producer/consumer 개념으로 중간에 SQS(아마존 큐 서비스)를 이용해볼까 하였지만, 다음과 같은 쉬운 방법이 있었습니다.
AWS Lambda Manager가 있고, 이 manager가 여러 Lambda instance를 invoke하는 방법입니다. Invoke하는 방식은 여러가지 있습니다. 그 중 boto3 라이브러리를 이용한 방법을 소개합니다. (boto3는 Python용 AWS SDK 이며, 환경은 python 3.6.2 입니다.)

 

import boto3
import json
lan = boto3.client(‘lambda’)
payload = {}
payload[‘hello’] = ‘hi’
# worker Lambda 호출
lan.invoke(FunctionName=”function_name”,
InvocationType=’Event’,
Payload=json.dumps(payload))

 

boto3 라이브러리의 invoke함수를 이용하는 방법입니다.  이 함수는 다른 Lambda instance를 생성시켜줍니다.  function name에는 Lambda 함수명을 넣어주고, InvocationType같은 경우는 Event로 주었습니다. (Sync하게 구성을 하고 싶으시면 RequestResponse 옵션을 주시면 됩니다.)
그리고 event로 넘겨줄 데이터를 dictionary 변수에 넣어주고 json형태로 넘겨주면 됩니다.

이러한 구조 변경으로 인해 안정적인 DW 플랫폼을 구성할 수 있었습니다.

 

 

| 마무리

 

 

위 방법으로 시스템을 구성한 결과 timeout문제는 전혀 없었습니다. Lambda를 사용해본 결과 얻었던 교훈은 한 Lambda instance에서 많은 코드를 실행시키지 말아야 하며, 적절한 분산 처리를 해야 한다는 점이였습니다.

Lambda를 쓰면서 가장 좋았던 점은 서버 관리를 따로 하지 않아도 된다는 점이였고, 또한 매우 싸다는 점입니다. EC2 instance를 띄워 구성하였을 시,  기본 몇만원은 하는 돈이 발생하지만, Lambda 같은 경우는 몇 달러 정도 이내에서 모두 해결이 가능하였습니다.

이 글의 리뷰를 도와주신 IT 사업실 분들 내부 분들께 감사의 말씀을 올리며 글을 마치겠습니다! 읽어주셔서 감사합니다!

 

답글 남기기

이메일은 공개되지 않습니다. 필수 입력창은 * 로 표시되어 있습니다.