라이브러리
함수 실행에 필요한 라이브러리들이다.
- 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
앞으로 코드를 수정해나가면서 뒤의 버전값을 늘려갈 예정
역할 생성
람다 함수 생성
메모리를 512MB 로 줬고 timeout 을 30초로 해줬다
메모리를 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) + ' !!!'
테스트
버전 생성 + 별칭 연결
앞으로 위 함수에
- dynamoDB 업데이트 코드 추가 + 권한추가
- x-ray sdk 코드 추가
- 별칭에 cloudwatch eventbridge 연결 + 리소스 기반 정책 추가
정도 작업을 할 예정
처음부터 도커로 배포했으면 빨랐겠는데..
람다 계층이랑 codeartifact 로 해본다고 전날 9시간 갈아넣고 안돼서 술한잔하고 퍼질러 잔다음에
일어나서 오늘 3시간만에 블로깅까지 다해버리시지
허무해 디질게~
참고 블로그
패키지 압축 후 람다 레이어에 추가하기
https://blog.naver.com/chandong83/221852027113
프로펫 람다에 넣기
https://towardsdatascience.com/how-to-get-fbprophet-work-on-aws-lambda-c3a33a081aaf
프로펫 람다 도커이미지
프로펫 문서
https://facebook.github.io/prophet/docs/installation.html
aws 람다 스토리지
https://aws.amazon.com/ko/blogs/korea/choosing-between-aws-lambda-data-storage-options-in-web-apps/
컨테이너 이미지로 람다 함수 배포하기 aws 문서
https://docs.aws.amazon.com/lambda/latest/dg/python-image.html
람다 컨테이너 이미지 생성 aws 문서
https://docs.aws.amazon.com/lambda/latest/dg/images-create.html#images-create-from-base
'1인개발 메이킹로그 > [Infra+k8s+App] 가상화폐 자동매매' 카테고리의 다른 글
[AWS-Server] 3. 람다함수에 Cloudwatch EventBridge 연결 (0) | 2023.04.02 |
---|---|
[AWS-Server] 2. EC2에서 python 으로 dynamoDB Table, SSM Parameter Store 읽기 (0) | 2023.03.31 |
[AWS-Server] 개발 일정 변경 (0) | 2023.03.27 |
[AWS-Server] dev_env-CICD-3-jenkins (0) | 2023.03.23 |
[AWS-Server] dev_env-CICD-2-demo_cdk_app_stack.py with chatGPT (0) | 2023.03.19 |