shinsj4653 / vs-data-portal-etl-demo

V사 데이터 포털의 DB 중앙 관리 시스템을 위한 Apache Airflow ETL 구축 실습

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

V사 DataPortal ETL-demo

V사 데이터 포털의 DB 중앙 관리 시스템을 위한 Apache Airflow ETL 구축 실습

데이터 포털의 메타 데이터 저장용 통합 DB 구축을 위해, Kafka 기반 CDC방식와 Airflow 기반 ETL을 고민함.

-> 실시간 데이터 변화에 대한 처리는 많지 않으므로, 일괄 처리 작업자동화 하는 방향으로 먼저 진행하는 것을 선택

-> 향후 데이터 스트리밍의 필요성이 커질 경우엔 Kafka를 도입할 예정

image

Demo ETL 파이프라인 구축 성공

목차

  1. Apache-Airflow
  2. Docker-Compose
  3. Windows 내에 Ubuntu 사용을 위한 WSL 구성
  4. Fetching docker-compose.yml & Run Docker-Compose
  5. sqlalchemy 기반 DAG 파일 생성
  6. Apache WebServer

Apache Airflow

시작에 앞서, Apache Airflow란 무엇인지 알아보고 가자.

Docker Compose

Windows 내에 Ubuntu 사용을 위한 WSL 구성

Docker Desktop 설치 후, 실행하려고 하는데 다음과 같은 에러 발생
image
Error : Docker Desktop requires a newer WSL kernel version

Docker Desktop requires a newer WSL kernel version.

다음과 같이 해결해주면 된다.

  1. Windows PowerShell 관리자 권한 실행

  2. 리눅스 서브 시스템 활성화

$ dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart
  1. 가상 머신 플랫폼 활성화
$ dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart
  1. Linux 커널 업데이트

https://wslstorestorage.blob.core.windows.net/wslblob/wsl_update_x64.msi
윗 링크를 통해 .msi 다운로드

  1. WSL 2를 default로 설정
$ wsl --set-default-version 2

Fetching docker-compose.yml & Run Docker-Compose

Airflow를 Docker Compose를 사용하여 배포하기 위해, docker-compose.yml 을 가져와서 실행해준다.

$ curl -LfO 'https://airflow.apache.org/docs/apache-airflow/2.7.2/docker-compose.yaml'

나 같은 경우, VSCode 내의 Bash 터미널을 사용하였다.

image bash 터미널을 활용하여 yaml 파일 가져와서 설치

docker-compose.yml & config 초기 설정

  1. example dag 파일들 삭제

예시 dag 파일들이 있지만, 너무 양이 많은 관계로 삭제해줬다.

AIRFLOW__CORE__LOAD_EXAMPLES: 'false'

docker-compose.yml 수정1

  1. timezone 수정

한국 시간대로 맞추기 위해 다음 옵션을 추가

AIRFLOW__CORE__DEFAULT_TIMEZONE: 'Asia/Seoul'

docker-compose.yml 수정 2

  1. airflow.cfg 수정

cfg 파일을 밖에서 원활하게 수정하기 위해 위에서 airflow.cfg 파일을 마운트하기로 하였다.

시스템 내부의 오리지널 cfg 파일은 /opt/airflow/airflow.cfg 에 위치하고 있으며, 이를 복사하여 로컬 환경 내의 config 폴더 안에 넣어줬다.

그 다음, airflow.cfg 파일 내의 default_timezone 값을 Asia/Seoul 로 수정하였다.

# Default timezone in case supplied date times are naive
# can be utc (default), system, or any IANA timezone string (e.g. Europe/Amsterdam)
#
# Variable: AIRFLOW__CORE__DEFAULT_TIMEZONE
#
default_timezone = Asia/Seoul

Initializing Environment

에어플로우 개발 전 환경 구성과 유저 권한을 세팅해야함

  1. 에어플로우 유저 권한 세팅
$ mkdir -p ./dags ./logs ./plugins # mkdir -p 옵션 : 여러 하위 디렉토리를 생성시에 사용

그 다음, .env 폴더 생성 후 다음 코드 입력

AIRFLOW_UID=50000

(참고) docker compose 지원 환경변수

  1. 에어플로우 DB 초기화
$ docker-compose up airflow-init
  1. 나머지 이미지들도 전부 실행
$ docker compose up -d
  1. 마지막으로 flower를 실행시켜준다.
$ docker compose up -d flower

sqlalchemy 기반 DAG 파일 생성

from datetime import datetime, timedelta
from dotenv import load_dotenv
import os
from airflow import DAG
from airflow.operators.postgres_operator import PostgresOperator
from airflow.operators.python_operator import PythonOperator
from sqlalchemy import create_engine
import pandas as pd
import pendulum

# load varaibles from the .env file
load_dotenv()

# set local timezone
local_tz = pendulum.timezone("Asia/Seoul")

# Define your default_args, schedule_interval, and other DAG configurations
default_args = {
    'owner': 'airflow',
    'depends_on_past': False,
    'start_date': datetime(2023, 10, 24, tzinfo=local_tz),
    'email_on_failure': False,
    'email_on_retry': False,
    'retries': 1,
    'retry_delay': timedelta(minutes=5),
}

dag = DAG(
    'pionada_etl',
    default_args=default_args,
    description='An example DAG to copy data from one PostgreSQL DB to another',
    schedule_interval=timedelta(days=1),  # Set your schedule interval
)

# Define a function to fetch data from source PostgreSQL DB
def fetch_data_from_source_db():
    source_engine = create_engine(f'postgresql://{FETCH_USER_NAME}:{FETCH_USER_PW}@{FETCH_DB_URL}/{FETCH_DB_NAME}')
    df = pd.read_sql(f'SELECT * FROM {FETCH_TABLE_NAME}', source_engine)
    return df

# Define a function to write data to target PostgreSQL DB
def write_data_to_target_db(**kwargs):
    target_engine = create_engine(f'postgresql://{WRITE_USER_NAME}:{WRITE_USER_PW}@{WRITE_DB_URL}/{WRITE_DB_NAME}')
    ti = kwargs['ti']
    df = ti.xcom_pull(task_ids='fetch_data_from_source_db')
    df.to_sql(f'{WRITE_TABLE_NAME}', target_engine, if_exists='replace', index=False)

# Define tasks
fetch_data_task = PythonOperator(
    task_id='fetch_data_from_source_db',
    python_callable=fetch_data_from_source_db,
    dag=dag,
)

write_data_task = PythonOperator(
    task_id='write_data_to_target_db',
    python_callable=write_data_to_target_db,
    provide_context=True,
    dag=dag,
)

# Set task dependencies
fetch_data_task >> write_data_task

회사 내 원하는 서비스의 DB정보를 가져와주는 fetch_data_task 와 가져온 데이터를 Airflow 내의 PostgreSQL 안에 적재시켜주는 write_data_task 를 정의하는 DAG 파일을 생성해줬다.

sqlalchemy 를 통한 DB 연결 및 SQL 문 실행을 수행하였고, xcom_pull 을 통해 task 사이에서의 데이터 전달이 가능해지도록 구현하였다.

PythonOperator 사용 시, return이 자동으로 Xcom 변수로 지정되게 된다. 또한, provide_context 를 통해 Task Instance의 시행 일자, Task ID와 같은 부가 정보들도 액세스 가능해진다.
또한, pendulum 라이브러리를 사용하여 DAG 파일 내 로컬 타임존을 적용하여, 스케쥴링 시간이 KST 기준으로 이뤄지도록 구현하였다.

작성 완료 후, dag 폴더 내에 넣어주고 나서 새로고침하면 바로 웹 상에서 확인 가능하다.

Apache WebServer

  1. 디폴트 계정으로 로그인

아이디 : airflow, 비번 : airflow

image

웹 서버 첫 화면

메인 화면에서 부터 KST 타임 설정이 잘 된 것을 확인할 수 있다.

  1. 현재 DAG 파일들 상태 확인

image

DAGs 메뉴 화면

원하는 DAG 을 선택한 후, 실행되는 과정을 상세하게 확인할 수 있다.

  1. Success, 혹은 Failed 이유를 로그를 통해 확인 가능

image Total success, 혹은 Total failed 클릭 시 상세 로그 확인 가능

로그 확인을 통해 DAG의 Task 중, create_engine 내에 들어가는 url 형식이 잘못된 것을 확인하였고 이를 수정하고 난 후 성공적으로 Airflow 기반 ETL 파이프라인을 구축할 수 있었다.

Total success, 혹은 Total failed 클릭 시 상세 로그 확인 가능

로그 확인을 통해 DAG의 Task 중, create_engine 내에 들어가는 url 형식이 잘못된 것을 확인하였고 이를 수정하고 난 후 성공적으로 Airflow 기반 ETL 파이프라인을 구축할 수 있었다.

About

V사 데이터 포털의 DB 중앙 관리 시스템을 위한 Apache Airflow ETL 구축 실습


Languages

Language:Python 100.0%