공부하기싫어
article thumbnail

라이브러리

함수 실행에 필요한 라이브러리들이다.

 

  • pyupbit
  • prophet

 

1. 람다 계층으로 시도 (실패)

ubuntu 인스턴스(t3a.large)를 띄우고 python 디렉토리를 만들어 준 후 위 라이브러리들을 다운받았다.

이후 압축후 람다 계층을 생성하고 add layer 로 추가해봤지만 numpy 버전이 맞지 않는지 테스트에 실패햇다.

aws 제공 layer 중 pandas 를 추가하면 numpy 호출이 잘 되었지만 종속성을 추가하면 용량 제한을 초과해서 다른 방법을 찾아보기로 했다.

 

 

2. CodeArtifact 참조 (실패)

CodeArtifact 에 prophet 과 pyupbit 패키지를 업로드하고 SDK 를 통해  lambda 로 불러오려고했으나

content 중 asset 을 불러오는데에서 더 진행이 되지 않아 실패했다.

에셋 리스트를 불러와서 확인한 다음 코드에 반영했지만 잘 되지 않았다.

 

 

3. Container image 로 lambda 함수 배포

pip 모듈인 pyupbit 와 prophet 의 크기가 너무 크기때문에 컨테이너 이미지로 배포해보려고 한다.

 

  • 컨테이너 이미지로 람다를 배포할때 용량 제한은 10GB 이다.
  • 오프라인으로 함수를 실행해볼 수 없다.

라고 한다.

 

연습으로 demo private 리포지토리를 ECR 에 생성하고

requirements.txt 파일에 pyupbit, prophet 을 넣고 빌드-푸시 한 후

컨테이너 이미지로 ECR 에 푸시된 이미지를 선택해서 테스트 해봤다

성공

모듈을 정상적으로 불러오는데 성공했다.

 

 

 

컨테이너 이미지

각각 람다 함수를 만들어주기 위해 2개의 ECR 리포지토리를 만들어서 배포할꺼다.

람다 역할은 따로 만들어서 설정해줄 예정

 

Dockerfile

dockerfile_bestk

FROM public.ecr.aws/lambda/python:3.9

# Install the function's dependencies using file requirements.txt
# from your project folder.

COPY requirements.txt  .
RUN  pip3 install -r requirements.txt --target "${LAMBDA_TASK_ROOT}"

# Copy function code
COPY lambda/app.py ${LAMBDA_TASK_ROOT}

# Set the CMD to your handler (could also be done as a parameter override outside of the Dockerfile)
CMD [ "app.handler" ]

 

dockerfile_endprice

FROM public.ecr.aws/lambda/python:3.9

# Install the function's dependencies using file requirements.txt
# from your project folder.

COPY requirements.txt  .
RUN  pip3 install -r requirements.txt --target "${LAMBDA_TASK_ROOT}"

# Copy function code
COPY lambda/app.py ${LAMBDA_TASK_ROOT}

# Set the CMD to your handler (could also be done as a parameter override outside of the Dockerfile)
CMD [ "app.handler" ]

 

 

 

requierments.txt

pyupbit
prophet

bestk 에는 prophet 을 제외해줬다

 

 

디렉토리

 

ECR 리포지토리

퍼블릭으로 생성했었는데 잘 안되서 프라이빗으로 생성했다

 

2개 생성해줬다

dev_bestk, dev_endprice

 

 

도커 빌드+푸시

# bestk
aws ecr get-login-password --region ap-northeast-2 | docker login --username AWS --password-stdin 501587125031.dkr.ecr.ap-northeast-2.amazonaws.com
docker build -t dev_bestk:1 .
docker tag dev_bestk:1 501587125031.dkr.ecr.ap-northeast-2.amazonaws.com/dev_bestk:1
docker push 501587125031.dkr.ecr.ap-northeast-2.amazonaws.com/dev_bestk:1

# endprice
aws ecr get-login-password --region ap-northeast-2 | docker login --username AWS --password-stdin 501587125031.dkr.ecr.ap-northeast-2.amazonaws.com
docker build -t dev_endprice:1 .
docker tag dev_endprice:1 501587125031.dkr.ecr.ap-northeast-2.amazonaws.com/dev_endprice:1
docker push 501587125031.dkr.ecr.ap-northeast-2.amazonaws.com/dev_endprice:1

앞으로 코드를 수정해나가면서 뒤의 버전값을 늘려갈 예정

 

 

역할 생성

 

람다 함수 생성

bestk

메모리를 512MB 로 줬고 timeout 을 30초로 해줬다

 

endprice

메모리를 4GB 로 줬고 timeout 은 1분으로 해줬다

 

 

 

 

 

테스트

bestk.1 안의 app.py

import pyupbit
import numpy as np


def get_ror(k=0.5):
    df = pyupbit.get_ohlcv("KRW-BTC", count=7)
    df['range'] = (df['high'] - df['low']) * k
    df['target'] = df['open'] + df['range'].shift(1)

    df['ror'] = np.where(df['high'] > df['target'],
                         df['close'] / df['target'],
                         1)

    ror = df['ror'].cumprod()[-2]
    return ror


def handler(event, context):
    dict={}
    for k in np.arange(0.1, 1.0, 0.1):
        ror = get_ror(k)
        print("%.1f %f" % (k, ror))
        dict[k]=ror
    bestk=max(dict, key=dict.get)
    bestk=round(bestk, 1)

    return 'bestk : ' + str(bestk) + '   !!!'

 

endprice.1 안의 app.py

import json
import pyupbit
from prophet import Prophet

predicted_close_price = 0
def predict_price(ticker):
    """Prophet으로 당일 종가 가격 예측"""
    global predicted_close_price

    #최근 200시간의 데이터 불러오기
    df = pyupbit.get_ohlcv(ticker, interval="minute60")

    #시간(ds) 과 종가(y) 만 남김
    df = df.reset_index()
    df['ds'] = df['index']
    df['y'] = df['close']
    data = df[['ds','y']]

    #학습
    model = Prophet()
    model.fit(data)

    #24시간 미래 예측
    future = model.make_future_dataframe(periods=24, freq='H')
    forecast = model.predict(future)

    #예상 종가 도출
    closeDf = forecast[forecast['ds'] == forecast.iloc[-1]['ds'].replace(hour=9)]
    if len(closeDf) == 0:
        closeDf = forecast[forecast['ds'] == data.iloc[-1]['ds'].replace(hour=9)]
    closeValue = closeDf['yhat'].values[0]
    predicted_close_price = closeValue


def handler(event, context):
    global predicted_close_price
    
    predict_price("KRW-ETH")
    print(predicted_close_price)

    return 'endprice : ' + str(predicted_close_price) + '   !!!'

 

 

테스트

bestk
endprice

 

 

버전 생성 + 별칭 연결

bestk:active-verison
endprice:active-version

 

 

 

앞으로 위 함수에

- dynamoDB 업데이트 코드 추가 + 권한추가

- x-ray sdk 코드 추가

- 별칭에 cloudwatch eventbridge 연결 + 리소스 기반 정책 추가

정도 작업을 할 예정

 

 

처음부터 도커로 배포했으면 빨랐겠는데..

람다 계층이랑 codeartifact 로 해본다고 전날 9시간 갈아넣고 안돼서 술한잔하고 퍼질러 잔다음에

일어나서 오늘 3시간만에 블로깅까지 다해버리시지

허무해 디질게~

 

 

 

 

 

 

 

 

 

 

 

 

참고 블로그

패키지 압축 후 람다 레이어에 추가하기

https://blog.naver.com/chandong83/221852027113

 

AWS 람다(AWS Lambda) 계층(Layer)를 이용해 파이썬 패키지(Package, Library) 사용하기

aws 람다를 작성하다 보면 기본 제공 패키지 외에 새로운 패키지를 설치해 사용해야 할 때가 있다. 예전에...

blog.naver.com

 

 

프로펫 람다에 넣기

https://towardsdatascience.com/how-to-get-fbprophet-work-on-aws-lambda-c3a33a081aaf

 

How to get fbprophet working on AWS Lambda

Solving package size issues of fbprophet serverless deployment

towardsdatascience.com

 

 

프로펫 람다 도커이미지

https://marcmetz89.medium.com/docker-run-rm-it-v-pwd-var-task-lambci-lambda-build-python3-7-bash-c7d53f3b7eb2

 

How to deploy Prophet by Facebook on AWS Lambda

Import fbprophet, pandas and numpy into your Lambda function.

marcmetz89.medium.com

 

프로펫 문서 

https://facebook.github.io/prophet/docs/installation.html

 

Installation

Prophet has two implementations: R and Python.

facebook.github.io

 

aws 람다 스토리지

https://aws.amazon.com/ko/blogs/korea/choosing-between-aws-lambda-data-storage-options-in-web-apps/

 

AWS Lambda 기반 서버리스 앱에서 데이터 스토리지 선택하기 | Amazon Web Services

AWS Lambda는 서버리스 애플리케이션을 지원하는 온디맨드 컴퓨팅 서비스입니다. Lambda 함수는 임시로 함수가 호출될 때 짧은 시간 동안만 실행 환경이 존재합니다. 그런데, 대부분 컴퓨팅 작업은

aws.amazon.com

 

컨테이너 이미지로 람다 함수 배포하기 aws 문서

https://docs.aws.amazon.com/lambda/latest/dg/python-image.html

 

Deploy Python Lambda functions with container images - AWS Lambda

Thanks for letting us know this page needs work. We're sorry we let you down. If you've got a moment, please tell us how we can make the documentation better.

docs.aws.amazon.com

 

람다 컨테이너 이미지 생성 aws 문서

https://docs.aws.amazon.com/lambda/latest/dg/images-create.html#images-create-from-base

 

Creating Lambda container images - AWS Lambda

When you specify ENTRYPOINT or CMD in the Dockerfile or as an override, make sure that you enter the absolute path. Also, do not use symlinks as the entry point to the container.

docs.aws.amazon.com