고루틴, 채널 사용 전
고루틴, 채널 사용 후 응답속도
기존 로직
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 |
---|