Durable scheduler 소개
n8n v2.34요약
durable scheduler는 Schedule Trigger 노드로 시작하는 것과 같은 시간 기반 워크플로를, 각 인스턴스의 메모리 대신 데이터베이스 기반 큐에서 실행합니다. durable scheduler는 환경 플래그 뒤에 있는 프리뷰 기능입니다.
durable scheduler는 Schedule Trigger 노드로 시작하는 것과 같은 시간 기반 워크플로를, 각 인스턴스의 메모리 대신 데이터베이스 기반 큐에서 실행합니다. 이 페이지에서는 durable scheduler가 무엇을 변경하는지, 켜는 방법, 작동 방식을 설명합니다. 이를 구성하는 환경 변수는 스케줄러 환경 변수를 참고하세요.
프리뷰 기능
durable scheduler는 환경 플래그 뒤에 있는 프리뷰 기능입니다. 이 기능이 일반 출시(GA)에 도달하기 전까지 환경 변수와 기본 동작이 변경될 수 있습니다.
durable scheduler는 기본적으로 꺼져 있으며 점진적으로 롤아웃되고 있습니다. 기존 인스턴스는 옵트인하기 전까지 계속 인메모리 스케줄러를 사용하며 이전과 동일하게 동작합니다. n8n은 먼저 프로덕션이 아닌 환경에서 테스트해볼 것을 권장합니다.
인메모리 스케줄러와 durable scheduler 비교#
n8n은 기본적으로 시간 기반 워크플로를 메모리에서 스케줄링합니다. 각 main 인스턴스는 활성 스케줄이 언제 실행되어야 하는지 스스로 계산하고, 해당 타이머를 자신의 프로세스 안에 보관합니다. 이 방식은 단일 인스턴스에서는 잘 작동하지만 다음과 같은 한계가 있습니다.
- 재시작 시 대기 중인 실행이 유실됩니다. 인스턴스가 중지되면 메모리 안의 타이머도 함께 사라집니다. n8n은 다운타임 동안 시각이 지난 실행을 나중에 따라잡지 않고 건너뜁니다.
- 여러 인스턴스에는 리더가 필요합니다. 멀티 메인 구성에서는 리더만 스케줄을 실행합니다. 잘못된 시점에 리더십이 바뀌면 타이밍이 어긋날 수 있습니다.
durable scheduler는 스케줄링을 데이터베이스로 옮겨 이 두 가지 문제를 모두 해결합니다.
- 재시작해도 실행이 유지됩니다. 스케줄러는 예정 시각이 되기 전에 다가오는 각 실행을 데이터베이스에 기록합니다. 재시작해도 실행이 유실되지 않습니다. 인스턴스가 중단된 동안 시각이 지난 실행도 인스턴스가 복구되면 실행되므로, 아예 실행되지 않는 대신 늦게라도 실행됩니다.
- 각 실행은 인스턴스 전체에서 정확히 한 번만 실행됩니다. 모든 main 인스턴스가 동일한 큐를 공유하며 그 큐에서 실행을 확보(claim)합니다. 각 실행은 하나의 인스턴스만 가져가므로, 작업이 단일 리더에 의존하지 않고 main 인스턴스 전체에 분산됩니다.
기능적으로 달라지는 점#
durable scheduler를 켜면 다음과 같은 동작 변화를 유의하세요.
- 타이밍 정확도. 스케줄러는 짧은 주기(
N8N_SCHEDULER_EXECUTOR_INTERVAL, 기본값 5초)로 예정된 실행을 확인하므로, 실행이 예정 시각으로부터 최대 한 주기만큼 늦게 시작될 수 있습니다. 인메모리 스케줄러는 정확한 시각에 더 가깝게 실행됩니다. - 시계 정렬 타이밍이 기본값입니다. "매 N초"와 "매 N분" 스케줄의 경우,
N8N_SCHEDULER_TRIGGER_NODE_MODE를 변경하지 않는 한 durable scheduler는 인메모리 스케줄러와 동일한 시계 정렬(clock-aligned) 타이밍을 유지합니다. Schedule Trigger 타이밍을 참고하세요. - 다운타임 이후의 지연된 실행. 스케줄러가 실행을 미리 기록해두기 때문에, 다운타임 중에 놓친 실행은 유실되지 않고 인스턴스가 복구되면 실행됩니다.
Durable scheduler 켜기#
옵트인하려면 N8N_SCHEDULER_ENABLED를 true로 설정하세요.
durable scheduler는 워크플로 게시 서비스(workflow publication service)도 켜져 있을 때만 Schedule Trigger 노드를 인계받습니다. N8N_SCHEDULER_ENABLED와 N8N_USE_WORKFLOW_PUBLICATION_SERVICE를 모두 true로 설정하세요. 게시 서비스 없이 스케줄러만 활성화하면 n8n이 경고 로그를 남기고 Schedule Trigger 노드는 계속 인메모리 스케줄러에서 실행됩니다.
나머지 변수는 스케줄러가 켜진 후에만 적용됩니다. 기본값은 대부분의 인스턴스에 적합하므로, 타이밍 정확도, 스토리지, 인스턴스 간 부하를 조정할 때만 값을 변경하세요. 별도로 명시하지 않는 한 모든 시간 단위는 초입니다.
Durable scheduler 작동 방식#
다음 용어를 알아두면 환경 변수를 이해하기 쉽습니다.
- 스케줄(Schedule): Schedule Trigger 노드의 "매 15분" 설정과 같은 반복 규칙입니다. 스케줄러는 각 스케줄을 데이터베이스에 저장합니다.
- 실행(Run): 특정 시각에 스케줄이 한 번 발생하는 것을 말합니다. 스케줄러는 다가오는 실행을 개별 행(row)으로 미리 기록합니다.
스케줄러는 각 실행을 네 단계로 진행시키며, 각 단계마다 자체 환경 변수가 있습니다.
- 구체화(Materialization). 스케줄러는 활성 스케줄을 스캔하여 (구체화 윈도우 내에서) 곧 다가올 실행을 기록합니다. 이는 실행이 예정 시각이 되기 전에 데이터베이스에 커밋되도록 합니다.
- 실행(Execution). 스케줄러는 시각이 도래한 기록된 실행을 확인하고, 다른 인스턴스가 가져가지 못하도록 각 실행을 확보(claim)한 다음 워크플로를 시작합니다.
- 복구(Recovery). 인스턴스가 실행을 확보했지만 완료 전에 중지되면(예: 크래시 이후), reaper가 해당 실행을 해제하여 다른 인스턴스가 가져갈 수 있게 합니다.
- 보존(Retention). 스케줄러는 완료된 실행을 최근 이력으로 얼마간 보관한 다음, 테이블을 작게 유지하기 위해 삭제합니다.
여러 인스턴스에 걸쳐, 모든 main이 네 단계를 모두 실행합니다. 확보(claim) 방식 덕분에 이는 안전합니다. 각 실행을 하나의 인스턴스만 확보하므로, 모든 곳에서 루프를 실행해도 작업이 중복되지 않고 분산됩니다.
Schedule Trigger 타이밍(차이점)#
durable scheduler에서는 대부분의 Schedule Trigger 스케줄이 인메모리에서와 동일한 방식으로 실행됩니다. 위에서 설명한 인스턴스 전체 차원의 변화(다운타임 이후의 지연 실행, 인스턴스 전체에서 각 실행이 한 번만 실행됨) 외에도, 특정 경우 두 가지 주기가 인메모리 스케줄러와 다르게 실행됩니다.
- "매 N초"와 "매 N분".
N8N_SCHEDULER_TRIGGER_NODE_MODE가 이 실행 방식을 제어합니다. 이 설정이 영향을 주는 유일한 주기입니다. - "매 N시간", "일", "주", "월". 이러한 주기는 어떤 모드에서든 일상적인 사용에서는 이전과 동일하게 실행됩니다. durable scheduler는 윤년, 한 해의 53번째 주, 일광 절약 시간 전환처럼 인메모리 스케줄러가 한 주기만큼 어긋날 수 있는 드문 달력 경계 사례를 더 정확하게 처리합니다.
N8N_SCHEDULER_TRIGGER_NODE_MODE에는 두 가지 값이 있습니다.
legacy(기본값): 인메모리 스케줄러와 동일하게 시계 경계에서 실행됩니다. "매 30초"는 매 분의 :00과 :30에 실행됩니다. 이 패턴은 매 분의 시작에서 다시 시작되므로, 60으로 나누어떨어지지 않는 간격은 분 경계에서 고르지 않은 간격이 남습니다. "매 7초"는 :00, :07, :14부터 :56까지 실행된 다음 다시 :00으로 돌아가, 7초가 아닌 4초의 간격이 생깁니다.new: 워크플로를 활성화한 시점부터, 시계 경계가 아니라 고정된 초 간격으로 실행됩니다. :07에 활성화하면 "매 30초"는 :07, :37, :07 순으로 실행됩니다. 분 경계를 넘나들어도 간격이 설정한 값 그대로 유지되므로, "매 7초"는 절대 어긋나지 않습니다.
legacy가 기본값이므로 durable scheduler가 롤아웃되는 동안 타이밍은 그대로 유지됩니다. new는 향후 기본값이 될 예정입니다.
N8N_SCHEDULER_TRIGGER_NODE_MODE는 "매 N초"와 "매 N분" 스케줄에만 영향을 줍니다. 원시 cron 표현식을 포함한 다른 모든 주기는 어느 값을 설정하든 동일하게 실행됩니다.