본문 바로가기

Go

고루틴을 사용해서 검색 API의 성능을 끌어올리기

고루틴, 채널 사용 전

 

고루틴, 채널 사용 후 응답속도

 

 

기존 로직

 
func SearchByKeyword[T model.Response](searchKeyword string, resp *[]T) {
    suggestKeyword := BuildSuggestQuery(searchKeyword)
 
    q := util.Queue{}
 
    _, s := util.InspectSpell(searchKeyword)
 
    q.Enqueue(elastic.NewMatchQuery(movieNmText, s))
    q.Enqueue(elastic.NewMatchQuery(movieNmEngToKor, s))
    q.Enqueue(elastic.NewMatchQuery(movieNmKorToEng, s))
    q.Enqueue(elastic.NewMatchQuery(movieNmText, suggestKeyword))
 
    sendRequestToElastic(q, resp)
}

 

큐에 통합검색에 사용되는 모든 쿼리를 enqueue 한 뒤에 es에 요청을 보냄.

 

순차적으로 큐에 데이터를 쌓은 후 처리해주기 때문에, BuildSuggestQuery 메서드를 실행하는 동안에 es 쪽으로 보내는 요청이 늦어짐.

 

 

변경 후 로직

 

func SearchByKeyword[T model.Response](searchKeyword string, resp *[]T) {
    suggestKeyword := searchKeyword
 
    ch := make(chan bool)
    go BuildSuggestQuery(&suggestKeyword, ch)
 
    q := util.Queue{}
 
    _, s := util.InspectSpell(searchKeyword)
 
    q.Enqueue(elastic.NewMatchQuery(movieNmText, s))
    q.Enqueue(elastic.NewMatchQuery(movieNmEngToKor, s))
    q.Enqueue(elastic.NewMatchQuery(movieNmKorToEng, s))
 
    sendRequestToElastic(q, resp)
 
    if len(*resp) != 0 {
        return
    }
 
    select {
    case <-ch:
        q := util.Queue{}
        q.Enqueue(elastic.NewMatchQuery(movieNmText, suggestKeyword))
        sendRequestToElastic(q, resp)
        close(ch)
    }
}
 

실행시간이 오래걸리는 BuildSuggestQuery를 고루틴을 사용해서 멀티 쓰레드 환경에서 병렬로 실행 함.

 

통합검색 요청과 대체 키워드를 구하는 메서드를 동시에 실행하기 때문에, 추후에 있을 대안검색 쿼리를 요청하는 데 시간 효율이 좋아질 뿐만 아니라,

 

대안검색을 할 필요가 없는 경우에는 큐에 추가적인 쿼리를 추가하지 않고도 바로 응답을 반환할 수 있기 때문에 효율이 높아짐.

 

select를 사용해 채널이 true일때만 추가적인 쿼리를 요청하기 때문에 동시성 문제를 방지할 수 있음.

 

 

Jmeter 성능 테스트 ( es서버가 싱글 노드라서 부하 때문에 짧게 끊어서 테스트 )

변경 전

 

변경 후

 

약 68%의 성능 개선

 

'Go' 카테고리의 다른 글

Go에서 의존성 주입을 받는 방법  (0) 2023.09.19