라이브락 (Livelock)과 교착 상태(Deadlock)의 차이점
핵심 인사이트 (3줄 요약)
- 본질: 교착 상태(Deadlock)가 서로 멱살을 잡고 아무것도 안 하며 멈춰버린 '얼음(Frozen)' 상태라면, 라이브락(Livelock)은 서로 양보하겠다고 계속 길을 비켜주느라 스텝이 꼬여서 둘 다 전진하지 못하고 춤만 추는 '헛발질(Active-Wait)'의 병적 상태다.
- 가치: 데드락은 CPU를 갉아먹지 않고 그저 자원만 점유한 채 잠들어 있지만, 라이브락은 서로 양보하겠다는 무한 반복 로직 속에서 CPU 연산 100%를 불태우며 스레드를 혹사시키기 때문에 시스템 과부하 측면에서 훨씬 끔찍한 파괴력을 지닌다.
- 융합: 라이브락은 OS 차원의 고전적 락 체계보단 현대 비동기 분산 시스템(네트워크 패킷 충돌, 분산 락 양보)에서 발현되며, 이를 파훼하려면 서로 동일한 타이밍에 양보하는 것을 막기 위해
랜덤 지연 시간(Randomized Backoff / Jitter)을 융합해 엇박자를 강제하는 것이 국룰이다.
Ⅰ. 개요 및 필요성
교차로에서 두 사람이 마주쳤다.
데드락(Deadlock): 둘 다 "네가 안 비키면 나도 안 비켜!" 라며 가만히 서 있는 상태. 서로 눈을 부라리며 영원히 서 있는다.
라이브락(Livelock): 착한 두 사람이 서로 비켜주겠다고 왼쪽으로 한 발짝 옮겼다. 어라? 둘 다 똑같이 왼쪽으로 옮겨서 또 마주쳤다. "아이고 죄송합니다" 하고 이번엔 둘 다 오른쪽으로 옮겼다. 또 마주쳤다. 이걸 1초에 1억 번씩 무한 반복하며 땀을 뻘뻘 흘리는데(CPU 폭발), 정작 앞으로 한 발짝도 걷지 못한다(실제 진척도 0%).
💡 비유: 데드락은 통화 중 대기라 아무 소용 없이 귀만 대고 있는 거고, 라이브락은 서로 자기가 끊겠다고 "제가 끊겠습니다", "아닙니다 제가 끊죠", "그럼 하나 둘 셋 하면 같이 끊죠" 이 대화만 1시간째 하면서 둘 다 전화를 못 끊는 바보 같은 상황이다. 활동은 엄청나게 하는데 결과가 없다.
┌─────────────────────────────────────────────────────────────────┐
│ Deadlock (교착) VS Livelock (라이브락)의 생체 신호 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ [ Deadlock: 멈춤의 미학 ] │
│ P1: "락 A 잡고 락 B 대기 (SLEEP 모드 진입)" │
│ P2: "락 B 잡고 락 A 대기 (SLEEP 모드 진입)" │
│ ▶ OS 센서: CPU 점유율 0%, 애들 다 자고 있음. 완전 조용함. │
│ │
│ [ Livelock: 발광의 헛발질 ] │
│ P1: "락 A 잡았다. 어? 락 B 못 잡나? 그럼 락 A 풀고 양보!" │
│ P2: "락 B 잡았다. 어? 락 A 못 잡나? 그럼 락 B 풀고 양보!" │
│ (... 0.1초 뒤 둘 다 락 잡고 또 동시에 풀고 무한 반복 ...) │
│ ▶ OS 센서: CPU 점유율 100%!!! 미친 듯이 연산을 하고 로그를 │
│ 찍는데, 정작 처리된 트랜잭션 건수는 0건! │
└─────────────────────────────────────────────────────────────────┘
📢 섹션 요약 비유: 데드락은 컴퓨터가 멈춰서 얼음이 된 거고, 라이브락은 눈코 뜰 새 없이 엄청 바쁘게 움직이는데 정작 쓰레기 하나 제대로 쓰레기통에 못 넣고 계속 허공에 헛스윙만 날리고 있는 코미디(CPU 낭비)입니다.
Ⅱ. 아키텍처 및 핵심 원리
발생 원인: "어설픈 데드락 회피 장치"의 부작용
웃기게도 라이브락은 대부분 "개발자가 데드락을 없애보겠답시고 어설프게 양보 로직(Rollback/Retry)을 기입했을 때" 발생한다.
- 상호 교인 락 (Politeness Mechanism):
- 데드락 예방을 위해 스레드가 락을 기다리다 안 되면
자발적 Un-lock (락 해제)을 하고 재도전(Retry) 하도록 코드를 짰다.
- 데드락 예방을 위해 스레드가 락을 기다리다 안 되면
- 동기화된 뻘짓 (Synchronized Retry):
- 스레드 둘의 속도와 클럭이 똑같기 때문에, 정확히 동시에 자기 락을 풀고, 정확히 동시에 다시 락을 잡는다.
- 계속해서 동기화된 리듬으로 둘 다 양보하고 둘 다 침투하는 짓을 반복하며, 아무도 두 개의 락을 전부 잡아내는(Critical Section 돌파) 데 성공하지 못한다.
📢 섹션 요약 비유: 데드락 룰 피하려다가 생기는 병입니다. "두 사람이 마주치면 가위바위보를 해서 진 사람이 양보합시다!" 라고 짰는데, 둘 다 항상 똑같이 '바위'만 내는 바람에 평생 가위바위보만 계속하면서 길을 못 지나가는 버그죠.
Ⅲ. 융합 비교 및 다각도 분석
| 진단 기준 | 교착 상태 (Deadlock) | 라이브락 (Livelock) |
|---|---|---|
| 프로세스의 상태 | 블록됨 (Blocked, 무한 슬립) | 러닝 중 (Running, 무한 폭주) |
| CPU 사용률 | 시스템이 놀고 있음 (0%대) | CPU 풀 로드 (100% 불타오름) |
| 자원의 상태 | 잡고 놔주질 않음 (Hold & Wait) | 잡았다 풀었다(Acquire & Release) 무한 진동 |
| 타파 방법 | 누군가 메스로 잘라 죽여야 함 (Abort) | 타이밍(박자)만 엇갈리게 흩트려주면 탈출함 |
📢 섹션 요약 비유: 환자에 비유하자면, 데드락은 마취를 맞고 수술대 위에서 곯아떨어져 깨어날 가망이 없는 코마(Coma) 환자고, 라이브락은 병실에서 쉬지 않고 제자리 점프를 천만 번 뛰면서 심장이 터지기 직전인 과잉 행동 장애 환자입니다.
Ⅳ. 실무 적용 및 기술사적 판단
실무 시나리오:
- 이더넷 CSMA/CD 충돌 회피 (네트워크 융합): 라이브락을 설명하는 가장 위대한 실전 사례다. 두 컴퓨터가 네트워크 선에 동시에 데이터를 쏴서 꽝 충돌(Collision)이 났다. 둘 다 "아쿠 충돌이네, 물러납시다" 하고 양보한다. 근데 둘 다 정확히 1초 뒤에 다시 데이터를 쏜다? 또 충돌(양보)난다. 이 라이브락을 격파하기 위해서 랜카드 설계자들은 Exponential Backoff (랜덤 지연 재전송) 알고리즘을 넣었다. 한 놈은 1.1초 뒤에, 한 놈은 0.3초 뒤에 난수(Random)로 엇박자를 만들어 재전송하게 만듦으로써 라이브락 고리를 영원히 끊어버렸다.
안티패턴:
- 고정 시간(Fixed Time) 재시도 루프: MSA 구동 환경에서 외부 결제 서버 A, B가 동시에 접근하다 에러가 터졌을 때, 개발자가
Thread.sleep(100)을 고정값으로 박아두면? 둘 다 사이좋게 0.1초 쉬었다가 다시 접근해서 꽝 터지고 영원히 라이브락에 빠진다. 고정 Sleep은 라이브락을 유도하는 최악의 독약 트리거다.
📢 섹션 요약 비유: 라이브락을 박살 내는 유일한 약은 "랜덤(무작위성)"입니다. 가위바위보로 100번 비겼으면, 그냥 "아무나 타이머 주사위 굴려서 늦게 나온애가 먼저 출발해!" 라며 시계를 고장 내버려야(Jitter) 해결됩니다.
Ⅴ. 기대효과 및 결론
| 기준 | 어설픈 교착 회피 코딩 (라이브락 유발) | 해커 정신의 랜덤 딜레이 (Jitter) |
|---|---|---|
| 시스템 비용 | CPU 100% 점유율 폭발, 클라우드 과금 지옥 | 0.01초 늦게 출발하는 약간의 레이턴시로 안정 달성 |
| 해결 방향성 | OS가 개입해 죽여도 계속 스텝이 또 꼬임 | 자기들끼리 엇박자 타며 자연스럽게 스르르 풀림 |
라이브락 (Livelock)은 데드락이라는 고요한 죽음을 막기 위해 인간이 삽입한 어설픈 양보 코드(Retry Policy)가 만들어낸 사생아다. 프로세스들은 살아있음을 증명(Live)하려 미친 듯이 연산하지만 일의 진척(Progress)은 제로에 수렴한다. 이 아이러니를 파괴한 것은 고도화된 스케줄링 이론이 아닌, 시간의 공정성을 깨부수는 무작위 난수(Randomized Backoff / Jitter)라는 극도의 인간적(비합리적) 트릭이었음을 인지하는 것이 핵심 설계 미학이다.
📌 관련 개념 맵
| 개념 | 관계 |
|---|---|
| 교착 상태 (Deadlock) | 라이브락의 거울 반대편에 있는 얼음 괴물. 멈춰있는 데드락과 뛰어다니는 라이브락. |
| 지수 백오프 (Exponential Backoff) | 이더넷 네트워크에서 라이브락(무한 충돌)을 막기 위해 창조된 위대한 엇박자 주사위 알고리즘 |
| 기아 상태 (Starvation) | 데드락 조치하려고 한 애만 집단 구타하다 생겼다면, 라이브락은 둘이서 서로 양보하며 자발적으로 안 먹다가 굶어 죽는 것 |
| Active-Waiting (바쁜 대기) | 라이브락이 미친 듯이 CPU를 잡아먹으며 춤추는 근본적인 물리적 엔진 |
👶 어린이를 위한 3줄 비유 설명
- "데드락"은 외나무 다리에서 만난 두 마리의 염소가 "네가 안 비키면 나도 안 비켜!" 라며 뿔을 맞대고 멈춰서 얼음이 된 상태예요.
- "라이브락"은 너무 착한 두 마리의 양이 서로 지나가라고 "오른쪽으로 비켰다, 왼쪽으로 비켰다"를 동시에 똑같이 무한 반복하면서 평생 춤만 추는 상태예요!
- 데드락은 조용히 길만 막히지만, 라이브락은 피곤하게 계속 왔다 갔다 체력(CPU)을 다 써버리니까 엇박자로 눈치 게임을 시켜(랜덤 대기) 해결해야 한답니다!