🌳 고급 system
데드락(Deadlock)이 뭔가요?
쉽게 이해하기
좁은 골목길에서 두 차가 정면으로 마주쳤는데 둘 다 양보 안 하고 버티는 상황이에요. A차는 B차가 비켜줘야 가고, B차는 A차가 비켜줘야 가는데 둘 다 안 비키니까 영원히 막혀버리는 거죠. 프로그램에서도 A 작업이 B 자원을 기다리고, B 작업이 A 자원을 기다리면 둘 다 멈춰버려요.
핵심 정리
두 개 이상의 프로세스가 서로를 기다리며 영원히 멈춰버리는 상황이에요.
자세히 알아보기
데드락은 두 개 이상의 프로세스나 스레드가 서로가 가진 자원을 기다리면서 무한정 대기 상태에 빠지는 현상이에요. 멀티스레딩 환경에서 자주 발생하는 문제죠.
구체적인 예를 들어볼게요. 스레드 A가 데이터베이스 테이블 1을 잠그고(Lock) 테이블 2를 기다리고 있어요. 동시에 스레드 B는 테이블 2를 잠그고 테이블 1을 기다리고 있죠. 이러면 A는 B가 테이블 2를 풀어줘야 하고, B는 A가 테이블 1을 풀어줘야 하는데 둘 다 안 풀어주니까 영원히 멈춰버려요. 실제로 은행 시스템에서 계좌 간 이체를 처리할 때 이런 데드락이 발생하면 전체 거래가 멈출 수 있어요.
데드락이 발생하려면 4가지 조건이 동시에 만족되어야 해요. (1) 상호 배제: 자원을 한 번에 하나의 프로세스만 쓸 수 있어야 하고, (2) 점유와 대기: 자원을 가진 채로 다른 자원을 기다려야 하고, (3) 비선점: 다른 프로세스가 강제로 자원을 뺏을 수 없어야 하고, (4) 순환 대기: 프로세스들이 원형으로 서로를 기다려야 해요. 이 중 하나라도 깨면 데드락을 예방할 수 있죠.
실무에서는 여러 방법으로 데드락을 해결해요. 타임아웃을 설정해서 일정 시간 대기 후 자동으로 포기하게 하거나, 자원을 요청하는 순서를 정해서 순환 대기를 막거나, 데드락 감지 알고리즘으로 발생 시 강제로 하나를 종료시키는 거죠. 데이터베이스는 보통 자동으로 데드락을 감지해서 한 트랜잭션을 롤백시켜요.
쿠버네티스에서도 데드락이 발생할 수 있어요. Pod A가 리소스를 요청했는데 노드에 공간이 없어서 Pod B가 종료되기를 기다리고, Pod B도 마찬가지로 Pod A가 종료되기를 기다리면 클러스터 전체가 멈출 수 있거든요. 그래서 리소스 제한과 우선순위를 잘 설정하는 게 중요해요.