soosue
끄적끄적
soosue
전체 방문자
오늘
어제
  • 분류 전체보기 (31)
    • TIL (6)
    • 살짝 정리 (10)
    • note (1)
    • 내가필요해서만든 (1)
    • 막쓰기 (3)
    • spring (4)
    • java (2)
    • git (2)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • git config alias
  • .gitconfig 파일
  • logger template
  • git
  • 로거 템플릿
  • git config파일
  • Logger만들기
  • git alias 설정
  • branch
  • live templates
  • remote
  • Logger 구현체
  • git alias 하는법
  • intellij logger template
  • Logger 구현체 선택
  • Rebase
  • git 명령어 alias
  • slf4j Logger
  • 로거 작성
  • switch -t

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
soosue

끄적끄적

살짝 정리

producer-consumer 패턴

2021. 6. 16. 23:32

producer - consumer패턴은 멀티스레드 디자인 패턴에서 많이 사용되는 패턴 중 하나이다.

 

한쪽은 producer의 역할. 즉, 어떤 작업을 생성해주는 역할을 하고

나머지 한 쪽은 consumer역할. 생성된 작업을 수행해주는 일을 한다.

 

그 중간 연결 매개체 역할을 queue가 수행한다.

 

producer    --->    queue    --->    consumer

            작업생성           작업수행

 

다시 말해 producer는 작업 생성 후 queue에 해당 작업을 넣어주는 일만 하고,

consumer는 queue에 들어있는 작업을 꺼내서 작업을 수행하는 일만 한다.

 

 

여기서 멀티스레드가 사용되는 부분은 어디일까.

producer와 consumer를 각각 멀티스레드로 돌릴 수 있다.

 

producer                                   consumer

producer    --->    queue    --->    consumer

producer                                   consumer

 

 

다음 예로 멀티스레드 적용시 장점을 살펴보자.

 

producer가 한 작업 생성에 평균 10초가 걸리고,

consumer가 한 작업 수행에 평균 30초가 걸린다고 하자.

생성해야 하는 작업은 총 4개가 있다고 한다면,

(queue에 넣거나 가져오는데 걸리는 시간은 0초라고 가정하자.)

 

단일 producer, 단일 consumer일 경우엔

producer는 계속 작업생성만 하므로 0~30초가 걸릴 것이고,

consumer는 0~10초는 기다리다가 10초 이후 queue에 작업이 들어오므로 10~100초까지 작업수행을 할 것이다.

즉, 총 소요시간은 100초이다.

 

다중 producer, 다중 consumer일 경우엔 (각각 3개씩이라고 가정하자)

producer 3개가 각각 작업을 생성하므로 0~10초가 걸릴 것이고,

consumer 3개 또한 0~10초는 기다리다가 10초 이후 queue에 들어온 작업을 수행하므로 10~40초까지 작업을 수행할 것이다.

즉, 총 소요시간은 40초이다.

 

여담으로 producer-consumer가 아닌 동기방식의 작업이었다면,

작업 생성 10초 - 작업 수행 30초, 작업 생성 10초 - 작업 수행 30초, 작업 생성 10초 - 작업 수행 30초

이렇게 반복이 되므로

총 120초가 걸렸을 것이다.

 

즉 장점은 멀티스레드를 활용하여, 작업시간을 효율적으로 줄일 수 있다.

역할의 분리라는 장점 또한 가져올 수 있을 것이다.

 

하지만 단점 또한 존재한다.

1. 멀티스레드 환경이기 때문에, 동기화 문제가 발생할 수 있다.

2. consumer가 작업을 수행하다 실패할 경우, 해당 작업을 어떻게 처리할지 결정해주어야 한다.(이건 단일 스레드나 동기방식의 작업도 하긴 해야한다.)

3. 동기방식의 구현보다 복잡해질 수 있다.

 

동기화 문제를 해결하기 위해서 Java에선 synchronized나 BlockingQueue등을 사용할 수 있다. (비관적 동시성 제어)

하지만 너무 방어적으로 코딩을 할 경우, 멀티스레드를 쓰는 의미(성능 향상)가 줄어들 수 있어서 낙관적 동시성 제어(Atomic)를 할 수 있다.

 

 

결론은 producer-consumer패턴을 이용하여 멀티스레드 환경을 구성할 수 있으며,

작업 효율성 증가라는 장점이 있지만, 동기화 문제, 구현의 복잡성이라는 단점이 있을 수 있다.

 

아 Apache Kafka를 주로 사용한다고 한다.

'살짝 정리' 카테고리의 다른 글

AWS Cloud Practitioner Essentials 모듈1  (0) 2021.06.29
컴포넌트의 내부 구현을 숨기자  (0) 2021.06.26
이진탐색  (0) 2021.06.24
대칭키, 비대칭키  (0) 2021.06.10
JPA 관계 생각해보기  (0) 2021.06.08
    '살짝 정리' 카테고리의 다른 글
    • 컴포넌트의 내부 구현을 숨기자
    • 이진탐색
    • 대칭키, 비대칭키
    • JPA 관계 생각해보기
    soosue
    soosue

    티스토리툴바