⚡ 개요
내부적으로 GraphQL을 사용해서 필요한 데이터를 호출해서 사용하고 있다. 그런데 데이터가 많아지면 많아질수록 rest API를 통해서 호출하는 방식보다 속도가 느려지는 경험을 하게 되었고 왜 이런 문제가 발생하는지 궁금해져서 찾아본 내용에 대해서 공유를 하려고 한다.
기본적으로 rest API VS GraphQL에 대해서 장단점이 명확하고 이에 대한 설명들을 많이 찾아볼 수 있으니 숙지하고 상황에 맞게 사용을 하는 게 좋을 거 같다.
혹시라도 버전이 업데이트 되면서 해당 이슈가 해결이 되었을 수도 있기 때문에 내가 테스트한 버전에 대해서 적어놓도록 하겠다.
- Spring boot 2.6.6
- graphql-java 20.0
- raphql-java-extended-scalars 19.1
- graphql:spqr 0.12.1
- 위의 두개의 graphql에 대해서 exclude를 해줘야 한다.
📒 리스트 검증이 느린 이유는??
우리는 조직도를 GraphQL을 통해서 조회를 하고 있다. 내부적으로 테스트를 하기 위해서 여러 조직들을 붙여서 테스트를 하고 있는 과정에서 속도가 너무 느리다고 판단을 했고 느린 이유가 GraphQL에서 객체 즉 DTO에 대한 검증을 하는 과정에서 속도 저하가 발생을 한다고 판단을 했다.
디버그 과정에서 조직도 데이터를 조회 하고 GraphQL에 데이터를 넘기는 과정은 바로 진행이 됐지만 Graphql에서 다시 넘어오는 과정에서 시간 소요가 상당했기 때문에 내부적으로 문제가 있다고 판단을 했었다.
추가적으로 테스트 및 검증을 하는 과정에서 restAPI로 호출을 하게 되는 경우 속도가 훨씬 빠르다는 결론도 얻게 되었다.
왜 위와 같은 현상이 발생하는지 자료를 찾아봤지만 무슨 이유 때문인지 정확히 알수가 없지만 GraphQL에서 데이터를 호출할 때 객체의 내용을 검증하는 과정이 존재하고 이 부분에서 속도가 저하가 될 가능성이 존재한다고 판단을 했다.
※ 추가적으로 다른 이유가 존재하거나 해당 내용이 틀렸다면 누군가 알려줬으면 좋겠다 :)
GraphQL을 사용 할때 전체 조회가 아닌 부분 부분의 구역을 나눠서 조회하고 그래프처럼 하나로 묶어서 사용을 하려고 한다고 한다. 그렇다면 우리가 내부적으로 사용을 잘못하고 있는 건 아닐까 생각을 했지만 위에서 디버그 해본 결과처럼 데이터를 조회하고 넘기는 과정에서는 속도 저하가 발생하지 않았다.
내부적으로 검증해본 결과는 위와 같고 GraphQL을 호출하면서 내부 클래스를 디버그 해본 결과 속도 저하가 발생하는 부분에 대해서 정리하도록 하겠다.
디버그를 했을때 내부적으로 타고 있는 클래스에 대한 내용이다. 쉽게 설명하자면 기본적으로 query 및 mutation으로 보낸 내용을 분리하고, 체크하고, 실행한다.
이 과정에서 대해서 디버그를 하는 과정에서 excute를 할 때, 객체 내부에 객체가 존재하는지 존재한다면 내부에 또 객체가 존재하는지를 검증하는 과정이 존재했다. 그래프 형태로 조회를 하다 보니 객체 내부에 객체가 존재할 수 도 있고 충분히 필요한 로직이라고 생각을 했다.
그런데... :(
데이터가 10만건이라고 가정을 했을 때, 데이터 건별로 객체 내부에 객체가 존재하는지 전부 검사를 하고 있었다.
물론 데이터가 많으면 느릴수도 있지만 뎁스가 깊다면 더 느려지는 현상이 나오게 된 것이다.
내부적으로 해결을 하기 위해서 여러 가지 시도를 했다.
위의 이미지처럼 내부 뎁스가 깊은 곳의 부분을 Fragments로 바꿔서 다른 if문을 탈 수 있도록 해봤지만 쿼리를 어떻게 보내느냐에 따라서 내부 클래스를 보면 결국을 특정 조건에 따라서 다시 collectFields로 보낸다.
결국 속도에 영향도는 있지만 정답은 아니라고 생각을 했다.
두 번째 방법으로는 쿼리의 내용을 전부 String으로 보내는 방법을 사용해 봤다.
필드에 대해서 검증하는 과정을 타지 않게 되면서 확실히 어떻게 쿼리를 작성해서 날려도 속도가 일정하게 빠르게 도착을 했다.
하지만 화면단에서 데이터를 가져와서 사용할 때는 특정 Field 값으로 사용하지 못하고 map을 사용해야 하는 아주 큰 단점이 발생했다. 내부적으로도 해당 방법의 경우는 graphQL을 사용하는 이점이 없다고도 판단을 했기 때문에 필드를 검증하는 과정에서 속도가 저하된 게 맞다는 결론만 얻게 되었다.
⚡ 참조
⚡ 생각
graphQL은 뎁스가 깊은 대용량 데이터를 사용할 때는 적합하지 않다고 생각을 했고, 사용 방법에 대해서 고민 해볼 필요성이 있다고 생각을 한다. graphQL이 나온 이유에는 펼쳐 있는 여러 데이터를 그래프 형태로 호출을 해서 표현을 하려고 했다고 한다.
이번 기회에 다른 방법에 대해서도 고민을 하고 최적화된 작업을 찾아서 적용 해봐야겠다.
💢 일단 내부적으로는 속도 이슈로 인해서 graphQL이 아닌 REST API 통신을 통해서 데이터를 가져오도록 변경을 했다.
'GraphQL' 카테고리의 다른 글
[GraphQL] GraphQL 개념 정리 (0) | 2022.07.06 |
---|