더 많은 도움을 드리기 위해

열심히 포스팅 중입니다!


지나가다 📢 광고 한 번 눌러주시면

더 좋은 글로 보답하겠습니다. 🥰

기술 면접 준비

동시성과 병렬성 - 기술 면접 준비

평비 - Giveloper 2025. 5. 23. 20:34

 

👋 

안녕하세요~ 평비입니다!

오늘은 많이 혼동하시는 동시성과 병렬성 개념에 대해서 나름(?) 자세하게 준비한 포스팅을 준비해봤습니다!

 

이 주제에 대해서, 설명을 하기 위해 지난 포스팅에 다뤘던 그림을 가져왔습니다.

 

백엔드 서버에 동시에 100개의 요청이 들어왔을 때, 이걸 어떻게 처리할까요?

이 시스템은 동시성이 보장된 시스템일까요?

또, 병렬성이 보장된 시스템일까요?

 

1. 개념

우선, 동시성과 병렬성의 개념부터 짚고 넘어가봅시다. 간단해요!

🟨 동시성 (Concurrency)

동시에 여러 작업을 “처리 중”인 상태 (꼭 동시에 “수행”되지 않아도 됨)

  • 시간 분할 (싱글코어에서도 가능)
  • 주로 I/O 바운드 문제에 대응

예시 : 하나의 CPU가 요청 A, B, C를 빠르게 번갈아가며 처리

 

🟦 병렬성 (Parallelism)

여러 작업을 실제로 동시에 수행하는 것

  • 멀티코어, 멀티스레드 필요
  • 주로 CPU 바운드 문제에 대응

예시: 4코어 CPU가 동시에 4개의 요청을 각각 다른 코어에서 처리

 

2. 비교

항목 동시성 병렬성
목적 응답성 향상 처리량 향상
필수 조건 단일/멀티코어 가능 멀티 코어/스레드 필요
주 대상 I/O 바운드 CPU 바운드
예시 async/await, coroutine 멀티 스레드, 분산 처리

 

3. 정리

그럼, 다시 아래 그림으로 돌아가봅시다.

이 그림은 동시에 요청 A, B, C, D, ...을 모두 처리하고 있으니 동시성이 있는 시스템이라고 할 수 있습니다.

다만, 단일 큐에 할 일을 쌓아놓고, 한 번에 하나의 일만 할 수 있기 때문에 병렬성이 없는 시스템이라고 할 수 있습니다.

 

4. 동시성 이슈 (Concurrency Issues)

공유 자원 접근 충돌이 대표적인 동시성 이슈입니다. 앞선 포스트에서 계속 다뤘던 갱신 손실도 동시성 이슈에 속합니다.

하나의 데이터에 여러 스레드나 요청이 동시에 접근할 때 발생하는 이슈이죠.

 

4-1. 동시성 이슈 사례

이슈 종류 설명
Lost Update (갱신 손실)   두 트랜잭션이 같은 데이터를 읽고, 서로 다른 값을 계산해 덮어씀.
→ 한쪽 변경 내용 소실
예약 충돌 락을 걸었는데, 같은 리소스를 여러 사용자가 동시에 예약해서 실패
Dirty Read   트랜잭션 A가 아직 커밋하지 않은 데이터를 B가 읽어버림
Non-repeatable Read   같은 트랜잭션 내에서 두 번 읽었는데 값이 달라짐
Phantom Read 조건에 맞는 row 개수가 두 번 읽었을 때 달라짐 (새로운 row 생김)
Write Skew 동시에 두 트랜잭션이 서로 독립적인 업데이트를 해서 전체 정합성이 깨짐
    - 송금 잔고 동시 차감   이체가 겹쳐서 잔고가 음수로 떨어지는 현상

갱신 손실, Dirty Read, Non-repeatable Read, 송금 잔고 동시 차감에 대해서는 앞선 포스트에서 참고 부탁드립니다!

 

4-1-1. 예약 충돌

동시성 이슈 사례 중, 송금과 자동이체가 동시에 일어나는 경우는 Repeatable read + Optimistic Lock으로 막을 수 있었습니다. 실패가 나더라도, 재처리 시도를 하면 어느 정도 보완이 됩니다.

그렇다면, 한 자리에 대해서 대규모 트래픽이 몰리는 SKT T1 롤드컵 티켓 예약을 예로 들면 어떨까요?

맨 처음 트래픽에 대해서는 성공했는데, 다른 모든 사람에 대해서 예약이 정상적으로 진행되다가 제일 마지막에 예약 버튼을 딱! 누르는 순간 아래와 같은 서버 에러가 발생한다면??? 그 날 콜센터는 또 난리가 날 겁니다...

모든 동시성 이슈에 대해서 Repeatable read + Optimistic Lock가 정답이라고 할 수 없는 것 같습니다!

이 경우는 낙관적 락이 사용자 경험에 직접 영향을 주는 케이스인데요. 이 경우는, 성능이 떨어지더라도 공정성과 UX가 중시되는 상황이라서 비관적 락이 더 적합하다고 할 수 있습니다.

 

하지만, 한 번 락을 잡았다고 무한정 점유하고 있게 하는 것은 아니고 보통의 경우 SOFT HOLD 상태로 만들게 됩니다.

SOFT HOLD 상태는 임시 점유 상태입니다. [최종 예약] 버튼을 누르기 전까지 3분, 5분, 20분 이런 식으로 임시 점유 상태로 만드는 거죠.

 

이와 같이, 락은 상황에 따라 적합하게 사용해야 합니다.

 

4-1-2. Phantom Read 문제

조건에 맞는 row 개수가 두 번 읽었을 때 달라짐 (새로운 row 생김)

이 문제는 Serializable이 아닌 모든 격리 수준, Repeatable read 격리 수준도 발생할 수 있는 문제인데요.

Repeatable read는 하나의 트랜잭션에서 조회를 여러번 해도 그 결과가 동일하다는 격리수준인데, 아쉽게도 다른 트랜잭션의 update는 반영이 되지 않아도 insert는 반영이 됩니다!

트랜잭션 2 입장에서, 어떠한 insert 연산도 하지 않았는데 다시 조회했더니 건수가 늘어있는 경우입니다. 유령이 와서 집어넣은 걸까요? 트랜잭션 2 입장에서는 충분히 놀랄만한 상황입니다! 그래서 이름도 Phantom Read인 모양입니다.

 

 

4-2. 병렬성 이슈 사례

이슈 종류 설명
락 경합 (갱신 손실) (동시성 이슈와 유사) 여러 스레드가 동시에 같은 자원 접근 → 순서에 따라 결과 달라짐
데드락 (Deadlock) 병렬 처리 중인 두 스레드가 서로의 락에 걸려 서로의 자원을 기다리며 멈추거나 계속 돌기만 함
우선순위 역전 (Priority Inversion) 낮은 우선순위 스레드가 자원을 점유 중 → 높은 우선순위 대기
Work Stealing 불균형 병렬 태스크 분배 시, 특정 노드만 작업이 몰려 과부하
캐시 불일치 멀티코어 CPU에서 각 코어의 캐시 불일치
False Sharing 서로 다른 스레드가 같은 캐시라인에 있는 변수 접근 시 성능 저하 (CPU 캐시 간 경합 현상)
ex) 두 스레드가 인접한 배열 원소를 동시에 수정
Memory Barrier 누락 CPU가 명령을 재배열하는데, 동기화 없이 접근 → 예측 불가 결과
Atomicity Violation 여러 연산이 원자적이지 않게 병렬로 수행되어 문제 발생

 

결국, 동시성 이슈와 병렬성 이슈 모두 자원 공유 간 동시에 접근했을 때 이슈가 발생하는 것이라서 비슷합니다. 다만, 병렬성 이슈는 좀 더 큰 맥락입니다. 동시성 이슈는 트랜잭션 단위였던 반면, 병렬성 이슈스레드나 프로세스를 사용할 때 리소스 관리/조율 시 이슈에 해당합니다.

  • ✅ 스레드 간 캐시 일관성 문제
  • ✅ 병렬 처리 간 로드 밸런싱 실패
  • 락 경합(lock contention) 과다로 오히려 성능 저하
  • ✅ False Sharing (CPU cache 간 경합 현상)
  • ✅ 병렬 작업 간 결합도 높아 성능 비효율

 

 

 

👏

 

자, 이렇게 기술 면접에서도 자주 언급되는, 동시성과 병렬성에 대해서 다뤄봤습니다!
저도 이 포스팅을 작성하면서, 두 개념의 차이에 대해서 좀 공부를 하게 된 것 같은데요...!

평비의 이 평범한 글이 여러분에게 비범한 도움이 되었으면 좋겠습니다 👍