Skip to content
isdnetworks
Go back

큐에 쌓인 것이 두 종류다

jobs 표에 처리 대기가 수천 건 쌓였다.

재투입 명령을 돌렸는데 건수가 안 줄었다. 다시 돌려도 여전히 그대로였다.

Table of contents

Open Table of contents

대기가 두 종류였다

명령이 성공했는데 상태가 안 바뀌면 그 명령이 이 상황에 안 맞는 것이다. 큐 테이블을 자세히 보니 상태 컬럼 말고 시각 컬럼이 세 개 있었다.

queued_at    큐에 들어온 시각
started_at   워커가 집어간 시각
finished_at  끝난 시각

대기 중인 것들을 started_at 기준으로 나눠 봤다.

상태건수
started_at 없음40아직 안 꺼냄
started_at 있고 finished_at 없음3,200워커가 이미 가져감

대부분이 두 번째였는데 안 꺼내진 것이 쌓인 게 아니라 꺼내 갔는데 안 끝나고 있는 것이었다.

대기 중이라는 한 상태가 성격이 다른 둘이었다. 화면에 같은 글자로 찍히니 구분할 생각을 안 했다.

원인 — 재투입이 무의미했던 이유

재투입 명령은 started_at 이 없는 것만 다시 큐에 넣는데 그것은 40건뿐이었다.

나머지 3,200건은 이미 worker 손에 있어서 다시 넣어도 중복 처리 위험만 생긴다.

봐야 할 곳이 jobs 가 아니라 워커였고 명령을 두 번 돌린 시간은 통째로 헛수고였다.

두 종류를 안 가른 채 조치를 고른 것이 문제였고 가르고 나면 안 맞는다는 것이 바로 보인다.

워커가 도는지 확인하기

워커가 살아 있는지는 ps 로 아는데 살아 있으면서 일을 안 하는 경우가 있다.

그래서 최근 완료 건수를 함께 봤다.

SELECT COUNT(*) FROM jobs
WHERE finished_at > NOW() - INTERVAL 5 MINUTE;

finished_at 이 최근 5분 안인 건을 센다.

관측판정
최근 5분 완료가 수백 건워커 정상, 그냥 밀린 것
최근 5분 완료가 한 자릿수워커가 멈췄거나 특정 작업에 걸림

한 자릿수였고 프로세스는 떠 있는데 사실상 멈춰 있는 상태였다.

살아 있음과 일하고 있음이 다른 확인이다. 앞은 ps 로 보고 뒤는 COUNT(*) 로 본다.

무엇에 걸렸나

워커 로그를 보니 한 작업에서 계속 재시도하고 있었다. 외부 응답이 안 와 타임아웃까지 기다리기를 반복했다.

그 하나가 워커를 붙잡고 뒤의 3,200건이 그것을 기다렸는데 단일 스레드 워커라 더 그랬다.

하나가 오래 걸리면 그 worker 는 아무것도 못 한다. 큐가 안 준다는 현상의 실체가 이 한 건이었다.

조치 — 상한과 격리와 분리

셋을 고쳤는데 첫째는 재시도에 상한을 둔 것이다.

무한히 시도하지 않고 세 번 실패하면 기록하고 넘어간다. 둘째는 실패 작업을 별도 큐로 뺀 것이다.

계속 실패하는 것이 정상 작업을 막지 않게 하려는 것이다. 셋째로 worker 를 여러 개로 나눴다.

하나가 막혀도 나머지가 도는데 부분적인 대책이라 같은 이유로 전부 막힐 수는 있다.

전체 흐름 — 진단 순서

큐가 안 줄어든다는 제보를 받으면 이 순서로 본다.

1. 대기를 두 종류로 나눈다 — 안 꺼낸 것과 처리 중인 것
2. 안 꺼낸 게 많으면 → 워커 수 부족이거나 투입이 안 되는 것. 재투입·증설
3. 처리 중인 게 많으면 → 워커를 본다. 재투입은 무의미
4. 최근 완료 건수를 센다 — 워커가 도는지 멈췄는지 갈린다
5. 멈췄으면 무엇에 걸렸는지 로그에서 찾는다

둘째와 셋째의 조치가 정반대라는 것이 요점이다. 구분 안 하고 재투입만 반복하면 아무것도 안 바뀐다.

첫째를 건너뛰면 나머지 넷이 전부 엉뚱한 자리를 향하는데 이번이 그랬다.

대장에 없으면 안 돈다

부수적으로 하나를 더 발견했는데 어떤 작업 종류가 자동 투입 스케줄에 아예 등록이 안 돼 있었다.

수동으로 넣지 않으면 영원히 대기이고 jobs 에는 있는데 아무도 안 꺼내 간다.

이것도 겉으로는 jobs 에 대기가 쌓이는 것으로만 보인다. 앞의 둘과 또 다른 세 번째 경우다.

그래서 스케줄 등록 목록과 실제 작업 종류를 대조하는 점검을 넣었다. 새 종류를 추가하고 등록을 빠뜨리면 그때 잡힌다.

정리


Share this post on:

Previous Post
변화의 부호를 봤다
Next Post
한 대뿐이라 손댈 수가 없었다