현재 모 스타트업 기업에서 인턴을 하고 있다. 이곳에서, 기업들의 각종 데이터를 지정해둔 사이트들에서 크롤링해서 사용자에게 보여 주는 웹 서비스를 제작하고 있다. 중요한 건, 크롤링에 필요한 정보들이 수시로 변해서, 이 정보를 유동적으로 수정하고, 삭제하고, 지정할 수 있어야 했다. 처음에는 데이터베이스를 통해 이 정보를 취급하려고 했었다.

 하지만, 이렇게 하기엔 문제가 있었다.

 

 

1. 이 서비스가 운영될 환경엔 전문 개발자가 없다. 따라서 DB에 대한 지식이 없는 관리자가 쉽게 데이터에 접근하고 수정할 수 있어야 하고, 그런 의미에서 DBMS를 통해 접속해서 데이터를 관리하는 건 부적절하다.

 

2. 그럼, 미리 데이터에 대한 질의나 수정 등 가능한 명령사항들을 래핑해서 일반적인 관리자들(DB에 대한 지식이 없는)이 이용 가능한 서비스로 만들 수도 있다. 하지만, 이 방법은 서비스의 규모나 가용 자원에 비해 너무 큰 작업이라고 생각했다.

 

 

 이러한 사유로 DB를 사용하는 건 포기했다. 대신, 나는 다른 점을 주목했다.

 

1. 여러 가지 정보를 크롤링하는데, 그 중 가장 자주 일어나는 크롤링도 겨우 일 1회이다. 데이터 특성상 실시간으로 모을 필요는 없었다.

 

2. 기업의 정보는 생각보다 자주 바뀐다. 따라서 수정 작업이 빈번할 것이다. 또한, 단순히 크롤링을 위한 URL 데이터 뿐만 아니라, 기업에 대한 다른 데이터들도 저장하고 있었고, 이 데이터들은 정해진 형식이 있는 경우가 많다.

 

 

 

 그래서, 나는 마땅한 대안을 찾다가 구글 스프레드시트를 주목했고, 읽기/쓰기 관련 API도 있다는 걸 알게 되고 데이터 저장을 위해 구글 스프레드시트를 사용하기로 결정했다. 

 

 

 혹시 오해할까봐 미리 적자면, '크롤링 할 대상에 대한 정보'를 구글 스프레드시트에 저장하는 것이고, '크롤링 한 결과'는 최소 수만 단위니까 당연히 DB에 저장했다. 구글 스프레드시트 입출력이 당연히 DBMS보다는 CRUD 관련 성능이 좋지 않다. 당장 사내에서 사용하는 시트 15개 X 시트당 약 5천행씩 존재하는 스프레드시트도 열 때마다 로딩을 몇초씩 기다려야 한다. 그러니까, 아래 방법은 데이터가 수백~수천 개 단위로, 비교적 크지 않을 떄만 활용할 수 있는 방법이다.

 

 

 

1. 스프레드시트 준비

 

 이 부분은 따로 설명이 필요 없을 것 같다. 다만, 공개 데이터가 아니니까 당연히 비공개 스프레드시트로 하고 권한도 적절히 설정한다. 이 부분이 스프레드시트를 사용할 때 큰 장점중 하나라고 생각한다. 사용자에게 수정/열람/공개 권한 등을 손쉽게 설정할 수 있다. 

 

 

2. API 사용 준비

 

 

 일단 결론부터 미리 설명하자면, 이런식으로 스프레드시트 공유자에 봇이 추가되도록 하는 게 목표다. 그러려면 우선 구글 API를 사용할 수 있도록 준비해야 하는데, https://console.developers.google.com/apis에 들어간다.

 

 

 

 나는 현재 프로젝트가 하나 있기에, 지금 보이는 화면과 조금 다를텐데, 맨 위의 google APIs 옆에 아마 '프로젝트 없음'으로 뜰 것이다. 그걸 누르면 사진과 같이 프로젝트 선택이 뜨는데, 나는 만들어 뒀던 게 있어서 기존 프로젝트가 뜨지만, 아마 아무 것도 없을 것이다. 이제 새 프로젝트를 눌러서 프로젝트를 만들면 된다. 이 이후엔 읽어보고 특별한 사항이 없다 싶으면 예스맨 하면 된다.

 

 

 

 

 

 이제 프로젝트가 만들어졌고, 구글 스프레드시트 API를 사용하도록 설정해야 한다. 하라는 대로 API 및 서비스 사용 설정을 누르자. 그러면 크롬 웹스토어랑 비슷한 화면이 뜰 텐데 검색창에 sheet만 쳐도 아래와 같은 API가 나올 것이다.

 

 

 

 

 

 사용 설정 버튼을 누르면 된다.

 

 

 그러면 이 화면이 뜰 텐데, 아직 이 상태론 사용할 수 없다. 내가 누구인지 확인하기 위해 사용자 인증 정보를 만들어야 한다. 친절하게 만들라고 위에 버튼까지 띄워줬으니 만들러 가자.

 

 

 

 

다음과 같은 화면이 뜰 텐데, 내가 썼던 방법을 소개하자면 나머지는 무시하고 위에서 '서비스 계정' 링크를 클릭한다.

 

 

 

 

서비스 계정이 당연히 없을 것이다. '서비스 계정 만들기'를 클릭한다.

 

 

 

원하는 대로 서비스 계정 이름과 설명을 넣는다. ID는 자동으로 만들어진다.

 

 

 

 

계정 권한은 다음과 같이 준다. '프로젝트-편집자'를 택했다. 사실 이 부분이 효과가 있는지는 모르겠는데, 혹시 몰라서 일단 줬다. 읽기 권한만 필요하면 뷰어만 줘도 될 것이다. (요 부분은 정확히 아시는분이 있으면 댓글 부탁드리겠습니다..)

 

 

 

 마지막으로 밑의 '키 만들기'를 누른다. JSON 형식으로 저장하면 된다. 이 키를 이용하여, 스프레드시트에 엑세스 할 것이다. 매우 중요한 파일이고 복구가 되지 않으므로 분실하지 않도록 함은 물론이고, 유출되지도 않아야 한다. 그래서 git을 사용해 관리할 땐, private 레포가 아니라면 꼭 이 파일은 ignore 해주자. 처음 생성하면 이름이 매우 길고 쓰기 힘드므로 적당히 UserKey.json 정도의 이름으로 바꿔주자.

 

 

 마지막으로, 스프레드시트에 해당 서비스 계정의 이메일을 스프레드시트에 공유 설정하자. 권한은 해당 봇이 사용할 만큼 주면 된다. 해당 이메일은 서비스 계정 탭에서도 볼 수 있고, 잘 모르겠다면 방금 받은 json 파일의 'client-email' 항목에 있다.

 

 

 

 이제 사용 준비가 완료되었다.

 

import gspread, os
from oauth2client.service_account import ServiceAccountCredentials

# 구글 API 사용을 위한 상수들
scope = ['https://spreadsheets.google.com/feeds',
         'https://www.googleapis.com/auth/drive']
key_file_name = 'UserKey.json' # 아까 받은 json 인증키 파일 경로가 들어가면 됨.

credentials = ServiceAccountCredentials.from_json_keyfile_name(key_file_name, scope)
spreadsheet = gspread.authorize(credentials).open("<스프레드시트 이름>")

pip install gspread, oauth2client 를 통해 필요한 라이브러리를 설치한다.

이제 spreadsheet를 통해 원하는 대로 조작하면 된다.

 

 

3. API 활용하기

 

 스프레드시트 API에 대해서는 구글 API 문서나 다른 블로거분들의 훌륭한 글이 많아서 따로 언급하진 않지만, 사용에 주의사항이 있다.

 

 

 구글 Sheet API 무료 이용 한도이다. 기본적으로는 무제한이지만, 개인당 매 100초당 100회, 즉 초당 1개씩꼴의 요청만 보낼 수 있다. 즉, loop문 속에서 셀 하나씩 가져오는 식으로 코딩하면 바로 한도에 걸린다. 따라서, 다음과 같은 식으로 코딩해야 한다.

 

    worksheet = spreadsheet.worksheet('<해당 시트 이름>')
    
    product_url_list = worksheet.col_values(3)
    product_code_list = worksheet.col_values(4)

    product_url_list = product_url_list[2:-1] # 필요한 만큼 가공
    product_code_list = product_code_list[2:-1] # 필요한 만큼 가공

    return list(zip(product_url_list, product_code_list))

 

 

 내가 사용했던 시트의 경우 단순화하면 이런 내용이었다.

데이터 목록
코드 바코드
81048 810483
82069 820697
... ...
합계 데이터 행

 나는 코드와 바코드 데이터만 필요하고, 데이터 목록이나 합계 같은건 필요없었다.  col_values(n) 같은 경우엔 해당하는 n열의 데이터를 모두 가져온다. 따라서 요청 한번으로 해당 열의 정보를 모두 가져오고, slicing을 통해 필요없는 데이터를 쳐냈다. 위의 경우엔 앞의 2행과 마지막 1행이 필요가 없으니 [2:-1] 을 통해 간단하게 가공했다. 지금 같은 경우는 간단한 경우고, 복잡한 처리가 필요할 땐 slicing하는 부분에 함수를 각각 따로 만들어서 처리하는 부분을 만들면 된다. 마지막엔 열 단위로 나눈 데이터를 다시 묶었다. 위의 경우엔 [('81048', '810483'), ('82069','820697'), ...] 과 같은 식으로 반환될 것이다.

 

 

 

4. 스프레드시트 사용의 장점 및 단점

 

 위에서도 언급했다시피 데이터 수정과 열람, 삭제가 자유로움은 물론, 데이터 형식을 강제하여 규칙성을 유지할 수 있고, 필요한 최소한의 열만을 입력할 수 있다. 한 가지 내가 겪은 사례를 들자면, 나는 어떤 열에 숫자가 들어가되, 무조건 6자리로 들어가도록 해야 한다. 13이 들어가도 000013 이런식으로 들어가야 한다. 이것을 스프레드시트에서 서식 -> 숫자 -> 추가 형식에서 직접 지정을 했다.

위와 같이 지정하면 그냥 13을 입력해도 000013 과 같은 식으로 자동으로 0을 채워준다.

 

 

 엑셀 함수 역시 활용할 수 있는데, 예를 들어 이 함수를 통해 해당 셀을 참고하여, 옆 셀이 비었으면 '비상장', 빈 셀이 아니라면 '상장사'를 자동으로 입력한다. 이런 식으로 함수를 활용하면 사용자가 직접 타이핑할 데이터를 줄일 수 있다. 사용자의 부담이 줄어듬은 물론이고, 예기치 못한 오타 역시 방지할 수 있다. 이외에도 특정 열에 중복을 허용하지 않도록 함으로서, 기본 키의 역할을 하도록 할 수도 있다.

 

 

 

 다만, 이러한 스프레드시트를 통한 DB의 대체는, 데이터 읽기가 겨우 일 1회만 일어날 정도로 드물고, 데이터의 양이 수천 행 정도로 비교적 적었기에 가능했다. 실제로 데이터의 실시간 반영에 대해서도 많이 고민했는데, 결국 스프레드시트의 한계를 인정하고, 새벽 시간에만 데이터를 한꺼번에 받아와서 읽도록 했다. 

 

 

 최종적으로 완성한 시스템의 구조는, 스프레드시트의 데이터를 새벽 2시에 한꺼번에 읽어와서 서버의 DB에 기존 테이블을 삭제한 후 새로 받은 데이터를 넣고(이 과정이 행 500개 기준으로 10초 조금 안되게 걸린다.), 그 데이터를 기반으로 크롤링을 하도록 했다. 기존 테이블을 삭제하는 이유는, 엑셀에서 어떤 데이터가 변경되거나 삭제되었는지 아는 방법이 까다롭고, 매 행을 대조하는 식으로 억지로 구현할 바에는 그냥 매번 데이터를 새로 받아 쓰는 게 차라리 더 편했기 때문이다. 큰 데이터에 적합하지 않은 이유는 이러한 까닭도 있다.

 

 

 마지막으로, 사용자가 엑셀에 대해 잘 모르면 효율이 떨어질 것이다. 함수나 서식 지정 같은 요소를 모르면 위처럼 데이터의 형식성을 강제할 수 없고, 결국 타이핑하는 사람에게 맡겨야 할 수밖에 없으니..

 

 

5. 결론

 

 사실 처음 이 프로젝트에 대해 들었을 땐 이런 방법을 쓰리라곤 상상도 못했다. 사실 이 방법이 다루는 데이터가 많아야 수만~수십만 개 수준인 소규모 프로젝트라 가능했겠지만, 그래도 꽤나 재미있는 발상으로 극복해 낸 것 같다. 그래도 스프레드시트와 DB를 동시에 사용하면서, DB의 장점과 단점을 동시에 경험해 볼 수 있는 기회였다.

 heidisql 등의 원격 접속 툴을 이용해도 접속이 안 됐다. 포트, 방화벽 설정 등등 모두 확인해 봤고 로컬에서 잘 돌아가는 데도 원격 접속이 안됐다. 사실 원격 접속만 안 되면 상관 없는데, codeigniter에서도 똑같이 로그인을 못해서 자꾸 에러가 났었다.

 

 일단, MariaDB는 10.4부터 root 권한 소유자에게 따로 비밀번호를 물어보지 않는다. 즉, 루트 계정으로 로그인했으면 그냥 콘솔에 mysql 치면 접속이 된다. 물론 다른 유저는 전처럼 비밀번호를 물어본다. 나는 이 root 계정으로 로그인을 며칠째 계속 시도해 봤는데 계속 안됐다.... 포트 문제도 아니었고 딱히 통신 문제도 아니었다. 심지어 SSH 접속 계정도 root 였다.

 

해답은 새로운 계정을 파서, 그 계정으로 접속을 하니까 잘 됐다. 계정 만드는 SQL 문이야 검색하면 바로 나올 거니까 따로 적진 않겠다.사실 별 내용 없는 건 아는데 새 계정을 파서 시도하란 말을 며칠 내내 구글을 뒤진 다음에야 본 것 같아서, 혹시 같은 어려움을 겪는 사람들이 있다면 빨리 해결할 수 있었으면 좋겠다. 

  EC2 프리 티어를 사용하는 사람이라면, 월 750시간의 t2.micro가 제공되는데 한 달 내내 쉬지 않고 돌려도 750시간을 다 못 쓴다. 그래서 그냥 켜놓고 방치하는 사람이 많고, 나 역시 그런 사람들 중 한명이다. 하지만, 프리 티어를 벗어나게 되면, EC2 인스턴스를 켜 놓은 시간에 비례하여 과금이 되기 때문에 최대한 안 쓸때는 꺼 놓는 게 현명하다. 특히 회사에서 운용하는 개발 서버 같은 경우, 주말에도 짬을 내서 개발을 하거나 야근을 하는 게 아니라면 출근 시간에 맞춰서 켜지고, 퇴근 시간에 맞춰서 끄는 게 현명하다.

 

 

 하지만, EC2 인스턴스가 그냥 크롬 탭 끄고 켜듯이 바로바로 껐다 켜지지도 않고, 무엇보다 이걸 매일 하려면 당연히 귀찮다. 그래서, 아마존에서 Instance Scheduler라는 솔루션을 내놓았다. 이 기능을 활용하여 정해진 시간, 정해진 요일에 인스턴스를 껐다 켰다 하는 작업을 자동화할 수 있다.

https://aws.amazon.com/ko/about-aws/whats-new/2018/02/introducing-the-aws-instance-scheduler/

 

AWS Instance Scheduler 소개

AWS Instance Scheduler는 고객이 Amazon EC2 및 Amazon RDS 인스턴스의 맞춤형 시작 및 중지 스케줄을 손쉽게 구성할 수 있는 솔루션입니다. 이 솔루션은 간편하게 배포할 수 있고 개발 환경과 운영 환경의 운영 비용을 절감하는 데 유용합니다. 정규 업무 시간에 이 솔루션을 사용하여 인스턴스를 실행하는 고객은 해당 인스턴스를 하루 24시간 실행하는 고객과 비교해 비용을 최대 70% 절감할 수 있습니다.

aws.amazon.com

AWS Instance Scheduler 의 구성도

 

 요금은 일단 프리 티어의 이용자라면 무료라고 봐도 좋다. AWS의 CloudFormation과, 위 사진처럼 AWS의 lambda, CloudWatch, DynamoDB 등을 활용하는 서비스인데, 이 서비스들 모두 프리 티어에서 일정량의 처리량을 무료로 제공하기 때문이다. 물론, 학생 수준에서 공부용으로 이용하는 정도로는 차고 넘치는 정도로 용량을 제공한다. 자세한 요금은 위의 각 제품의 요금을 확인하자. 전부 친절하게 계산기까지 구비되어 있다. 

 

 

 크게 3단계로 나뉘어져 있는데, 차례차례 내가 했던 방법대로 설명하겠다.

 

참고 자료 : https://www.contentbloom.com/using-aws-instance-scheduler-to-manage-ec2/

https://medium.com/@ahmeeddhon/using-aws-instance-scheduler-to-reduce-amazon-ec2-or-rds-cost-56c9eb374344

 

 이 글은 위의 두 링크에 나온 방법과 시행착오를 통해 이뤄낸 방법을 기록해 뒀으며, 혹시 이 글대로 했을때 문제가 생기면 위의 링크들을 참고하자. 

 

1. CloudFormation에서 Stack 생성

 

 AWS CloudFormation은 클라우드 환경에서 AWS나 타사의 애플리케이션을 조작하고 제어...한다는데 솔직히 어떻게 쓰는 지는 잘 감이 안 잡힌다. 내가 이해한 바로는, 쉽게 말해 여러 개의 애플리케이션을 조작해야 하는 업무를 한꺼번에 스크립트를 통해 할 수 있도록 만들어주는 솔루션 같다. 

 

https://aws.amazon.com/ko/premiumsupport/knowledge-center/stop-start-instance-scheduler/

 

AWS 인스턴스 스케줄러 및 AWS CloudFormation을 사용하여 인스턴스 중지 및 시작

참고: DynamoDB 콘솔 또는 AWS CloudFormation 사용자 지정 리소스를 사용하여 기간을 생성할 수도 있습니다. us-west-2는 해당하는 AWS 리전으로 바꿉니다. 기간에 대한 자세한 내용은 시작 및 중지 시간을 참조하십시오. 2.    DynamoDB 콘솔을 엽니다. 3.    [테이블]을 선택한 후 구성 테이블을 선택합니다. 참고: AWS Instance Scheduler 템플릿은 상태 테이블과 구성 테이블이라는 2개의 Dynamo

aws.amazon.com

 

 일단 AWS에서 공식적으로 제공하는 설치 방법이다. 그런데, 이 방법대로 하면 나중에 CLI를 조작해야 해서 어려우면서도 귀찮고 중요한 걸 안 알려줘서 처음에 이대로 하다가 좀 애먹었다. 그래서 위의 참고 자료에 나온 영문 링크를 참고해서 작업했다.

 

 일단 지역을 확인한다. EC2의 리전이 서울이었으면 당연히 서울로 하는 게 좋을 것이다. 지역 세팅을 확인했으면 이제 CloudFormation 에 가서 스택 생성을 누른다. 

 

 

 

 

 

 

복붙할 URL은 아래에 준비되어 있다.

https://s3.amazonaws.com/solutions-reference/aws-instance-scheduler/latest/instance-scheduler.template

 

다음을 누른다. 스택 이름을 입력하라는 데 이 값이 나중에 EC2 설정에 쓰이니, 잘 알아볼 수 있는 이름으로 짓자.

 

 

 

 

EC2를 쓴다면 당연히 서비스할 대상으로 EC2를 지정한다.

 

 나는 Schedule이라는 이름으로 지었다. 

이외에도 아래에 이것저것 엄청 많은데 다 건드리지 않아도 되고, 중요한 건 몇 군데 정도다.

 

 

 

 

 

 

영어로 각 항목에 대한 설명이 있으니 딱히 부연 설명은 하지 않아도 될 것이다.

 

 

 

 

 

 

 이 값은 우리의 스케쥴러가 몇 분마다 돌아갈지를 결정한다. 나는 하루에 한 번만 정해진 시간에 인스턴스를 끄도록 만들었기 때문에 30분으로 정했다. 사실 하루에 언제 끄고 언제 켜는지만 정해두는 정도면 10분 이하의 Frequency는 필요하지 않을 것이다. 오히려 너무 간격이 짧으면 그 만큼 lambda 등의 서비스에 트래픽이 많이 생길 것이다.

 

 

 

 

 

맨 아래에 있는 항목들은 다음과 같이 입력해 두자.

 

이제 다음 다음 하다보면 마지막 페이지에 다음과 같은 문구가 보일 것이다.

 

 

 

 

 여기는 체크를 하자. 쉽게 말해, 클라우드를 통한 접근 권한을 주는 것이라고 보면 된다. 

여기까지 하고 스택을 생성하자. 이 스택 생성도 시간이 걸리기 때문에 좀 기다려야 한다.

대시 보드에서 CREATE_COMPLETE라고 뜨면 생성이 완료된 것이다.

 

 

 

 

2. AWS DynamoDB 에서 설정 생성

 

 이제 기본적인 준비는 마쳤고, 원하는 대로 세팅을 할 차례다. 이미 템플릿을 통해 lambda에도 못 보던 애플리케이션이 생겼을 것이고, DynamoDB도 마찬가지다. DynamoDB는 아마존에서 서비스하는 NoSQL DB인데, 여기에 설정값들이 저장되고 이 값을 fetch해서 스케쥴러로 이용하는 구조다. DynamoDB로 들어가 보자.

 

 

 

 

 다음과 같이 테이블 탭을 눌러보면 처음 보는 테이블들이 만들어져 있다. Ec2instanceScheduler는 내가 스택 이름으로 지은 거고, 아마 사람마다 다른 이름이 있을 것이다. 중요한 건 뒤의 ConfigTable과 StateTable이다. StateTable은 함부로 바꾸면 안 되고, 우리는 ConfigTable만 건드리면 된다.

 

ConfigTable을 열어보면 이미 여러 개의 항목들이 예시로 만들어져 있을 것이다. 각 항목들은 json의 구조와 거의 동일하다. type에 config/schedule/period가 각각 있는데, 나중에 열어보면 알겠지만 간단히 설명하자면, schedule 항목에서 기본적인 스케쥴 설정(각종 설정들)을 하고, 시간을 지정하는 항목을  따로 항목으로 분리하여 둔 것이다. 즉, schedule 타입의 항목에서 period 행을 이름을 통해 참조하는 형식이 된다.

 

 config 행은 건들 필요 없고, 나머지 schedule/period type의 행들은 삭제하자. 다 삭제하면 config 타입의 행 하나만 남을 것이다. 이제 우리가 원하는 대로 설정을 할 차례다. '항목 만들기'를 누르자.

 

 

 

 

처음 창을 열면 이 형태로 나와있진 않을 것이다. Tree->Text로 바꿔주고 DynamoDB JSON에도 체크해주자.

 

period 항목을 생성한다. 이제 원하는 대로 설정을 할 차롄데, 각 파라미터는 다음과 같다.

나는 내가 필요한 항목만 적었으니, https://docs.aws.amazon.com/solutions/latest/instance-scheduler/components.html 여기 공식 문서의 Period Definitions를 참고하자. 나보다 훨씬 자세하게 잘 써놓았다.

 

- description : 항목에 대한 설명. 필수는 아니지만 써 놓아서 나쁠건 없다.

- type : 말 그대로 아까 말한 period,config,schedule 등을 지정하는 건데 우리는 period 항목을 만드는 거니 이대로 한다.

- name : 항목의 이름이다. 임의로 하면 되지만, 이걸 Schedule 항목에서 다시 불러와야 한다는 걸 생각하면서 만들자.

나는 office-hours로 이름지었다.

- weekdays : 어떤 요일에 적용할지 지정할 수 있다. mon#1 과 같이 지정할 수도 있는데, 이 경우엔 그 달의 첫 번째 월요일이라는 의미다. 자세한 내용은 위의 문서를 참조하자.

- monthdays : 나는 지정하지 않았는데, 한 달중 특정한 날짜를 지정할 수 있따. 1-3 이면 매달 1일,2일,3일을 의미하는 식이다. 역시 조금 복잡하니 문서를 참조하자.

- begintime, endtime : 인스턴스를 시작할 시간, 종료할 시간을 hh:mm 의 형식으로 지정한다. 나는 begintime을 지정하지 않았는데, 사용하고 싶다면 endtime 항목을 그대로 복사해서 이름만 바꿔서 쓰면 된다.

 

- 참고로, "S" 나 "SS" 등은 자료형을 나타낸다. DynamoDB JSON만의 형식인 것 같다.

 

나는 인스턴스를 켜는 시간은 딱히 지정하지 않고 끄는 시간만 사진과 같이 19:30분으로 지정했다.

https://docs.aws.amazon.com/solutions/latest/instance-scheduler/appendix-e.html 에 다양한 예시가 있으니, 내가 언급한 이외의 스케쥴을 사용할 사람들이라면 참고해 보자.

 

 귀찮은 사람은 아래 코드를 복붙해서 원하는 대로 변형해서 사용하면 될 것이다. 아래의 경우엔 시작 시간으로 8:30분, 종료 시간으로 19:30을 지정한 것이다.

{
  "description": {
    "S": "Shut-down period. Daily (end of the day)."
  },
  "endtime": {
    "S": "19:30"
  },

  "begintime": {
    "S": "08:30"
  },
  "name": {
    "S": "office-hours"
  },
  "type": {
    "S": "period"
  },
  "weekdays": {
    "SS": [
      "mon-sun"
    ]
  }
}

 

이대로 저장하고, 이제 다시 새로운 항목을 만들자.

 

이번엔 아래와 같다.

 

{
  "description": {
    "S": "worktime"
  },
  "enforced": {
    "S": "false"
  },
  "name": {
    "S": "autostop"
  },
  "periods": {
    "SS": [
      "office-hours"
    ]
  },
  "retain_running": {
    "S": "false"
  },
  "stop_new_instances": {
    "S": "true"
  },
  "timezone": {
    "S": "Asia/Seoul"
  },
  "type": {
    "S": "schedule"
  }
}

 

 여기는 주로 설정값이 모여있다. type이나 description은 위에서 언급했고, timezone 역시 서울 리전이라면 다음과 같이 설정한다. retain_running이나 stop_new_instances 등등은 특수한 설정이다. 예를 들어, retain_running은 인스턴스가 예정된 종료 시간 이후로 사용자가 임의로 다시 시작했을 떄, 이 실행을 막을지를 설정하는 여부이다. 이 각각의 설정값에 대한 설명은 역시 아까 언급한 https://docs.aws.amazon.com/solutions/latest/instance-scheduler/components.html

-> Schedule Definitions에 자세하게 설명되어 있으니 참고하자.

 

 중요한 곳은 periods랑 name이다. periods에 office-hours라고 되어 있는데, 이건 아까 내가 정의했던 period 항목의 이름이다. 혹시 다른 이름을 썼다면 이 부분은 그걸로 바꿔주자. name은 인스턴스에서 스케쥴을 설정할 때 이 이름을 쓰게 되니까 잘 지어주자. 나는 autostop이라고 지었다. 자동으로 인스턴스를 중지해 주니까!

 

 역시 위 코드를 본인 필요한 대로 잘 지지고 볶아서 저장한다.

 

 

 

 

3. 인스턴스에 설정한 스케쥴 적용하기

 

 이제 거의 끝났다. EC2 -> 인스턴스 로 들어간다. 대시보드에 들어가자.

 

 

 

 

 결론적으로 만들어지는 결과값은 다음과 같다. 태그는 키:값으로 이루어져 있는데, 키에는 위에서 입력했던 CloudFormation의 스택 이름, 값에는 아까 dynamoDB에서 만들었던 schedule 항목의 이름으로 해 주자! 헷갈릴거 같아서 내가 지었던 이름엔 위에서 모두 밑줄을 쳐 놨으니 참고하자. 태그를 추가하는 방법은 일단 만들어진 인스턴스를 아무거나 눌러보자.

 

 

 

 

태그 창에 가서 태그 추가/편집을 누르면 UI가 직관적이라 금방 수정이 가능할 것이다.

 

 

 

 사실 다 하고 보면 별 게 아닌데, 나 같은 학생이나 AWS에 갓 입문한 사람이라면 난생 처음 들어보는 서비스 여러 개를 서로 상호작용 하도록 만드는 거라 좀 복잡해 보인다. 그래도, 막상 해보니까 그냥 생소한 게 많아서 그렇지 복잡한 로직이 아니고, 진짜 귀찮은 건 이미 AWS에서 만들어준 스크립트들이 알아서 해 주고 있기 때문에 비교적 편하게 할 수 있었던 것 같다. 

 

- 틀린 점이나 수정할 점은 언제든 댓글로 남겨 주시면 감사하겠습니다.

  일단 글을 읽기 전에, 이 문제는 정말 여러 가지 원인일 수 있다. 한 마디로 요약하자면 가장 가능성이 높은 요인은 CUDA랑 Cudnn 라이브러리를 제대로 못 불러온 건데, 이걸 못 불러오는 원인이 천차만별이다. 심지어 아예 안깔렸을수도 있고. 내 경우에는 다른 텍스트 에디터(주피터 노트북 등등)에서 import tensorflow로 구동을 확인했고, 오직 pycharm 18.2 버젼에서만 저 오류가 떴었다. 심지어 내장된 파이썬 콘솔에서도 오류 없이 정상 작동했었다. ㅡㅡ;

 

 

https://pythonkim.tistory.com/137

 

윈도우10 + 텐서플로 GPU 버전 설치

얼마만인지 모르겠다. 블로그에 올린 많은 글들 중에 나름 봐줬으면 하는 글들이 꽤 있는데 통계를 보면 우분투에 텐서플로 GPU 버전을 설치하는 글이 가장 인기가 많다. 왜 그런지는 모르겠다. 아직 그 부분이 해..

pythonkim.tistory.com

 

 일단 이 블로그를 참조하면 좋겠다. 정말 잘 쓰셨고 나도 이 블로그를 참조해서 구동했다.

CUDA,cuDnn을 깔고 환경 변수까지 제대로 설정하고, cmd든 vscode든 다른 에디터로 일단 구동을 확인하면 좋겠다.

밑에서 설명할 해결법은 일단 정상적으로 타 환경에서는 작동한다는 것을 전제로 하기에, 이 단계에서 막히면 여기서는 아마 답을 찾기 힘들 것이니 이 블로그를 끄고 열심히 구글에서 검색하는 게 빠를 것이다.

 

 

 그리고 이제 본인이 파이참을 쓴다면 파이참의 버젼을 확인해보자. 19.1 이하의 버젼이라면 새로 업데이트 해 주자.

19.7월 기준으로 19.2 버젼이 나와있다.

18.x ->19.x는 바로 업데이트가 안 되고 19.x 인스톨러를 실행해서 구버젼을 지우고 새로 설치하게 된다. 물론 내부 설정은 그대로 연동할 수 있다. 구버젼 삭제 때 slient uninstall에 체크하고, 새 버젼 설치 때 기존 설정 폴더(아마 자동으로 선택되어 있을 것)을 선택하면 그 설정 그대로 설치된다.

 

 

 설치가 끝나면 프로젝트를 열고, 설정값을 불러오도록 좀 기다린 후 문제가 됐던 파일을 다시 실행시켜보니 잘 됐다.

그럼 문제해결인데...

 

 

 왜 이런 문제가 생겼냐, 그건 구 버젼 파이참에서 버그가 있었기 때문이다.

conda 가상환경을 사용할 때, 시스템 환경변수 중 PATH의 값이 정상적으로 불러와지지 않는 문제가 있었다.

tensorflow-gpu는 환경변수를 통해 cuda 같은 관련 라이브러리의 위치를 불러오니, 당연히 관련 dll이 정상적으로 import 될 리가 없다.

 

 

참고:

https://youtrack.jetbrains.com/issue/PY-27234

 

PyCharm incorrectly set PATH after conda venv activation : PY-27234

To reproduce: *create conda environment with Python 3.5 *install cvxopt *try to open Python console and run import cvxopt *result: `ImportError: DLL load failed: The specified module could not be…

youtrack.jetbrains.com

 19.1 까지도 안된다는 댓글이 몇 보이는데, 19.2 버젼에서는 해결됐다고 하고 나 역시 19.2 버젼으로 해결했다.

 

 버젼업을 하지 않고 해결하는 법은 자세히는 설명하지 않겠지만, 시스템 환경변수에서 PATH의 값을 긁어와서 파이참의 프로젝트 실행환경 설정에서 환경 변수 값에 방금 긁은 값을 복붙해서 넣으면 된다.

 

 

 교훈:

뭔가 안될땐 실행 환경도 바꿔보자. ide 자체 버그일수도 있다.

 

 

 

해답 : pip install opencv_contrib_python 를 사용해 보자. 

 

1. pip install opencv_python 으로 설치 시 실행은 되지만 import 에러가 발생했다.

2. 직접 whl를 다운받은 후 pip를 통해 설치했을 때도 에러가 발생했다.

3. 아예 opencv 라이브러리를 통째로(대략 1기가) 받은 후, python 폴더 안의 pyd 파일을 찾아서

로컬 라이브러리 폴더에 넣었을 때도 에러가 떴었다.

 

 나는 위와 같은 시행착오를 거치고 해답을 얻었다.

주의할 점으론, opencv 라이브러리는 여러 가지 버젼이 있는데, namespace가 겹치기 때문에 반드시 하나의 버젼만 설치해야 한다. 여러 개가 설치되어 있다면 하나만 남기고 uninstall 해주자. 공식 문서의 맨 위에 있는 내용이다.

 

참고 : https://stackoverflow.com/questions/43184887/dll-load-failed-error-when-importing-cv2

파이썬 3.7 / windows 10 사용.

+ Recent posts