클라우드 원격 서버(EC2)에서 주기적으로 데이터를 처리하는 방법을 소개한다.

카카오톡 챗봇 데이터를 처리하기 위해서는 매일 밤 아티스트 데이터를 Amazon S3에 밀어넣는 배치 작업 이 필요하다. 리눅스 crontab을 이용하여 반복되는 작업을 자동화할 수 있다. 리눅스 머신으로는 Amazon EC2를 이용했다. AWS 프리티어 범위 안에서 사용할 수 있다.

이번 글에서는 다음 내용을 다룰 것이다. EC2 대신 다른 환경(로컬에서 우분투 등)에서 crontab을 이용한다면, 두 번째 내용만 보면 된다.

다음 내용은 다루지 않을 것이다.



EC2 환경 설정

EC2 인스턴스를 생성하고 인스턴스 페이지로 가면, 페이지 하단에 퍼블릭 DNS 를 확인할 수 있다. EC2에 접근하는 주소 역할을 하며, 다음과 같은 형식이다.

  • ec2-{고유 주소}.ap-northeast-2.compute.amazonaws.com

터미널에 아래와 같이 입력하여 EC2 환경으로 들어간다. key-pair.pem 파일은 EC2 접속에 필요한 접근 권한 정보를 담고 있다. AWS 공식 문서에 키 페어 생성 방법이 나와 있다.

ssh -i key-pair.pem ec2-user@{퍼블릭 DNS}

초기 EC2 환경에는 python3, pip3 등 필요한 라이브러리들이 들어 있지 않다. 기본적으로 python2는 제공되어 있지만, 대부분의 사용자는 python3를 사용할 것이다. 따라서 기본적인 것들을 설치해야 한다. 여기서는 안정화된 버전인 python 3.6을 설치하겠다.


python 설치

  • sudo yum list | grep python
  • sudo yum install python36
  • python3를 실행하여 설치됐는지 확인 후, quit()으로 빠져 나오기


pip 설치

python을 설치했다고 pip를 바로 이용할 수 없기 때문에, 별도의 과정이 필요하다.

  • curl -O https://bootstrap.pypa.io/get-pip.py
    • 숫자 0이 아닌 알파벳 대문자 O임
  • python3 get-pip.py


필요한 python 라이브러리 설치

EC2 환경은 로컬 환경과 다르다. python 언어만 설치한 상태이기 때문에, pip를 이용하여 필요한 라이브러리들을 설치해야 한다.

  • pip3 install boto3 --user
  • pip3 install requests --user
  • 등등 필요한 라이브러리 설치


AWS configure

터미널에서 AWS 서비스 커맨드를 실행하기 위해, 계정 정보를 설정해 주어야 한다.

먼저 AWS IAM으로 들어가 왼쪽 메뉴에 있는 사용자 를 클릭한다. 등록된 사용자 목록을 확인할 수 있다.

20200709-1-iam

configure할 계정 이름을 클릭하고, 보안 자격 증명 탭으로 들어가면, 액세스 키 만들기 버튼을 눌러 액세스 키를 발급한다.

20200709-2-iam2

  • 이전에 발급했다면 그 키를 써도 된다. 다만 그 때 발급한 키를 적어 두지 않았을 경우, AWS_ACCESS_KEY_ID는 IAM에서 확인할 수 있지만 AWS_SECRET_ACCESS_KEY는 확인할 수 없다.

이제 터미널에서 aws configure를 입력하여 발급한 키 정보를 입력한다.

  • Default region name은 사용하고 있는 AWS region 이름을 입력하면 된다. 나는 ap-northeast-2(서울 리전)이다.
  • Default output format은 엔터로 넘어가도 된다.

입력한 정보는 aws configure list로 확인할 수 있다.



crontab을 이용한 배치 작업

crontab 개요

crontab은 특정 시간이나 날짜를 설정하여, 반복되는 작업을 자동화할 수 있다. 나는 데이터를 Amazon S3에 밀어넣을 것인데, 해당 내용은 python 스크립트로 미리 작성해 두었다. 필요한 작업을 python3 {파일 이름}으로 매번 실행하지 않아도 된다.

crontab의 기본적인 문법은 다음과 같다.

* * * * * {명령어}

5개의 *은 각각 분(0-59), 시간(0-23), 일(1-31), 월(1-12), 요일(0-6, 일요일이 0)을 나타낸다.

예시를 살펴보자.

0 16 * * * /usr/bin/python3 /home/ec2-user/ttandaudio_to_s3.py
  • 매일 16시 0분에 python3/home/ec2-user/ttandaudio_to_s3.py 파일을 실행한다.
*/5 1,2,3 * * * /usr/bin/python3 /home/ec2-user/ttandaudio_to_s3.py
  • 분에서 5로 나눈 것은 60을 5로 나눈 시점, 즉 00, 12, 24, 36, 48분을 의미한다. 매일 1,2,3시 00, 12, 24, 36, 48분에 파일을 실행한다.

더 자세한 내용은 Crontab – Quick Reference를 참조하길 바란다.


crontab 실습

로컬 디렉토리에서 시작한다. 먼저 로컬에 있는 파일을 EC2로 복사한다. 터미널에 아래와 같이 입력하면 된다.

scp -i key-pair.pem ttandaudio_to_s3.py ec2-user@{퍼블릭 DNS}:~/
  • ttandaudio_to_s3.py 파일을 EC2의 ~/ 위치에 복사하는 명령이다.


EC2로 들어간다.

ssh -i key-pair.pem ec2-user@{퍼블릭 DNS}


EC2 현재 디렉토리를 확인한다.

  • pwd
    • /home/ec2-user 일 것이다. ~/ 위치와 같다.
  • which python3
    • /usr/bin/python3 일 것이다.


이제 crontab 서비스를 시작하고 작업을 지정한다.

  • sudo service crond start: 서비스 시작
  • crontab -e: vi로 들어오게 된다. 위의 crontab 문법대로 작업을 지정하면 된다.

여기서 주의할 점 2개가 있다.

  • 시간의 경우 UTC 기준 이다. 한국은 UTC+9이기 때문에, UTC 기준으로는 한국 시간에 9시간을 빼야 한다. 나는 아래와 같이 설정해 두었다. 매일 새벽 1시(16 + 9 = 25)에 python3로 /home/ec2-user/ttandaudio_to_s3.py 파일을 실행하는 것이다.
0 16 * * * /usr/bin/python3 /home/ec2-user/ttandaudio_to_s3.py
  • EC2에서의 python3는 기본적으로 UTF-8 인코딩을 지원하지 않는 것 같다. 즉, python 코드에서 한글 주석이 들어가면 SyntaxError: Non-ASCII Character 오류가 난다. 따라서 코드의 최상단에 다음과 같이 써 주어야 한다. # 주석을 포함해야 한다.
# -*- coding: utf-8 -*-

crontab 명령을 설정했으면, crontab -l로 현재 적용된 작업을 확인할 수 있다. 작업을 취소하려면 다시 crontab -e로 들어가 해당 작업을 지우거나, 해당 행 앞에 #로 주석 처리하면 된다.


작업 완료 확인

설정한 작업이 정상적으로 완료됐는지 확인하려면, 완료될 만한 시점에 EC2 터미널에서 아무 명령어나 입력한다. 명령어 실행 결과와 함께, 아래와 같이 메일이 왔다는 메시지가 뜬다.

You have new mail in /var/spool/mail/ec2-user

가만히 있으면 터미널에 뜨는 게 아니고, 어떤 명령어를 실행해야 그 결과와 함께 뜬다. vi /var/spool/mail/ec2-user를 입력하여 메일을 확인한다. 정상적으로 실행되었을 경우, 해당 python 파일의 실행 결과를 확인할 수 있다!

...
X-Cron-Env: <LANG=en_US.UTF-8>
X-Cron-Env: <SHELL=/bin/sh>
X-Cron-Env: <HOME=/home/ec2-user>
X-Cron-Env: <PATH=/usr/bin:/bin>
X-Cron-Env: <LOGNAME=ec2-user>
X-Cron-Env: <USER=ec2-user>

{python 출력 결과}



마무리하며

데이터 엔지니어링의 핵심은 반복되는 데이터 작업을 배치 처리를 통해 자동화하는 데에 있는 것 같다. 사용자의 액션이 있을 때 필요한 실시간 처리와, 이 글에서 다룬 배치 처리를 적절히 활용하여 서비스를 개발하는 연습을 지속적으로 해야겠다.



참고 문서