[Java] 대용량 데이터 전산 처리 방안(유량제어) 3 - 향후 고려사항 : 데드락(교착상태)

Hyo Kyun Lee·2024년 11월 11일
0

Java

목록 보기
61/66

1. 개요

대용량 데이터 전산 처리 성능 개선 작업을 진행하면서 동시성 제어와 유량 제어 뿐만 아니라 여러 다른 고려사항까지 생각하면서 공부를 해보았는데, 다른 스레드의 무한 로딩 혹은 한 스레드의 자원 무한 점유 상태까지 고려해야 하지 않을까하는 생각을 하게 되었다.

성능테스트를 최대 11.933TPS까지 진행을 하는데, 해당 부하까지 데드락 상태가 발생하지는 않았으나, 더 많은 사용자와 더 많은 TPS 조건에서 단순히 동시성 제어만을 생각한다면 그것은 Best practice이다. 여기서 더 나아가려면 한정된 상태에서의 추가적인 고려사항이 필요하고, 난 그것이 데드락일 것이라 생각하였다.

2. 데드락을 생각한 이유

현재 조건에서 데드락이 발생할 수 있는 지점은 채번 테이블이라 생각하였다. 사용자가 동시에 채번 테이블이라는 자원을 선점하고자 할텐데, 나는 여기서 동시성 제어만을 생각하였지만 그 전에 채번테이블이라는 자원에 접근하는 과정에서 데드락이 발생할 수 있을 것이다 라는 생각을 하게 되었다.

하지만 더 알아보면서 현재 조건이 데드락을 발생시키는 요인은 아니지만(순환대기에서 발생조건이 아님, 채번 테이블이라는 자원 하나), 그래도 향후 업무에서 충분히 고려할 수 있는 부분이라고 보았다. 유량제어의 한 부분이라고 생각하였던 것도 이를 기록한 이유 중 하나이다.

또한 대용량 데이터 산출 쿼리 튜닝을 진행하면서 간혹 메모리 과부하로 인한 무한 로딩 상태를 경험하기도 하였는데, 전산 처리 시 단순히 메모리 과부하로 인한 무한 로딩이 아니라 프로세스 동시 요청으로 인한 데드락 상태로 인한 무한 로딩 상태가 될 수 있다는 것을 생각할 수 있어야 한다는 것을 느꼈다.

3. 데드락(교착상태)

  • 프로세스 및 스레드가 자원을 선점하지 못하고, 다른 선점하고 있는 자원의 상태가 계속 유지됨으로 인해 프로세스 및 스레드들이 다른 자원을 선점하기 위한 대기 상태가 그대로 유지되는 것, 쉽게 말해 자원 선점을 위한 무한 대기 상태를 의미한다.

데드락의 발생 조건의 핵심은 여러 스레드, 프로세스가 하나의 자원을 점유하고자 경쟁하고 이러한 상태가 여러 자원에 대해 발생하는 것(순환대기)이다.

나의 상황처럼 점유하고자 하는 자원이 하나일 경우 데드락이 발생하지 않는다. 발생한다면 메모리 관련 오류이다.

4. 데드락 발생 조건

오른쪽에 기재한 내용은 해당 상황을 유발할 수 있을 것으로 생각한 요인이다.

  • 상호배제 : 자원은 한 프로세스만 사용 가능하다. -> 싱글톤 동시제어를 사용
  • 점유대기 : 현재 점유한 자원 이외 다른 프로세스에 할당된 자원까지 사용하고자 하는 프로세스가 있는 상태이다. -> 채번 테이블 (WAIT)
  • 비선점 : 다른 프로세스 사용이 끝날 때까지 자원 사용은 불가능하다. -> 싱글톤 동시제어
  • 순환대기 : 프로세스들이 서로가 서로의 자원을 점유하고자 대기하는 상황이 발생한다. -> 채번테이블을 두개 이상 사용해야 할 경우

지금 일단 이런 요인만 생각하였으나, 더 많은 상황을 경험하고 개념을 확장해야 한다.

5. 해결 방안

해결 방안은 의외로 간단하였는데,

  • 교착상태가 되면 시스템 에러를 나도록 하라
  • 교착상태 발생 조건 중 하나 이상을 부정하라

교착상태 회피는 조금 이상적인 상황이 아닌가라는 생각이 들어서, 나중에 다시 정리해보고자 한다.

1) 상호 배제(Mutual Exclusion) 부정

애초에 공유할 수 있는 자원을 만든다. Immutable의 개념을 사용해서, 공유할 수 있는 자원을 전역에서 사용할 수 있도록 만든다. 싱글톤과는 결이 다른 것 같다.

2) 점유 및 대기(Hold and Wait) 부정

프로세스 대기를 없애기 위해서 프로세스가 실행되기 전에 필요한 모든 자원을 할당합니다. (자원 낭비 발생)
자원을 점유하지 않고 있을 때에만 다른 자원을 요청할 수 있도록 합니다. (기아상태가 될 수 있음)

내가 일전에 생각한 삼항연산자/Null병합 연산자를 사용하면 좋을 방안이다. 최초 초기화되어있지 않은 상태에서 자원을 할당받을 수 있도록 하고, 작은 작업 단위에서는 좋은 방안이지만 큰 작업 단위에서 어떻게 사용해야 할 것인지..더 생각해봐야겠다.

3) 비선점(No Preemption) 부정

자원 선점을 허용한다.
프로세스가 할당받을 수 없는 자원을 요청하는 경우, 기존에 가지고 있던 자원을 모두 반납하고 새 자원과 이전 자원을 얻기 위해 대기하도록 합니다. (자원 낭비 발생 )

하지만 동시성제어에서 이 항목은 의미가 없지 않나 생각되는데, 이 부분을 해결하지 않으면 성능 테스트는 의미가 없었다. 더 생각해보도록 한다.

4) 순환 대기(Circular Wait) 부정

자원에 고유한 번호를 할당하고, 번호 순서대로 자원을 요구하도록 합니다. (자원 낭비 발생)

채번테이블 대신 DB Sequence를 사용하는 의미와 제대로 맞아 떨어지는 방안이다. 자원 낭비의 경우, Sequence를 사용하지 않을 경우 누락 항목이 발생한다는 점인데 이에 대한 관점이 자원 낭비라 생각하지 않는다면 사용가능한 방안이다.

6. 참고자료

교착상태 발생 조건 - https://velog.io/@dl_edge/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-%EA%B5%90%EC%B0%A9%EC%83%81%ED%83%9C-4%EA%B0%80%EC%A7%80-%EC%A1%B0%EA%B1%B4
교착상태 해결 방안 - https://yoongrammer.tistory.com/67

0개의 댓글