상황
Airflow를 이용해서 low한 통계 데이터를 집계하는 API를 호출하여 daily 과금 금액과 total 과금 금액을 집계한다. 이때 과금 금액을 "사용한 값" 이라고 하자. "사용한 값"은 00시에 0으로 리셋해준다.
"사용할 값"은 하루에 총 소진되어야 할 시간 * 스케줄(06시 ~ 12시에만 소진되어야 하는 등의 설정이 가능하다)
그런데 리셋을 해주었음에도 불구하고 "사용할 값"이 갑자기 치솟아 과소진 된 이슈가 있었다.
원인
쿼리의 구성은 이랬다.
- 원시 통계 데이터를 가지고 1차 가공 디비에 업데이트 (따라서 시간이 오래 걸리고, Replace Into와 셀렉트 절을 사용한다)
REPLACE INTO 1차 가공 테이블
(date, 통계 데이터)
SELECT
date,
식별자,
통계에 필요한 필드들,
now()
FROM
(SELECT
date,
통계에 필요한 필드들
FROM
stats
GROUP BY
date) statistics
JOIN 통계 ON statistics.식별자 = 식별자
GROUP BY
date
- 1차 가공 테이블을 사용하여 2차 테이블에 업데이트
UPDATE 업데이트 대상 필드,
(SELECT
통계 필드
FROM
(SELECT
통계 필드
FROM
1차 통계 테이블
WHERE
GROUP BY
식별자) 토탈 통계 테이블
LEFT JOIN
(SELECT
ad_id,
사용 값
FROM
1차 통계 테이블
GROUP BY
ad_id) 2차 가공 값
ON total_stats.ad_id = daily_stats.ad_id) new_stats
SET 업데이트 대상 필드.통계 필드 = 2차 가공값.통계 필드
보안을 위해 아주 추상화 했지만 이러한 구조를 가지고 있다.
그런데 문제는, 쿼리의 시간이 너무 오래걸려 23시 50분 시점에 해당 배치가 실행되면 정작 최종적으로 업데이트 되는 시간은 다음 날이 되는것이 문제의 원인이었다. 즉 전날의 값이 엎어 쳐지는 것이다.
해결 방안
세션 변수를 하나 할당하여 1차 가공과 2차 가공에서 모두 where절로 걸어주었다.
SET @statistics_current_date := CURDATE();
의문
글을 읽다 보면 의문이 들 수 있다. 이것이 과연 Airflow의 문제라고 할 수 있는가?
가령 스프링 배치나 스프링 스케줄러 같은 다른 방법을 사용하여 쿼리를 돌렸어도 동일하게 발생할 문제이지 않은가?
맞다. 그러나 미리 스포하자면 문제의 원인은 여기서 끝이 아니었다. 다음 포스팅에서 추가로 식별된 Airflow로 인한 배치에서의 문제점을 써보도록 하겠다.
'트러블 슈팅 > 인프라' 카테고리의 다른 글
(Kafka) Kafka Streams에서 Repartition Topic을 Consume하지 못하는 장애(feat: kafkaAdminCli) (0) | 2024.06.16 |
---|---|
(Kafka) Kafka Streams에서 Repartition Topic을 Consume하지 못하는 장애 (feat: Metric으로 Lag값 추출) (0) | 2024.05.18 |
(Kafka) 유효하지 않은 레코드가 토픽에 들어와 카프카 어플리케이션 장애가 났을 때 (2) | 2024.05.08 |
(Airflow) 배치 날짜값 오차로 인한 통계값 오류가 발생한 이슈 2 (8) | 2024.05.01 |
(ES) Kibana Index Pattern이 생성되지 않는 버그 (1) | 2024.04.27 |