gRPC의 장단점에 대해

Seungwoo Kim·2022년 9월 9일
0

grpc

목록 보기
1/1

JSON 기반 HTTP API를 사용하여 서버 간 통신을 하는 것과 비교했을 때 어떠한 이점이 있을까?

이 포스트는 이러한 궁금증에서 출발한다.

직렬화 방식
gRPC 메시지는 protobuf를 사용하여 직렬화된다.

여기서 직렬화란, 메모리에 상주하는 객체, 구조체, 리스트, 해시 테이블, 트리 등의 구조화된 데이터를 파일 시스템에 쓰거나, 네트워크를 통해 전송하기 위해 일련의 바이트열 형태로 변환하는 것이다.

Q. 메모리에 상주할 때부터 바이트열이라면 이런 직렬화가 필요없지 않나?
A. 메모리에 상주할 때는 CPU에서 효율적으로 접근하고 조작할 수 있도록 포인터를 활용해 최적화되어 있다. 그러니 직렬화 과정은 불가피하다.

그래서 많은 프로그래밍 언어는 인메모리 객체를 바이트열로 직렬화하는 기능을 내장한다. 대표적으로 Java.io.Serializable이 있다. 그러나 프로그래밍 언어에 내장된 직렬화 라이브러리는 해당 언어에 종속되어 있어 다른 언어에서 데이터를 읽기 어렵다는 단점이 있다.

그래서 JSON, XML, CSV, 이진 변형과 같은 다양한 프로그래밍 언어에서 읽고 쓸 수 있는 표준화된 형식이 존재한다.

HTTP API에서 주로 사용하는 JSON과 gRPC에서 사용하는 protobuf를 비교해보자.

JSON은 텍스트 형식이다. protobuf는 이진 형식이다.

특히 protobuf는 객체의 속성값을 숫자(1, 2, 3..) 값으로 대체해버린다.(자세히 알고 싶으면 protobuf 문법과 직렬화 방식에 대해 참고하자.) 그렇기에 JSON보다 더 적은 데이터 공간을 차지한다.

그리고 protobuf는 .proto 파일에 별도의 스키마를 정의해야 한다. 스키마를 정의한 후 선택한 프로그래밍 언어로 스키마를 구현한 코드를 생성해서 사용한다. 또한 서버와 클라이언트 각각에서 모두 .proto 파일이 공유되고 코드가 생성되어야 한다. 버전 관리도 필요하다.

장점
데이터의 크기가 작으니 통신이 빠르다.
별도의 파싱이 필요 없다. .proto에서 정의된 스키마대로 코드 생성된 객체가 이미 존재하기 때문에 바이트열 그대로 메모리에 쓰고, 객체의 레퍼런스에서 읽으면 된다.
단점
이진 형식이니 텍스트 형식인 JSON에 비해 읽기가 불편하다. .proto 파일이 없으면 무슨 의미인지 알 수가 없다.
.proto 문법을 배워야하니 러닝커브가 생긴다.
스키마 변경시 종단(서버와 클라이언트)간의 .proto 파일 공유를 통해 함께 반영되어야하는 단점이 있다.
통신 프로토콜
gRPC는 HTTP/2용으로 설계되었다. (HTTP API는 정해진 HTTP 버전이 없다.)

HTTP/2에서는 HTTP 1.1에서 해결되지 못했던 Head Of Line Blocking 문제가 해결되고 멀티플렉싱을 지원한다.

자세히 알아보면, HTTP 1.1은 Persistent Connection + Pipelining이라는 특성을 갖는다. 그래서 한번의 TCP 연결로 여러 개의 컨텐츠 요청 및 응답이 가능해졌다. 그러나 연결당 하나의 요청과 하나의 응답만 처리할 수 있다.
파이프라이닝을 적용하면 요청을 줄줄이 보내고 줄줄이 받을 수 있다. 앞선 요청의 응답을 기다리지 않고 다음 요청을 보내기 때문에 처리량을 높일 수 있다. 물론 응답의 순서는 보장되어야 한다.

HTTP 1.1은 여전히 개선의 여지가 있다. 요청의 응답 순서가 보장되어야 하기 때문에 Response #1에서 발생한 딜레이만큼 Response #2와 Response #3의 latency가 증가한다. 이게 HOL Blocking 문제다.

HTTP 2에서는 하나의 커넥션에서 여러 메시지를 동시에 주고 받을 수 있는 멀티플렉싱(Multiplexing)을 제공한다. 멀티플렉싱은 반송파 상에 다중 신호나 정보 스트림을 단일 복합신호의 형태로 동시에 보내고, 수신측에서 별개의 신호들로 복원하는 것이다.

그래서 결론적으로 gRPC는
데이터 페이로드가 가볍다. 이진 부호화를 채택하고 직렬화 과정에서 용량 최적화를 이루어냈기 때문에. 그러니 통신속도가 빠르다. 특히 데이터셋의 크기가 커질 수록 일반 HTTP API와 통신 속도의 차이는 더 벌어진다.

사양이 엄격하다. 그래서 gRPC를 적용한다면 개발자 간의 논쟁이 불필요하다.

.proto파일이 데이터 객체 코드를 클라이언트와 서버 측에 자동으로 생성해주기 때문에 코드의 중복을 줄일 수 있다.

HTTP/2를 사용하니 양방향 실시간 통신 스트리밍이 가능하다.

profile
一筆揮之

0개의 댓글