카테고리 Archives: Python

AWS SES – SMTP 계정 의 키 변경

AWS SES (Simple Email Service) 는 직접 구축이 어려운 이메일 서비스를 제공한다.

sendmail 으로 SMTP 구성을 사용할 수 있지만 보통 스팸 방지를 위한 여러 솔루션에 의해서 차단이 되기 때문에

직접 sendmail 서비스를 구성하고 서비스 하기 위해서는 광범위한 공부가 필요 하다.

1. sendmail – smtp 구축

2. KISARBL 등록 (이것은 한국의 포털 쪽으로 메일 서비스 원활히 발송하기 위해 필요 하다.)

3. ReverseDNS 등록 (이건 해외 포털 서비스 쪽과 관련이 있다. Internet Service Provider 에서 등록이 가능하다. – KT, SK, U+ 등등..)

4. DKIM, DMARC 설정 (해외 포탈 gmail, yahoo 등등)

아울어서 주기적인 IP 신뢰도 관리를 위해 서버내에서 발송되는 메일을 추적, 통제 해야 한다.

 

AWS SES 는 월 62,000건 까지는 무료로 발송이 되며 이후 초과 되는 1000개의 메일당 약 100~150원 정도의 비용이 발생 한다.

물론 수신자의 스팸 신고가 많거나(1%) 허위 메일 주소로 발송(5%)되면 메일 발송 서비스가 차단 된다.

 

메일 발송을 위한 SMTP 계정은 생성을 하게 되면 auth 계정이 할당 되게 되며 사전에 등록된 메일 주소로만 발송을 할 수 있다.

문제는 ID / PW 형식 이기 때문에 유출 되었거나.. 혹은 패스워드 생성일이 오래 되면 보안상 바꾸어 주어야 한다.

 

AWS – IAM 에서 일반적으로 생성하는 액세스 키는 20글자 시크릿 키는 40 글자 를 차지 한다.

2021-01-22_151318

 

AWS – SES 에서는 SMTP 계정을 만들때 패스워드 길이가 44 글자를 가진다.

즉 SES 메뉴에서 “Create My SMTP Credentials” 생성한 계정을 사용할 수 있다.

2021-01-22_151735

 

그래서 찾아 보니 아래와 같은 메뉴얼을 찾을 수 있었다.

https://aws.amazon.com/ko/premiumsupport/knowledge-center/ses-rotate-smtp-access-keys/

 

근데 이해는 잘 되지 않는…

종합해보면 기본으로 제공 되는 파이선코드 를 이용하여 컨버팅 해서 써야 한다는 말이다.

 

시스템 엔지니어링을 하는 입장에서는 생성된 값을 테스트 하고 넘겨 줘야 하는 부분도 있고 python3 전용인 부분도 조금 마음에 안들어서

패스워드 생성 후 SMTP 테스트를 진행 하도록 하였다. ‘ㅅ’a

 

사용 방법은 다음과 같다.

 

IAM 아무렇게나 생성된 계정에서는 작동하지 않고, 계정에 ses:SendRawEmail 권한이 부여 되어 있어야 작동 한다. (SES 에서 생성한 계정은 이미 부여가 되어 있을 것임.)

 

ps. 위에 예시된 엑세스키/시크릿키/SMTP비밀번호는 이 글을 포스팅 한 이후 모두 삭제 했으니까 굳이 테스트 해보지 않으셔도 된다. ‘ㅅ’a

python – apache pyarrow 를 이용한 parquet 생성 및 테스트

apache 재단에서 진행 되는 프로젝트 이다. python, java, R 등등 많은 언어를 지원 한다.

CSV (Comma-Separated Values)의 가로열 방식의 데이터 기록이 아닌 세로열 기록 방식으로 기존 가로열 방식에서 불가능한 영역을 처리가 가능하도록 한다.

2020-12-24_135314

보이는가 선조의 지혜가 -3-)b

이미지 출처: 훈민정음 나무위키

 

차이점을 그림으로 표현하자면 아래와 같다.

2020-12-28_090732

 

문서를 모두 읽는다 에서는 큰 차이가 발생하지 않지만 구조적으로 모든 행이 색인(index) 처리가 된 것처럼 파일을 읽을 수 있다.

sql 문으로 가정으로 “(SELECT * FROM 테이블 WHERE 재질 = ‘철’)” 을 찾게 될 경우 index 가 둘다 없다는 가정하에서

CSV 는 9개의 칸을 읽어야 하지만 (재질->무게->산화->나무->가벼워->탄다->철->무거워->안탄다->return)

parquet 의 경우 5개의 칸만 읽으면 된다. (재질->나무->철->무거워->안탄다->return)

PS. 물론 색인(index) 는 이런 구조가 아닌 hash 처리에 따른 협차법 으로 찾아서 빨리 찾을 수 있어 차이가 있다.

압축을 하더라도 컬럼별 압축이 되기 때문에 필요한 내용만 읽어서 압축해제 하여 데이터를 리턴 한다.

 

적당한 TSV (Tab-Separated Values)데이터를 준비 한다.

2020-12-24_145706

 

python 을 이용하여 TSV 파일을 읽고 python 의 pyarrow를 이용하여 parquet 파일을 생성 하고 읽는 테스트를 한다. (pyarrow, pandas 는 pip install pyarrow pandas 으로 설치할 수 있다.)

 

TSV -> parquet 압축률(높을수록 좋음) 및 처리 시간(낮을수록 좋음)

defextMBcompress ratioprocessing time
python 2.7
processing time
python 3.6
txt.txt58.8 MB
gzip.txt.gz16.3 MB72%3.24 sec
pyarrowwrite_table,
compression='none'
.parquet
40.1 MB32%0.74 sec0.93 sec
write_table,
compression='snappy'
24.8 MB58%1.31 sec 0.95 sec
write_table,
compression='lz4'
24.7 MB58%0.79 sec0.94 sec
write_table,
compression='zstd'
19.3 MB67%1.00 sec0.98 sec
write_table,
compression='gzip'
18.8 MB68%5.07 sec1.18 sec

읽기/쓰기 테스트 모두 AWS – EC2(m5.large-centos7) – gp2(100GB) 에서 진행 하였다.

 

parquet 을 생성한 이유는 파일을 읽을때 모든 컬럼인 index가 걸려있는것과 같이 빠르게 읽기 위함이니 읽기 테스트도 해본다.

 

TSV, parquet 파일 읽기 테스트 (pandas, pyarrow)

defextMBprocessing time
python 2.7
processing time
python 3.6
pandasread_csv.txt58.8 MB1.39 sec1.56 sec
read_csv,
compression='gzip'
.txt.gz16.3 MB1.68 sec2.06 sec
read_parquet.parquet
(none)
40.1 MB0.72 sec0.93 sec
.parquet
(snappy)
24.8 MB1.03 sec0.95 sec
.parquet
(lz4)
24.7 MB0.73 sec0.94 sec
.parquet
(zstd)
19.3 MB0.76 sec0.95 sec
.parquet
(gzip)
18.8 MB0.96 sec1.18 sec
pyarrowread_csv,
to_pandas
.txt58.8 MB1.01 sec1.30 sec
.txt.gz16.3 MB1.41 sec1.37 sec
read_table,
to_pandas
.parquet
(none)
40.1 MB0.69 sec0.90 sec
.parquet
(snappy)
24.8 MB0.99 sec0.89 sec
.parquet
(lz4)
24.7 MB0.69 sec0.92 sec
.parquet
(zstd)
19.3 MB0.75 sec0.95 sec
.parquet
(gzip)
18.8 MB0.95 sec1.22sec

 

이 문서 처음에 언급 했다 시피 대용량 파일을 처리 하기 위함. 즉 “빅데이터”(HIVE, Presto, Spark, AWS-athena)환경을  위한 포멧이다.

모두 테스트 해보면 좋겠지만 아직 실력이 부족해서 AWS athena 만 테스트를 진행 한다.

구조적으로 S3 버킷에 parquet 파일을 넣어 두고 athena 에서 테이블을(S3 디렉토리 연결) 생성 하여 SQL 문으로 검색을 하는데 사용 한다.

 

TSV, parquet 파일 읽기 테스트 (AWS – athena)

ROW FORMAT SERDEextSearched
MB
processing time
(select target 2)
processing time
(select target 50)
athenaorg.apache.hadoop.hive.
serde2.lazy.
LazySimpleSerDe
.txt58.8 MB1.17 ~ 3.35 sec1.86 ~ 2.68 sec
.txt.gz16.3 MB1.37 ~ 1.49 sec1.44 ~ 2.69 sec
org.apache.hadoop.hive.
ql.io.parquet.serde.
ParquetHiveSerDe
.txt.parquet10.48 MB1.11 ~ 1.49 sec1.00 ~ 1.38 sec
.snappy.parquet4.71 MB0.90 ~ 2.36 sec0.90 ~ 1.00 sec
지원 불가.lz4.parquet지원 불가
.zstd.parquet
org.apache.hadoop.hive.
ql.io.parquet.serde.
ParquetHiveSerDe
.gzip.parquet2.76 MB0.89 ~ 1.17 sec0.90 ~ 1.85 sec

읽는 속도가 향상되었고 스캔 크기가 적게 나온다. (parquet 의 강점을 보여주는 테스트-스캔비용의 절감이 가능.)

 

athena 테이블 생성에 사용된 DDL 쿼리문 (TSV, parquet)

 

PS. 이건 저도 어려 웠어요…..

Machine Learning 공부 – PlaidML

말로만 듣지 말고 해보자 라는 개념으로 시작했다.

Anaconda3 64비트를 설치 하고 파이선의 venv를 생성 한뒤에 tensorflow 설치 및 keras 설치를 진행 한다.

 

이후 메뉴얼의 트레이닝을 했을때 CPU 연산을 하는것으로 확인이 되었고

연습용 PC 으로 AMD 르누아르 계열을 쓰고 있기 때문에 GPU 연산을 위해 PlaidML 을 설치 진행 하였다.

setup시 대화형인데 동의, 그래픽카드선택, 저장 에 순서 의다.

 

사용방법 – keras를 이용하는 코드에서 아래와 같이 선언만 하면 된다.

 

테스트1 – plaidbench

 

테스트2 – python 코드 VGG19

 

잘 돌기는 도는데 이게 지금 GPU 연산을 하는가? 라는 의문이 있었다.

2020-12-02_174953

위와 같이 작업 관리자의 GPU 그래프가 너무나도 잠잠했기 때문에..

트레이닝을 시켰을때 GPU의 메모리 사용량이 늘은 것을 확인 했으나 GPU 코어 측정 부분이 가만히 있고 덩달아 시스템의 cpu / mem 사용량이 늘어 났다.

 

자세히 디버깅을 하면서 실행 해보니 AI 트레이닝 이전에 CPU/MEM 사용량이 먼저 증가 하였다 ‘ㅅ’a

구동 시나리오상 python도 같이 돌기 때문에 python 이 학습 및 테스트 데이터를 dataframe 에 넣을때 cpu 및 memory 사용량이 늘어나는것 같다.

윈도우 작업 관리자의 GPU 부분은 3D / Copy / Video Encoding, Decoding 등등만 보여주기 때문에 트레이닝시 GPU 로드 그래프 확인이 안되는것으로 추정 된다.

 

그래서 찾은 방법은 GPU-Z 를 설치해서 모니터링 하는 것이다.

2020-12-02_181729

잘된다 🙂

 

다른 방법으로는 트레이닝 시간을 측정해 볼수 있겠다.

CPU연산을 했을때에는 5 columns, 110,281 rows 를 LSTM 연산을 했을때 약 35분 11초(2111초)가 소요 되는 트레이닝이 GPU 연산을 했을때 5분 46초(346초)로 단축이 되었다.

 

PS. PlaidML 은 intel 이 만들었고 keras backend 를 연결하여 intel, AMD gpu를 쓸수 있게 해주는 패키지 이다 ‘ㅅ’a

Nvidia 가 만든 CUDA를 이용하는 구글의 tensorflow 를 쉽게 쓰게 도와주는 keras…

이와 별개로 AMD가 구축하는 ROCm 이 있다 ‘ㅅ’a (이거는 나중에 스스로 공부할때 사용할 키워드를 주절주절 써놓은것…)

AWS 상에서의 API Gateway – Lambda – python – pymysql – rds(mariadb) 구현

aws 에서는 API Gateway 를 제공 한다.

이는 serverless 기반의 API 생성 및 운영을 손쉽게 할 수 있는 서비스 이다. (근데 손쉽지 않더라..)

물론 굉장히 난해 하고 어렵지만 처음 한걸음은 항상 어려 웠다 ‘ㅅ’a (이 산을 넘으면 devops 가 되는 첫걸음이 된다.)

 

aws-api-lambda-python-rds

위 이미지 생성은 클라우드크래프트 (https://cloudcraft.co/) 에서 진행 하였다. (AWS 아키텍쳐를 짜는데 매우 유용함.)

 

즉 restful API 를 AWS 상에서 API gateway 와 Lambda 서비스를 이용하여 구축 하여 운영하는 것이다.

이미 이와 같은 많은 글을 참고 하였으나 대부분 아마존에서 제공 하는 nodojs 를 활용하는 방법만 존재 하더라…


1. Lambda 에서 함수를 생성 한다.

2020-08-07_154033


2. 함수가 생성 되면 기본 설정에서 함수의 제한 등을 확인할 수 있다.

핸들러의 의미는 함수가 실행되었을때 lambda_function.py 한의 def lambda_handler() 를 실행한다는 의미가 된다.

(물론 편집도 된다. DB 접근 시간이 있기 때문에 제한시간을 10~15초로 늘린다.)

2020-08-07_162631


3. 스크롤을 올려 보면 AWS Cloud 9 IDE 의 간소화 버전을 이용하여 수정을 할 수 있다.

2020-08-07_163001


4. Test 버튼을 눌러 테스트 셋을 생성 한다. (이미지는 없음)

테스트를 위한 좀더 많은 json 은 https://github.com/awsdocs/aws-lambda-developer-guide/blob/master/sample-apps/nodejs-apig/event.json 에서 확인할 수 있다.

다시 TEST 버튼를 눌러보면 실행 API Gateway 에 연결 되었을때 실행 후 결과 값이 확인 된다.

2020-08-07_164220

함수 생성이 완료 되었지만 Hello World 를 보려고 이것을 하는게 아니기 때문에 API의 근본 목적인 데이터베이스 접속을 할 차례이다 ‘ㅅ’a


배포용 코드 작성은 AWS cloud 9 IDE 를 통해 작성을 할 예정이다. (일반적인 linux 나 windows 환경에서도 가능하다.)

물론 Cloud 9 을 통해 lambda 배포가 가능하지만 단순 소스 작성을 위해서만 이용할 예정 이다 ‘ㅅ’a  (이걸 하려면 또 Cloud Fomation 을 해야 하기 때문에…)

Lambda 에서는 일부 json, logging 등을 별다른 설정 없이 import 할 수 있지만 pymysql 과 같은 서버에 별도 설치가 필요한 부분은 같이 업로드가 되어야 한다.

때문에 아래와 같이 pymysql 설치를 한다.

db 정보를 저장할 dbinfo.py 파일과 AWS lambda 핸들러에서 지정된 lambda_function.py 파일을 같이 생성 한다.

위와 같이 작성을 하고 zip 파일로 압축을 한다.

압출한 파일을 AWS 웹콘솔 에서 업로드 한다.

2020-08-07_173321

zip 파일이 압축 해제가 되며 lambda001 아래에 파일 및 폴더가 위치 할 수 있는데 아래와 같이 드래그 앤 드롭으로 맞추어 준다.

아니면 기본설정-핸들러를 lambda_function.lambda001.lambda_handler 으로 바꾸어도 될꺼 같기도 하다 ‘ㅅ’a

2020-08-07_174505


데이터베이스의 경우 보안 때문에 IP를 막고 일부만 열어서 서비스 하는것이 일반적이기 때문에 실행하는 람다를 VPC 내에서 실행 되게 해야 한다.

그래서 생성한 lambda 함수가 자신의 VPC 에서 네트워크 인터페이스를 사용할 수 있는 권한을 주어야 한다.

2020-08-07_175052

화면 최상단의 권한 으로 이동하고 실행 역할(IAM role) 을 눌러 해당 정책에 정책 추가를 진행해야 한다.

아래의 권한으로 정책을 새롭게 생성해서 연결 해도 되고 인라인 정책 추가를 해도 된다.

추후 생성되는 Lambda 함수는 권한 부분에서 기존 역할로 이미 VPC 권한이 부여된 역할을 선택 해주면 좀더 편하게 사용할 수 있겠다.

2020-08-07_175631


lambda 실행될 VPC 에 대한 정보를 설정해 주어야 한다.

2020-08-07_180250

2020-08-07_180507

사용자 지정 VPC 지정과 VPC 지정 subnet 지정(2개 이상) 과 EC2보안그룹을 지정 하면 된다.


그리고 RDS 서버의 보안그룹에서 위에서 lambda 가 사용할 것으로 지정된 두개의 서브넷(172.31.0.0/20, 172.31.16.0/20)을 허용한다.

2020-08-10_113634


테스트를 달려 본다.

2020-08-07_181235

앗싸 가오리!


너무 길어져서 API 게이트웨이는 나중에 추가 할 예정이다 =_=a

팔로우 할때 주의 할점은 API 게이트 웨이의 리소스 > 메소드 에서 “통합 요청”의 유형이 LAMBDA 가 아닌 LAMBDA_PROXY 으로 해야 하는 python 코드 이다.

python 에서 mysql 접속 하기

서버사이드 프로그램을 짜더라도 DB에 접근 하여 데이터를 가져다가 작동을 하게 하는 경우가 많다.

python의 경우 프로그래밍 언어 이고 사용자 층도 두껍고 오래 되었기 때문에 대부분 드라이버가 제공이 된다.

그래서 필요한 내용을 설치하여 import 하여 사용 하면 된다 🙂

 

하지만 db 정보가 소스에 삽입되어 있는 것은 좋지 못하기 때문에 YAML 형식의 문서로 config 파일을 생성하고

그 config 파일을 python 에서 읽어서 DB 접속을 해야 한다. (json 은 시인성이 좋지만 주석을 첨부 할 수 없고/xml은 시인성이 너무 떨어진다.)

 

 

여담으로 python은 기본적으로 CentOS linux 에 대부분 설치되어 있으나 import 하는 pymysql 과 yaml은 설치 되어 있지 않기 때문에 아래와 같이 pip를 설치 하고 pip으로 설치 한다..

 

YAML의 경우 python 혼자만 쓰는 설정파일일 경우 info.py 를 만들고 import 하는게 편하지만 다른 언어의 프로그램 이나 로직과 겸용해야 할때 필요하겠지..