λ©±λ±μ± (Idempotency)
- κ°μ νμ΄νλΌμΈμ μ¬λ¬ λ² μ€νν΄λ κ²°κ³Όκ° νμ κ°μμΌ νλ€.
μ νμν κΉ? νμ΄νλΌμΈμ μΈμ λ μ€ν¨ν μ μλ€.
μλ²½ 2μ νμ΄νλΌμΈ μ€ν
-> μ λ°μ―€ μ€νλλ€κ° μλ² μ₯μ λ‘ μ€ν¨
-> μλ²½ 3μ μ¬μ€ν
-> λ°μ΄ν°κ° λ λ² λ€μ΄κ°λ©΄?
- λ©±λ±μ±μ΄ μμΌλ©΄ μ¬μ€νν λλ§λ€ λ°μ΄ν°κ° μ€λ³΅λλ€.
1. λμ μμ - μ€νν λλ§λ€ λ°μ΄ν°κ° μμ
INSERT INTO fct_orders
SELECT * FROM stg_orders
WHERE date = '2024-01-01';
2. μ’μ μμ - λ¨Όμ μ§μ°κ³ λ€μ λ£μ
DELETE FROM fct_orders WHERE date = '2024-01-01';
INSERT INTO fct_orders
SELECT * FROM stg_orders
WEHRE date = '2024-01-01';
λλ MERGE / UPSERT μ¬μ©
MERGE INTO fct_orders AS target
USING stg_orders AS source
ON target.order_id = source.order_id
WHEN MATCHED THEN UPDATE SET ...
WHEN NOT MATCHED THEN INSERT ...
μ¬μ²λ¦¬ (Backfill)
- κ³Όκ±° λ°μ΄ν°λ₯Ό μκΈν΄μ λ€μ μ²λ¦¬νλ κ²μ΄λ€.
- λ©±λ±μ±μ΄ μμΌλ©΄ backfill ν λ λ°μ΄ν°κ° μ€λ³΅λκ±°λ κΌ¬μΈλ€. λ©±λ±μ±κ³Ό μ¬μ²λ¦¬λ νμ ν¨κ» μ€κ³ν΄μΌ νλ€.
μν© : 2024λ 1μ λ³ν λ‘μ§μ λ²κ·Έκ° μμμ
-> 1μ λ°μ΄ν°λ₯Ό μ λΆ λ€μ μ²λ¦¬ν΄μΌ ν¨
-> λ©±λ±μ±μ΄ μμ΄μΌ μμ νκ² μ¬μ²λ¦¬ κ°λ₯
- Airflowμμλ μ΄λ κ² μ€ννλ€.
airflow dags backfill \
-- start-date 2024-01-01 \
-- end-date 2024-01-31 \
my_pipeline
νν°μ λ (Partitioning)
- λμ©λ ν
μ΄λΈμ λ μ§ λ± κΈ°μ€μΌλ‘ λλ μ μ μ₯νλ κ²μ΄λ€.
- νν°μ λμ 쿼리 μ±λ₯λΏ μλλΌ λΉμ©μλ μ§μ μ μΈ μν₯μ μ€λ€. BigQueryλ μ€μΊν λ°μ΄ν° μλ§νΌ λΉμ©μ΄ λμ€κΈ° λλ¬Έμ νν°μ ν루λμ΄ μ λλ‘ λλμ§ νμΈνλ κ²μ΄ μ€μνλ€.
νν°μ λ μμ΄
fct_orders (3μ΅ κ±΄ μ 체 μ€μΊ)
-> 쿼리 λλ¦Ό, λΉμ© λ§μ΄ λμ΄
νν°μ λ μ μ©
fct_orders/
βββ date=2024-01-01/ (100λ§ κ±΄)
βββ date=2024-01-02/ (100λ§ κ±΄)
βββ date=2024-01-03/ (100λ§ κ±΄)
-> WHERE date = '2024-01-01' 쿼리 μ
-> ν΄λΉ νν°μ λ§ μ½μ -> λΉ λ₯΄κ³ μ λ ΄
- BigQuery κΈ°μ€ νν°μ λ ν μ΄λΈ μμ±
CREATE TABLE fct_orders
PARTITION BY DATE(ordered_at)
AS SELECT * FROM stg_orders;
λͺ¨λν°λ§ & μλ¦Ό
- νμ΄νλΌμΈμ΄ μ€ν¨νμ λ μ무λ λͺ¨λ₯΄λ©΄ μλλ€.
Airflow DAG μ€ν¨
-> slack μλ¦Ό λ°μ‘
-> λ΄λΉμκ° νμΈ
-> μμΈ νμ ν μ¬μ€ν
- Airflow μμ Slack μλ¦Ό μ€μ
def alert_slack(context):
SlackWebhookOperator(
task_id='slack_alert',
message=f":red_circle: νμ΄νλΌμΈ μ€ν¨\nDAG: {context['dag'].dag_id}\nTask: {context['task_instance'].task_id}",
webhook_token_conn_id='slack_webhook'
).execute(context)
with DAG(
'my_pipeline',
on_failure_callback=alert_slack,
...
):
...
λͺ¨λν°λ§μμ ν¨κ» μ±κ²¨μΌ ν κ²λ€
- SLA : λͺ μκΉμ§ νμ΄νλΌμΈμ΄ μλ£λΌμΌ νλκ°
- λ‘κΉ : μ΄λ νμ€ν¬μμ μ μ€ν¨νλμ§ μΆμ κ°λ₯νκ°
- dbt test μ°λ : λ°μ΄ν° νμ§ κ²μ¬ μ€ν¨λ μλ¦Ό λμμ ν¬ν¨
νμ΄νλΌμΈ μ 체 κ·Έλ¦Ό λ° μ€κ³ 체ν¬λ¦¬μ€νΈ
[MySQL: μ£Όλ¬Έ λ°μ΄ν°]
↓ Airbyte (λ§€μΌ μλ²½ 1μ μμ§)
[BigQuery: Raw ν
μ΄λΈ]
↓ dbt run (μλ²½ 1μ 30λΆ)
[BigQuery: Marts]
↓ dbt test (μλ²½ 2μ)
βββ μ€ν¨ → Slack μλ¦Ό λ°μ‘
βββ μ±κ³΅
[Looker λμ보λ κ°±μ (μλ²½ 2μ 30λΆ)]
β‘ λ©±λ±μ± — μ¬μ€νν΄λ λ°μ΄ν° μ€λ³΅μ΄ μκΈ°μ§ μλκ°?
β‘ νν°μ
λ — λ μ§ κΈ°μ€μΌλ‘ λ°μ΄ν°λ₯Ό λλ΄λκ°?
β‘ μ¬μ²λ¦¬ — κ³Όκ±° λ°μ΄ν° backfillμ΄ κ°λ₯νκ°?
β‘ λͺ¨λν°λ§ — μ€ν¨ μ μλ¦Όμ΄ μ€λκ°?
β‘ λ‘κΉ
— μ΄λμ μ€ν¨νλμ§ μΆμ κ°λ₯νκ°?
β‘ SLA — λͺ μκΉμ§ μλ£λΌμΌ νλκ°?'Database > Engineering' μΉ΄ν κ³ λ¦¬μ λ€λ₯Έ κΈ
| [DE] λ°°μΉ vs μ€νΈλ¦¬λ° (2) | 2026.05.21 |
|---|---|
| [DE] dbt(data build tool) - SQLμ μ½λμ²λΌ κ΄λ¦¬νλ λꡬ (0) | 2026.05.21 |
| [DE] λ°μ΄ν°μ¨μ΄νμ°μ€ λͺ¨λΈλ§ κΈ°λ³Έ - Star Schema (0) | 2026.05.20 |
| [DE] OLTP vs OLAP (2) | 2026.05.19 |