๐Ÿš€ ๋ฐ์ดํ„ฐ ํŒŒ์ดํ”„๋ผ์ธ ์ž๋™ํ™”์˜ ๋ํŒ์™•, Airflow ํŒŒํ—ค์น˜๊ธฐ!

Joshuaยท2025๋…„ 1์›” 15์ผ
1

DB

๋ชฉ๋ก ๋ณด๊ธฐ
3/3
post-thumbnail

์ด๋ฒˆ ํฌ์ŠคํŒ…์€ ๋ฐ์ดํ„ฐ ์—”์ง€๋‹ˆ์–ด๋ง ์—ฌ์ •์— ๊ฐ•๋ ฅํ•œ ๋‚ ๊ฐœ๋ฅผ ๋‹ฌ์•„์ค„ Airflow์— ๋Œ€ํ•œ ๋ชจ๋“  ๊ฒƒ์„ ๋‹ด์•˜๋‹ค. ๊ธด ์Šคํฌ๋กค ์••๋ฐ•์ด ์˜ˆ์ƒ๋˜์ง€๋งŒ, ๊ทธ๋งŒํผ ์•Œ์ฐฌ ์ •๋ณด๋กœ ๊ฐ€๋“ ์ฑ„์šฐ๋ ค๊ณ  ๋…ธ๋ ฅํ–ˆ๋‹ค! ๐Ÿ”ฅ

1. ์„œ๋ก : ์™œ Airflow๊ฐ€ ํ•„์š”ํ• ๊นŒ? ๐Ÿค”

LLM ํ•™์Šต์— ๋น ์ ธ ์‚ด๊ณ  ์žˆ๋Š” ์ฃผ๋‹ˆ์–ด ๊ฐœ๋ฐœ์ž๋กœ์„œ, ๋ฐ์ดํ„ฐ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ณผ์ •์—์„œ ์ˆ˜๋งŽ์€ ์–ด๋ ค์›€์„ ๊ฒช์—ˆ๋‹ค. ์ˆ˜๋™์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์˜ฎ๊ธฐ๊ณ , ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‹คํ–‰ํ•˜๊ณ , ์˜ค๋ฅ˜๋ฅผ ๊ฐ์‹œํ•˜๋Š” ์ผ์€ ์ •๋ง ๊ณ ๋๋‹ค. ๐Ÿ˜ตโ€๐Ÿ’ซ

์ด๋Ÿฐ ๋ณต์žกํ•˜๊ณ  ๋ฐ˜๋ณต์ ์ธ ์ž‘์—…์„ ์ž๋™ํ™”ํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์ด ์—†์„๊นŒ? ๊ณ ๋ฏผํ•˜๋˜ ์ค‘ ๋ˆˆ์— ๋“ค์–ด์˜จ ๊ฒƒ์ด ๋ฐ”๋กœ Airflow!

Airflow๋Š” ๋ณต์žกํ•œ ๋ฐ์ดํ„ฐ ํŒŒ์ดํ”„๋ผ์ธ์„ ์ •์˜, ์Šค์ผ€์ค„๋ง, ๋ชจ๋‹ˆํ„ฐ๋งํ•  ์ˆ˜ ์žˆ๋Š” ๊ฐ•๋ ฅํ•œ ์˜คํ”ˆ์†Œ์Šค ํ”Œ๋žซํผ์ด๋‹ค. ๋ฐ์ดํ„ฐ ์—”์ง€๋‹ˆ์–ด๋ง์˜ ํ•„์ˆ˜ ๋„๊ตฌ๋กœ ์ž๋ฆฌ๋งค๊น€ํ•˜๊ณ  ์žˆ์œผ๋ฉฐ ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ ์ž๋™ํ™”์˜ ํ•ต์‹ฌ ๊ธฐ์ˆ ์ด๋ผ๊ณ  ํ•  ์ˆ˜ ์žˆ์Œ !!

Airflow๊ฐ€ ํ•„์š”ํ•œ ์ด์œ :

  • ์ˆ˜๋™ ์ž‘์—…์˜ ํ•œ๊ณ„: ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ ์ž‘์—…์€ ๋ฐ˜๋ณต์ ์ด๊ณ  ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜๊ธฐ ์‰ฝ๋‹ค. Airflow๋Š” ์ด๋Ÿฌํ•œ ์ˆ˜๋™ ์ž‘์—…์„ ์ž๋™ํ™”ํ•˜์—ฌ ํšจ์œจ์„ฑ์„ ๋†’์—ฌ์ค€๋‹ค.
  • ๋ณต์žกํ•œ ์˜์กด์„ฑ ๊ด€๋ฆฌ: ์—ฌ๋Ÿฌ ์ž‘์—…์ด ๋ณต์žกํ•˜๊ฒŒ ์—ฐ๊ฒฐ๋œ ํŒŒ์ดํ”„๋ผ์ธ์„ ๊ด€๋ฆฌํ•˜๋Š” ๊ฒƒ์€ ๋งค์šฐ ์–ด๋ ต๋‹ค. Airflow๋Š” ์ž‘์—… ๊ฐ„ ์˜์กด์„ฑ์„ ๋ช…ํ™•ํ•˜๊ฒŒ ์ •์˜ํ•˜๊ณ  ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์ค€๋‹ค.
  • ์‹คํŒจ ์ฒ˜๋ฆฌ ๋ฐ ์žฌ์‹œ๋„: ์ž‘์—… ์‹คํŒจ ์‹œ ์ž๋™ ์žฌ์‹œ๋„ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜์—ฌ ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ ์•ˆ์ •์„ฑ์„ ๋†’์—ฌ์ค€๋‹ค.
  • ๋ชจ๋‹ˆํ„ฐ๋ง ๋ฐ ์•Œ๋ฆผ: ํŒŒ์ดํ”„๋ผ์ธ์˜ ์‹คํ–‰ ์ƒํƒœ๋ฅผ ๋ชจ๋‹ˆํ„ฐ๋งํ•˜๊ณ , ์˜ค๋ฅ˜ ๋ฐœ์ƒ ์‹œ ์•Œ๋ฆผ์„ ๋ฐ›์„ ์ˆ˜ ์žˆ์–ด ๋ฌธ์ œ ๋ฐœ์ƒ ์‹œ ๋น ๋ฅด๊ฒŒ ๋Œ€์‘ํ•  ์ˆ˜ ์žˆ๋‹ค.

2. Airflow ํ•ต์‹ฌ ๊ฐœ๋… ์งš์–ด๋ณด๊ธฐ ๐Ÿง

Airflow๋ฅผ ์ œ๋Œ€๋กœ ํ™œ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ๋ช‡ ๊ฐ€์ง€ ํ•ต์‹ฌ ๊ฐœ๋…์„ ์ดํ•ดํ•ด์•ผ ํ•œ๋‹ค. ๋งˆ์น˜ ๋ ˆ๊ณ  ๋ธ”๋ก์ฒ˜๋Ÿผ, ์ด ๊ฐœ๋…๋“ค์„ ์กฐํ•ฉํ•˜์—ฌ ๋ฐ์ดํ„ฐ ํŒŒ์ดํ”„๋ผ์ธ์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋Š” ๊ฒƒ !

  • DAG (Directed Acyclic Graph): Airflow์˜ ํ•ต์‹ฌ ๋‹จ์œ„๋กœ, ์ž‘์—…(task)๋“ค์˜ ์˜์กด ๊ด€๊ณ„๋ฅผ ๋ฐฉํ–ฅ์„ฑ ๋น„์ˆœํ™˜ ๊ทธ๋ž˜ํ”„(DAG) ํ˜•ํƒœ๋กœ ํ‘œํ˜„. DAG๋Š” ํŒŒ์ดํ”„๋ผ์ธ์˜ ๋…ผ๋ฆฌ์  ๊ตฌ์กฐ๋ฅผ ์ •์˜.
  • Task: DAG๋ฅผ ๊ตฌ์„ฑํ•˜๋Š” ๊ฐœ๋ณ„ ์ž‘์—… ๋‹จ์œ„๋ฅผ ์˜๋ฏธ. (๋ฐ์ดํ„ฐ ์ถ”์ถœ, ๋ณ€ํ™˜, ๋กœ๋“œ ๋“ฑ)
  • Operator: Task๊ฐ€ ์ˆ˜ํ–‰ํ•˜๋Š” ์‹ค์ œ ์ž‘์—…์„ ์ •์˜. Airflow๋Š” ๋‹ค์–‘ํ•œ ์ข…๋ฅ˜์˜ Operator๋ฅผ ์ œ๊ณตํ•˜๋ฉฐ, ์‚ฌ์šฉ์ž ์ •์˜ Operator๋ฅผ ๋งŒ๋“ค ์ˆ˜๋„ ์žˆ์Œ. (BashOperator, PythonOperator, PostgresOperator ๋“ฑ)
  • Scheduler: ์ •์˜๋œ DAG๋ฅผ ์Šค์ผ€์ค„์— ๋”ฐ๋ผ ์‹คํ–‰ํ•˜๋Š” ์—ญํ• . Cron ํ‘œํ˜„์‹์„ ์‚ฌ์šฉํ•˜์—ฌ ์‹คํ–‰ ์ฃผ๊ธฐ๋ฅผ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.
  • Executor: Task๋ฅผ ์‹คํ–‰ํ•˜๋Š” ์—”์ง„. (LocalExecutor, CeleryExecutor, KubernetesExecutor ๋“ฑ)
  • Web UI: Airflow ์›น ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ํ†ตํ•ด DAG ์‹คํ–‰ ์ƒํƒœ๋ฅผ ๋ชจ๋‹ˆํ„ฐ๋งํ•˜๊ณ , ๋กœ๊ทธ๋ฅผ ํ™•์ธํ•˜๊ณ , ์Šค์ผ€์ค„์„ ๊ด€๋ฆฌ

3. Airflow, ์ด๋ ‡๊ฒŒ ํ™œ์šฉํ•˜์„ธ์š”! โœจ

Airflow๋Š” ๋ฐ์ดํ„ฐ ์—”์ง€๋‹ˆ์–ด๋ง์˜ ๋‹ค์–‘ํ•œ ๋ถ„์•ผ์—์„œ ํ™œ์šฉ๋  ์ˆ˜ ์žˆ๋‹ค. ๋ช‡ ๊ฐ€์ง€ ์˜ˆ์‹œ๋ฅผ ํ†ตํ•ด Airflow์˜ ํ™œ์šฉ ๊ฐ€๋Šฅ์„ฑ์„ ์‚ดํŽด๋ณด์ž !

  • ๋ฐ์ดํ„ฐ ์ˆ˜์ง‘ ๋ฐ ํ†ตํ•ฉ: API, ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค, ํŒŒ์ผ ์‹œ์Šคํ…œ ๋“ฑ ๋‹ค์–‘ํ•œ ์†Œ์Šค์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์ˆ˜์ง‘ํ•˜๊ณ  ํ†ตํ•ฉํ•˜๋Š” ํŒŒ์ดํ”„๋ผ์ธ ๊ตฌ์ถ•
  • ๋ฐ์ดํ„ฐ ๋ณ€ํ™˜ ๋ฐ ์ •์ œ: ์ˆ˜์ง‘๋œ ๋ฐ์ดํ„ฐ๋ฅผ ์›ํ•˜๋Š” ํ˜•ํƒœ๋กœ ๋ณ€ํ™˜ํ•˜๊ณ  ์ •์ œํ•˜๋Š” ํŒŒ์ดํ”„๋ผ์ธ์„ ๊ตฌ์ถ•ํ•  ์ˆ˜ ์žˆ๋‹ค. (๋ฐ์ดํ„ฐ ๋ˆ„๋ฝ ๊ฐ’ ์ฒ˜๋ฆฌ, ์ด์ƒ์น˜ ์ œ๊ฑฐ, ๋ฐ์ดํ„ฐ ํ˜•์‹ ๋ณ€ํ™˜ ๋“ฑ์„ ์ž๋™ํ™”)
  • ๋จธ์‹ ๋Ÿฌ๋‹ ๋ชจ๋ธ ํ•™์Šต: ๋ชจ๋ธ ํ•™์Šต์— ํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ ์ „์ฒ˜๋ฆฌ ๊ณผ์ •์„ ์ž๋™ํ™”ํ•˜๊ณ , ๋ชจ๋ธ ํ•™์Šต ๋ฐ ๋ฐฐํฌ ํŒŒ์ดํ”„๋ผ์ธ ๊ตฌ์ถ•
  • ๋ฐ์ดํ„ฐ ์›จ์–ดํ•˜์šฐ์Šค ๊ตฌ์ถ•: ๋ฐ์ดํ„ฐ ์›จ์–ดํ•˜์šฐ์Šค์— ๋ฐ์ดํ„ฐ๋ฅผ ์ ์žฌํ•˜๊ณ  ๊ด€๋ฆฌํ•˜๋Š” ํŒŒ์ดํ”„๋ผ์ธ ๊ตฌ์ถ•
  • BI (Business Intelligence) ๋ณด๊ณ ์„œ ์ƒ์„ฑ: ๋ฐ์ดํ„ฐ๋ฅผ ๋ถ„์„ํ•˜์—ฌ BI ๋ณด๊ณ ์„œ๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ๋ฐฐํฌํ•˜๋Š” ํŒŒ์ดํ”„๋ผ์ธ ๊ตฌ์ถ•

Airflow ํ™œ์šฉ ์˜ˆ์‹œ (Python ์ฝ”๋“œ):

from airflow import DAG
from airflow.operators.bash import BashOperator
from airflow.operators.python import PythonOperator
from datetime import datetime

def my_python_function():
    print("Hello from Python!")

with DAG(
    dag_id='my_first_airflow_dag',
    start_date=datetime(2024, 1, 1),
    schedule_interval=None,
    catchup=False
) as dag:
    bash_task = BashOperator(
        task_id='run_bash_command',
        bash_command='echo "Hello from Bash!"'
    )

    python_task = PythonOperator(
        task_id='run_python_function',
        python_callable=my_python_function
    )

    bash_task >> python_task

์œ„ ์ฝ”๋“œ๋Š” Bash ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•˜๋Š” Task์™€ Python ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰ํ•˜๋Š” Task๋กœ ๊ตฌ์„ฑ๋œ ๊ฐ„๋‹จํ•œ DAG๋‹ค. ์ด ์ฝ”๋“œ๋ฅผ Airflow์— ๋“ฑ๋กํ•˜๋ฉด, ์ •์˜๋œ ์ˆœ์„œ๋Œ€๋กœ Task๊ฐ€ ์‹คํ–‰๋œ๋‹ค.


4. airflow ์„ค์น˜์™€ ์‚ฌ์šฉ

1) ์„ค์น˜

pip install apache-airflow
์ด๋ ‡๊ฒŒ pip๋กœ ์ง์ ‘ ์„ค์น˜ํ•˜๊ฑฐ๋‚˜

curl -LfO 'https://airflow.apache.org/docs/apache-airflow/stable/docker-compose.yaml'
airflow์—์„œ ์ œ๊ณตํ•˜๋Š” docker-compose ํŒŒ์ผ์„ ๋ฐ›์•„์™€๋„ ๋œ๋‹ค.

์ด๋Ÿฐ๊ฑฐ ๋„ˆ๋ฌด ๊ท€์—ฌ์›€

๋‚˜์˜ ๊ฒฝ์šฐ ๊ธฐ์กด์— ์‚ฌ์šฉํ•˜๋˜ MySQL์—์„œ PostgreSQL๋กœ ์ด๋™ํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ–ˆ๋‹ค.

  • compose file(airflow ๊ธฐ๋ณธ ์„ธํŒ…)
    ์ด ๋ถ€๋ถ„์—์„œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ์„ค์น˜ํ•˜๊ณ  ๋กœ๊ทธ์ธ ์ •๋ณด๋ฅผ ์ž…๋ ฅํ•˜๋ฉด ๋œ๋‹ค.
    version: '3.7'
    services:
      postgres:
        image: postgres:13
        environment:
          POSTGRES_USER: airflow
          POSTGRES_PASSWORD: airflow
          POSTGRES_DB: airflow
        ports:
          - "5432:5432"
        volumes:
          - postgres_data:/var/lib/postgresql/data
    
      mysql:
        image: mysql:8.0
        environment:
          MYSQL_ROOT_PASSWORD: root
          MYSQL_DATABASE: source
          MYSQL_USER: user
          MYSQL_PASSWORD: password
        ports:
          - "3306:3306"
        volumes:
          - mysql_data:/var/lib/mysql
    
      redis:
        image: redis:7.2-bookworm
        ports:
          - "6379:6379"
    
      airflow-webserver:
        image: apache/airflow:2.7.1
        environment:
          - AIRFLOW__CORE__EXECUTOR=LocalExecutor
          - AIRFLOW__CORE__SQL_ALCHEMY_CONN=postgresql+psycopg2://airflow:airflow@postgres/airflow
          - AIRFLOW__CELERY__BROKER_URL=redis://redis:6379/0
        depends_on:
          - postgres
          - mysql
          - redis
        ports:
          - "8080:8080"
        volumes:
          - ./dags:/opt/airflow/dags
          - ./logs:/opt/airflow/logs
          - ./plugins:/opt/airflow/plugins
        command: >
          bash -c "
          airflow db init &&
          airflow users create --username airflow --password airflow --firstname Admin --lastname User --role Admin --email admin@example.com &&
          airflow webserver"
    
      airflow-scheduler:
        image: apache/airflow:2.7.1
        depends_on:
          - postgres
          - redis
        volumes:
          - ./dags:/opt/airflow/dags
          - ./logs:/opt/airflow/logs
          - ./plugins:/opt/airflow/plugins
        command: >
          bash -c "
          airflow scheduler"
    
    volumes:
      postgres_data:
      mysql_data:

๊ทธ ๋‹ค์Œ docker-compose up -d๋กœ ์˜ฌ๋ฆฌ๋ฉด ๊ธฐ๋ณธ ์„ธํŒ… ๋ !

  • ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ์ž‘์—…ํ•  py ํŒŒ์ผ
    from airflow import DAG
    from airflow.operators.python import PythonOperator
    from datetime import datetime, timedelta
    import mysql.connector
    import psycopg2
    # MySQL์—์„œ ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๊ธฐ
    def transfer_data():
        # MySQL ์—ฐ๊ฒฐ
        mysql_conn = mysql.connector.connect(
            host="mysql",
            user="user",
            password="password",
            database="db"
        )
        mysql_cursor = mysql_conn.cursor()
        mysql_cursor.execute("SELECT * FROM your_table LIMIT 100")
        rows = mysql_cursor.fetchall()
    
        # PostgreSQL ์—ฐ๊ฒฐ
        postgres_conn = psycopg2.connect(
            host="postgres",
            user="airflow",
            password="airflow",
            database="airflow"
        )
        postgres_cursor = postgres_conn.cursor()
    
        # PostgreSQL์— ๋ฐ์ดํ„ฐ ์‚ฝ์ž…
        insert_query = """
        INSERT INTO my_table (job_title, job_post, company)
        VALUES (%s, %s, %s)
        """
        postgres_cursor.executemany(insert_query, rows)
    
        # ์ปค๋ฐ‹ ๋ฐ ์—ฐ๊ฒฐ ์ข…๋ฃŒ
        postgres_conn.commit()
        mysql_cursor.close()
        mysql_conn.close()
        postgres_cursor.close()
        postgres_conn.close()
    # DAG ์ •์˜
    default_args = {
        "owner": "airflow",
        "depends_on_past": False,
        "email_on_failure": False,
        "email_on_retry": False,
        "retries": 1,
        "retry_delay": timedelta(minutes=5),
    }
    
    with DAG(
        "mysql_to_postgres",
        default_args=default_args,
        description="Transfer data from MySQL to PostgreSQL",
        schedule_interval="0 * * * *",  # ๋งค์‹œ๊ฐ„ 0๋ถ„์— ์‹คํ–‰
        start_date=datetime(2025, 1, 1),
        catchup=False,
    ) as dag:
    
        transfer_task = PythonOperator(
            task_id="transfer_data",
            python_callable=transfer_data,
        )

๋งค ์‹œ๊ฐ„๋งˆ๋‹ค 100๊ฐœ์”ฉ ์˜ฎ๊ธฐ๋„๋ก ์„ค์ •ํ•ด๋‘์—ˆ๋‹ค.
yamlํŒŒ์ผ์—์„œ ์„ค์ •ํ•œ http://localhost:8080๋กœ ์ ‘์†ํ•ด ๋กœ๊ทธ์ธํ•˜๋ฉด ๋ฐฐ์น˜ ์ž‘์—…์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

์ด๋Ÿฐ์‹์œผ๋กœ !
๊ฐ„๋‹จํ•œ ์ž‘์—…์ด์–ด์„œ ๋‚˜๋„ ์กฐ๊ธˆ ๋” ์จ๋ด์•ผ ์•Œ๊ฒ ์ง€๋งŒ
ํ™œ์šฉ๋„๊ฐ€ ๋†’์€ ํˆด์ด๋‹ค๋ณด๋‹ˆ ๋” ๊นŠ๊ฒŒ ๊ณต๋ถ€ํ•ด๋ด์•ผ๊ฒ ๋‹ค๋Š” ์ƒ๊ฐ !!
๋‚˜์ค‘์—๋Š” ๋ฐ์ดํ„ฐ ๋ถ„์„์„ ์œ„ํ•œ ๋ฐ์ดํ„ฐ ํŒŒ์ดํ”„๋ผ์ธ๋„ ๋งŒ๋“ค์–ด๋ด์•ผ๊ฒ ๋‹ค.


5. ๊ฒฐ๋ก : ๋ฐ์ดํ„ฐ ์—”์ง€๋‹ˆ์–ด๋ง ์—ฌ์ •์˜ ๋“ ๋“ ํ•œ ๋™๋ฐ˜์ž, Airflow! ๐Ÿค

Airflow๋Š” ๋ฐ์ดํ„ฐ ํŒŒ์ดํ”„๋ผ์ธ ์ž๋™ํ™”๋ฅผ ์œ„ํ•œ ๊ฐ•๋ ฅํ•œ ๋„๊ตฌ๋‹ค. ๋ณต์žกํ•œ ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ ์ž‘์—…์„ ์ž๋™ํ™”ํ•˜๊ณ , ํšจ์œจ์„ฑ์„ ๋†’์ด๋ฉฐ, ์•ˆ์ •์ ์ธ ์‹œ์Šคํ…œ์„ ๊ตฌ์ถ•ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์ค€๋‹ค. ์ฃผ๋‹ˆ์–ด ์ž…์žฅ์—์„œ Airflow๋ฅผ ๋ฐฐ์šฐ๊ณ  ํ™œ์šฉํ•˜๋Š” ๊ฒƒ์€ ๋ฐ์ดํ„ฐ ์—”์ง€๋‹ˆ์–ด๋ง ๋ถ„์•ผ์˜ ์„ฑ์žฅ์— ํฐ ๋„์›€์ด ๋  ๊ฒƒ์ด๋‹ค.

๋‚˜๋„ ์•„์ง Airflow๋ฅผ ๋ฐฐ์šฐ๋Š” ๊ณผ์ •์— ์žˆ์ง€๋งŒ, ์•ž์œผ๋กœ๋„ Airflow๋ฅผ ํ™œ์šฉํ•œ ๋ฐ์ดํ„ฐ ํŒŒ์ดํ”„๋ผ์ธ ๊ตฌ์ถ• ๊ฒฝํ—˜์„ ๊ณต์œ ํ•˜๋ฉฐ ๊ณ„์† ์„ฑ์žฅํ•ด ๋‚˜๊ฐ€์•ผ๊ฒ ๋‹ค! ๐Ÿš€


๋งˆ๋ฌด๋ฆฌ:

์ด ํฌ์ŠคํŒ…์ด Airflow์— ๋Œ€ํ•œ ์—ฌ๋Ÿฌ๋ถ„์˜ ์ดํ•ด๋ฅผ ๋†’์ด๋Š” ๋ฐ ๋„์›€์ด ๋˜์—ˆ๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค. ๊ถ๊ธˆํ•œ ์ ์ด ์žˆ๋‹ค๋ฉด ์–ธ์ œ๋“ ์ง€ ๋Œ“๊ธ€๋กœ ์งˆ๋ฌธํ•ด์ฃผ์„ธ์š”. ๋ฐ์ดํ„ฐ ์—”์ง€๋‹ˆ์–ด๋ง์˜ ์„ธ๊ณ„์—์„œ ํ•จ๊ป˜ ์„ฑ์žฅํ•ด ๋‚˜๊ฐ€๋Š” ๋ฉ‹์ง„ ์—ฌ์ •์„ ๊ธฐ๋Œ€ํ•ฉ๋‹ˆ๋‹ค! ๐Ÿ’ช

profile
๐Ÿฅ์‚์•ฝ์ด ๊ฐœ๋ฐœ์ž๐Ÿค

0๊ฐœ์˜ ๋Œ“๊ธ€

๊ด€๋ จ ์ฑ„์šฉ ์ •๋ณด