Airflow Error: Already running on PID

Airflow Web UI 주소에 접속이 안되어서 airflow webserver 시스템 로그를 확인해 보았더니 이와 같은 에러 메세지가 출력되었다. 좀 더 자세하게 보면
Feb 20 07:45:21 jobfairy-airflow-server airflow[3521154]: [2025-02-20 07:45:21 +0000] [3521154] [INFO] Starting gunicorn 22.0.0
Feb 20 07:45:21 jobfairy-airflow-server airflow[3521154]: Error: Already running on PID 1056 (or pid file '/var/lib/airflow/airflow-webserver.pid' is stale)
~
~
이렇게 확인할 수 있는데, 아무래도 웹서버가 이미 돌아가고 있는데, 또 다른 웹서버 프로세스를 띄우려고 하니 문제가 생겼다는 뜻인듯 하다.
이 에러는 보통 에어플로우 웹서버를 내렸다가 다시 올릴 때 이전에 종료가 제대로 되지 않았거나, PID 파일이 제대로 삭제되지 않은 상태로 남아 있는 경우에 발생한다고 한다.
이를 해결하기 위해서는 아래 두 가지의 방법을 사용해볼 수 있다.
시스템 서비스 재시작
나는 airflow webserver와 scheduler를 시스템 서비스(systemd)로 관리 중이기 때문에
sudo systemctl restart airflow-webserver
이나,
sudo systemctl stop airflow-webserver
로 완전히 중지한 뒤 sudo systemctl start airflow-webserver
로 다시 시작해 볼 수 있다.
하지만 문제가 해결되지 않았기에 다음 방법을 사용할 수 밖에 없었다.
수동으로 PID 파일 삭제
만약 Airflow 웹서버가 실제로는 안돌아가는데 이러한 에러가 뜬다면, PID 파일이 남아있어서 그런것일 수 있다.
우선 다음 명령어로 관련 프로세스의 유무를 확인한다.
ps aux | grep airflow
실행중인 프로세스가 없는게 맞는데도 PID 파일이 있으면 PID 파일을 수동으로 지워줘야 한다.
에러 메시지가 알려준 pid 파일의 경로
(Feb 20 07:45:21 jobfairy-airflow-server airflow[3521154]: Error: Already running on PID 1056 (or pid file '/var/lib/airflow/airflow-webserver.pid' is stale))
로 가서 pid 파일들을 확인해보자.
ls /var/lib/airflow/*.pid
메시지가 알려준 pid 파일이 실제로 있는 것이 확인되면 아래 명령어로 pid 파일을 삭제한 뒤 다시 웹서버를 실행하면 문제가 해결된다!
sudo rm /var/lib/airflow/airflow-webserver.pid
+) 😮 이것도 알아두자!
이번 이슈를 해결하면서 알게 된 정보들을 같이 기억해두자
pid 파일은 왜 생기는건가요?
pid란 데몬이나 특정 서비스가 현재 실행 중인 프로세스의 ID를 기록해두는 파일이다.
💡 데몬(Daemon)은 백그라운드에서 실행되는 장기 프로세스를 가리키는 말
일반적으로 직접적인 사용자 인터페이스가 없으며, 시스템이 부팅될 때 자동으로 시작되어 서버 역할, 모니터링, 스케줄링 등의 작업을 수행한다.
이는 서비스 관리, 중복 실행 방지, 모니터링/종료 등에 쓰이기에 그 필요가 있는데
시스템은 여러 서비스(데몬)가 동시에 돌 수 있기 때문에 어떤 서비스가 현재 실행 중인지 파악할 필요가 있다.
또 airflow-webserver로 예를 들면 이미 웹서버가 돌아가고 있으면, 새롭게 웹서버를 띄우려고 할 때 이미 실행 중임을 알고 중복 실행을 방지할 수 있어야 한다. 이때 PID 파일이 사용된다.
또 서비스가 중지될 때, PID 번호를 참조하여 kill -TERM [PID]
식으로 프로세스를 종료할 수 있다.
예시) Airflow-webserver에서의 PID 파일의 동작
실행 시 생성 : 웹서버가 시작될 때 프로세스 ID를 PID 파일에 기록한다.
정상 종료 시 제거 : 웹서버가 정상적으로 종료되면, 종료 과정에서 이 PID 파일을 지운다.
- 만약 비정상 종료 되거나 에러로 제대로 정리되지 못했다면 PID 파일만이 남아 Error: Already running on PID XXXX (or pid file ‘…’ is stale)와 같은 오류가 발생할 수 있다.
웹서버는 죽어도 스케줄러가 살아있으면 dag들은 정상작동 한다.
웹 서버가 작동을 안하고 있어 파이프라인이 돌지 않고 있을거라 예상했는데 파이프라인은 정상 작동 하면서 데이터들이 갱신 되고 있음을 확인할 수 있었다.
“웹 서버는 말 그대로 UI를 제공하는 툴이고, 실제로 DAG를 실행하고 파이프라인을 돌리는 것은 스케줄러(with executor/worker)가 담당한다. 웹서버가 죽어도 스케줄러가 살아있으면 DAG들은 정상 작동한다.”
스케줄러(scheduler)의 실제 역할
새 DAG나 태스크 실행이 필요한지 감지
태스크를 실행 가능한 상태(Queued, Scheduled)로 변경
실제 작업은 Executor(LocalExecutor, CeleryExecutor 등) 및 Worker(작업을 실제 수행하는 프로세스)가 담당
메타데이터 DB(metadata database)
Airflow의 핵심 엔진 역할을 하는 DB로, DAG 스케줄 정보, 태스크 상태, 로그인 사용자 정보 등을 저장
웹서버나 스케줄러는 모두 이 DB와 통신하여 상태를 확인하고 업데이트함
웹서버(airflow webserver)
DAG, 태스크 상태 모니터링과 실행/정지/로그 조회 등 UI 기능 제공
“이미 실행 중” 문제(위에서 언급한 PID 파일 관련) 등은 주로 웹서버 쪽에서 발생
워커(worker) / Executor
- 스케줄러가 태스크를 실행하라고 지시하면, 워커(Executor)가 그 태스크를 수행
나는 web server와 scheduler 서비스만 실행시켰는데 worker 서비스는 어떻게 돌아가는건가?
Airflow에서 worker 프로세스가 따로 있는지는 Executor
설정에 따라 달라진다.
즉, airflow.cfg
의 executor
항목이 무엇이냐에 따라 다음이 달라진다.
SequentialExecutor (기본값, 소규모 테스트용)
LocalExecutor
CeleryExecutor
KubernetesExecutor
기타 커스텀 Executor 등
Local이나 Sequential Executor라면 별도의 워커 프로세스를 띄울 필요가 없다.
- 스케쥴러 프로세스가 내부적으로 태스크를 실행(프로세스/스레드 생성)하며 워커 역할까지 겸하게 되는 것이다.
CeleryExecutor(분산 실행)라면 celery worker를 따로 구동해 프로세스를 여러 대 띄워서 분산 실행을 한다.
KubernetesExecutor라면 태스크 하나하나를 Kubernetes Pod으로 배포해 실행하기 때문에 따로 워커 프로세스를 띄우지 않아도 된다. 하지만 당연히 쿠버네티스 클러스터가 있어야 한다.
좀비 프로세스란?
자식 프로세스가 종료되었지만, 부모 프로세스가 wait()
회수 명령을 호출하지 않아 생긴 “죽은 프로세스의 잔해” 같은 존재
- 비정상 종료/처리가 있었음을 보여주는 간접 지표에 가깝다.
💡 wait()을 호출하면 어떻게 되는데?
wait()
또는waitpid()
는 부모 프로세스가 자식 프로세스의 종료 사태를 회수하여 자식 프로세스가 완전히 정리되도록 해주는 함수이다.
자식 프로세스가 종료하면, 커널은 자식의 종료 코드를
좀비
형태로 프로세스 테이블에 남겨둔다. 이때 자식은 이미 종료됐으므로 CPU나 메모리를 실질적으로 사용하진 않지만, 프로세스 테이블 항목은 남아 있는좀비 상태
가 된다!부모 프로세스가 wait()을 호출하면
커널이 자식 프로세스의 종료 상태(Exit Code 등)를 부모에게 반환한다.
프로세스 테이블에서 해당 자식 프로세스 정보를 제거해서 좀비상태가 사라진다. 결과적으로 좀비 프로세스는 사라지고 자식 프로세스는 완전히 시스템에서 정리되는 것이다.
부모가 자식 프로세스가 종료되었다는 사실을 알고(시그널을 통해) wait()을 적절히 호출해야만 좀비가 해소되는 것이다
→ 좀비 프로세스가 있다는 것은 정상적인 종료가 되지 않았다는 것!
Subscribe to my newsletter
Read articles from 정세욱 directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
