Dify 플러그인 데몬의 스레드 누수에 대한 임시 해결 방법

Dify 플러그인 데몬의 스레드 누수에 대한 임시 해결 방법

3 min read

 

문제 개요 #

발생 현상:

  • 대량의 지식 베이스 문서를 인덱싱하면 플러그인 데몬(plugin_daemon)이 무수한 스레드를 계속 생성하여 최종적으로 “약 30,000개”에서 새 스레드를 생성할 수 없게 됩니다.
  • 컨테이너 로그에 can't start new thread 오류가 발생하고 서비스가 정지됩니다.

추정 원인:

  • 컨테이너/cgroup v2의 pids.max(프로세스+스레드 상한)가 29958(약 3만)로 설정되어 있어 이를 초과하는 시점에 스레드 생성이 실패합니다.
  • 플러그인 데몬 측의 스레드 누수 또는 대량 동시 처리로 인해 단시간에 스레드 수가 비대해지고 있습니다.

시행착오:

  • Docker Compose나 컨테이너 내에서 pids_limit: 0 또는 ulimit를 조정해도 호스트의 cgroup이 29958로 고정되어 있어 효과가 없었습니다.
  • /sys/fs/cgroup/system.slice/docker-.scope/pids.max의 실제 값을 확인한 결과 29958이었습니다.

근본 해결책 #

  • 플러그인 데몬 측의 스레드 누수 수정(업데이트 또는 패치 적용).
  • 한 번에 처리하는 문서 수를 분할하여 스레드가 과도하게 증가하지 않도록 합니다.

임시 대응책 #

  • 호스트의 cgroup 설정을 변경하여 pids.max를 max(무제한) 또는 큰 값으로 상향 조정합니다.
  • 함께 systemd의 slice 유닛(system.slice 등)에서 TasksMax=infinity를 설정하여 재시작 후에도 원래대로 돌아가지 않도록 합니다.

임시 대응 절차(단계별) #

STEP 1. 컨테이너의 “호스트 측 PID”에서 cgroup 경로 특정 #

컨테이너 ID 확인:

docker ps

플러그인 데몬은 998eb0c50703 등의 ID입니다.

docker top <컨테이너ID>로 호스트상의 PID 획득:

docker top 998eb0c50703

예: /app/main 프로세스가 1012512(호스트 PID) 등.

/proc/<호스트PID>/cgroup 참조:

cat /proc/1012512/cgroup

출력 예: 0::/system.slice/docker-998eb0c5070321...scope

STEP 2. 실제 상한값(pids.max) 변경 #

해당 디렉터리로 이동하여 pids.max 확인:

cd /sys/fs/cgroup/system.slice/docker-998eb0c5070321...scope
cat pids.max

값이 29958 등 숫자로 되어 있으면 제한 있음, max이면 무제한입니다.

무제한으로 변경:

echo max | sudo tee pids.max

이것으로 “현장에서는” 제한이 해제되지만, 재시작이나 컨테이너 재생성 시 원래대로 돌아갈 가능성이 높습니다.

STEP 3. systemd 설정으로 TasksMax를 영구적으로 무제한화 #

cgroup 설정이 리셋되지 않도록 systemd의 slice 유닛(system.slice)에서 TasksMax를 덮어씁니다:

3-1. 오버라이드 파일 생성: #

sudo systemctl edit --force --full system.slice

에디터가 열리면 다음과 같이 [Slice] 섹션을 추가하여 저장합니다:

[Slice]
TasksMax=infinity

3-2. 데몬 리로드 & 재시작: #

sudo systemctl daemon-reload
sudo systemctl restart docker
docker-compose를 사용하는 경우 일단 docker-compose down && docker-compose up -d 등으로 컨테이너를 재시작하십시오.

새로 컨테이너가 생성될 때 TasksMax=infinity가 반영됩니다.

3-3. 반영 확인: #

systemctl show system.slice -p TasksMax
# => TasksMax=infinity이면 OK

cat /sys/fs/cgroup/system.slice/pids.max
# => max이면 OK

또한 컨테이너가 시작되면 다시 “STEP 1~2″의 방법으로 /sys/fs/cgroup/system.slice/docker-.scope/pids.max를 확인하여 max로 되어 있는지 체크합니다.

STEP 4. (필요에 따라) 커널 파라미터 등 체크 #

커널의 스레드/PID 상한:

sysctl kernel.threads-max
sysctl kernel.pid_max

만약 작은 값(3만~6만 정도)이라면 더 상향 조정이 필요합니다.

sudo sysctl -w kernel.threads-max=200000

영구화하려면 /etc/sysctl.confkernel.threads-max=200000 등을 추가합니다.

systemd 전체의 기본 TasksMax:

cat /etc/systemd/system.conf

만약 /etc/systemd/system.confDefaultTasksMax=65535 등의 기술이 있다면 모든 서비스에 적용될 수 있습니다.

이를 infinity로 변경하고 재시작하면 더욱 확실합니다.

정리 #

  • 문제의 원인:cgroup v2의 pids.max가 약 30000으로 고정되어 있어 플러그인 데몬이 대량의 스레드를 생성하기 때문에 한계에 도달합니다.
  • 임시 대응책:/sys/fs/cgroup/system.slice/docker-.scope/pids.max를 max로 변경하여 제한을 완화합니다. 추가로 systemd slice에 TasksMax=infinity를 설정하여 재시작 시에도 원래대로 돌아가지 않도록 합니다.
  • 보충:스레드 수가 비정상적으로 증가하는 근본 원인(애플리케이션의 스레드 누수)을 수정하지 않으면 결국 메모리 부족 등 다른 문제가 발생할 가능성이 있습니다. 가능하다면 소프트웨어 업데이트나 배치 분할 처리 등으로 근본 해결을 도모하십시오.

이상의 절차로 “약 29958 상한에 도달하여 정지되는 문제”를 회피할 수 있습니다.

 

Updated on 2026年6月9日

What are your feelings

  • Happy
  • Normal
  • Sad