Uber 가 Push Platform 에서 gRPC 를 적용한 이유

이 글은 Uber 의 Real-Time Push Platform 에서 gRPC 로 정착하게 된 이유에 대해서 소개하는 글입니다. 


Push Platform 을 구성하는 요소들은 많은데 여기서는 그런 부분을 다 제외시키고, 간단하게 메시지 전달 프로토콜에만 집중해서 보겠습니다. 


정말 간단하게 쓰고자 생략한 내용이 많은데요.


좀 더 자세하게 보고 싶다면 원문을 참조하길 바랍니다. 링크는 글의 맨 아래에 첨부해둘게요.  


Uber 의 메시지 전달 프로토콜은 Polling -> SSE (Server Sent Event) -> gRPC 순으로 변경되었습니다. 하나씩 살펴볼게요.


<1. Polling 방식의 문제점> 


Uber App 초기에 실시간 메시지 전달을 위한 별도의 플랫폼이 없었기 때문에 메시지를 가져오기 위해서 Polling 방식이 사용되었습니다.  


일반적으로, 메시지를 Pull 하는 Polling 방식은 연결을 유지하며 메시지를 Push 하는 방식(e.g WebSocket, SSE)보다 처리할 수 있는 양이 적습니다. 


예시로, 러시아의 Mail Ru 는 Polling 방식을 사용할 당시에는 초당 최대 50,000개의 요청을 처리할 수 있었으나, WebSocket으로 전환 후에는 3,000,000개의 커넥션을 관리하며 효율적으로 메시지를 전달할 수 있었다고 합니다.


또한, Polling 방식은 네이티브 앱에서도 부정적인 영향을 미칩니다. 앱의 배터리 소모 증가, 응답 지연, 다양한 API 조회로 인한 앱 시작 속도 저하 등의 문제가 발생할 수 있습니다.



<2. Polling 에서의 SSE 로의 전환 > 


Uber 에서는 SSE 를 도입한 주요 이유로 보안, 모바일 SDK 지원, HTTP 사용의 용이성 등을 꼽았습니다. 


SSE 를 사용하면서, Uber 에서는 메시지 전달의 신뢰성을 ‘적어도 한번 (at-least once)’ 을 보장하고자 했습니다. 


불확실한 네트워크 환경에서 메시지 전달을 보장하기 위해서는 메시지 수신에 대한 응답을 받아야만 합니다. 


이를 Uber 에서는 acknowledgment mechanism 이라는 표현을 사용했는데 다음과 같은 정책으로 구현했습니다. 

  • 메시지를 전달할 때 Sequence Number 를 부여해서 전달합니다.

  • 서버와의 연결이 끊겼다가 다시 연결될 때 마지막으로 받은 Sequence Number 를 서버에 전달하여, 그 이후의 메시지를 다시 받습니다.

  • 30초마다 서버에 받은 메시지에 대한 확인 응답(Ack)을 전송하여 수신한 메시지들을 알려줍니다. 이 응답으로 인해서 이제 불필요한 메시지는 수신되지 않습니다. 


또한, Uber 에서는 실시간 메시지 전달을 위해 연결 상태를 지속적으로 확인합니다:

  • 서버는 4초마다 상태 확인 메시지를 전송하고, 클라이언트는 7초마다 이 메시지를 받았는지 확인합니다. 만약 메시지를 받지 못했다면 재연결을 시도합니다.



<3. SSE의 한계와 gRPC 의 필요성> 


Uber 는 SSE 를 이렇게 잘 쓰고 있다가도 다음의 이유로 gRPC 를 적극적으로 검토했습니다: 

  • 양방향 연결의 필요성:

    • SSE는 단방향 연결이기 때문에, 30초마다 보내는 확인 응답(Acknowledgment) 메시지가 유실될 경우, 이미 전송된 메시지를 다시 보내야 하는 문제가 발생했습니다.

    • Uber는 메시지의 우선순위에 따라 분류하고, 중요한 메시지의 즉각적인 전달 여부를 확인하는 필요성이 있었습니다. 이를 위해 양방향 연결이 필수적이라고 판단했습니다.


  • Binary Encoding 방식의 필요성: 

    • 전 세계적으로 서비스를 제공하는 Uber는 3G와 같은 네트워크 환경에서도 효율적으로 서비스를 제공해야 합니다. 이를 위해 데이터 전송을 최대한 Compact하게 유지할 필요가 있습니다.

    • SSE는 Text based Encoding 방식을 사용하는 반면, Binary Encoding 은 데이터 크기를 크게 줄일 수 있습니다. 예를 들어, 일반적으로 간단한 JSON 데이터를 Protocol Buffer 와 같은 Binary Encoding 을 사용하면 데이터 크기를 절반 이상 줄일 수 있습니다.


  • Stream 전송의 필요성: 

    • SSE 에서는 큰 메시지 전송 후에 Health Check 메시지를 보내는 경우, head-of-line blocking 문제로 인해 Health Check 메시지가 지연되어 연결이 끊길 수 있습니다.

    • HTTP/2 와 같은 스트림 형식으로 메시지를 전달할 경우, Health Check 메시지와 같은 작은 데이터는 더 빠르게 수신할 수 있습니다.


  • QUIC/HTTP 3와 같은 고급 기능의 필요성:

    • Uber 는 QUIC/HTTP3 의 streams, multiplexing, flow control 같은 고급 기능들이 필요하다고 판단했습니다



<4. Uber의 gRPC 적용 과정: 고려 사항 및 구현 전략> 


Payload Compression:

  • 3G 환경에서 데이터 전송 시간을 최소화하기 위해 gzip을 사용하여 메시지 압축을 적용했습니다. 실제로 적용 결과 1MB 데이터의 다운로드 시간이 20-50초에서 gzip 적용 후 5초로 단축되었습니다.

  • (사실 gzip 을 왜 고려했는지는 저는 잘 모르겠긴 합니다. 압축 알고리즘의 선택은 압축률, 압축 속도, 압축 해제 속도, 사용하는 CPU 리소스를 고려해야 하는데 gzip 은 zstandard 의 완전 하위호환이라서...) 


Fallback Mechanism: 

  • gRPC 기반 메시지 전송에 문제가 발생할 경우를 대비해 기존 SSE 기반 메시지 전송을 대체 방법으로 사용했습니다.


Handling Missing Callbacks:

  • 클라이언트가 연결을 종료할 때, 적절한 종료 콜백이 수신되지 않아 Health Check 메시지를 불필요하게 전송 시도하려는 문제가 발생했습니다. 이를 해결하기 위해 메시지 전송 전 커넥션 검증 로직을 추가했습니다.


Message Flow Control:

  • streamObserver 대신 ServerCallStreamObserver 를 사용하여, 클라이언트와 서버 간의 연결이 성공적으로 이루어진 후에만 메시지를 수신하도록 설정했습니다. 이 방법은 서버가 준비되지 않은 상태에서 메시지를 받아 처리하지 못하는 문제를 방지했습니다.


Graceful Shutdown Handling: 

  • 종료되어야 할 streamObservers 를 쉽게 추적할 수 있도록 ShutdownHandler 의 Wrapper 를 별도로 개발했다고 합니다. 



References: 

  • https://www.uber.com/en-KR/blog/real-time-push-platform/?uclick_id=c4eaf0d6-60d5-46a3-aecc-db943c555963

  • https://www.uber.com/en-KR/blog/ubers-next-gen-push-platform-on-grpc/?uclick_id=c4eaf0d6-60d5-46a3-aecc-db943c555963

Uber's Real-Time Push Platform

Uber Blog

Uber's Real-Time Push Platform

다음 내용이 궁금하다면?

또는

이미 회원이신가요?

2023년 11월 18일 오후 12:38

 • 

저장 30조회 3,576

댓글 2

함께 읽은 게시물

🎯 유튜브에 100번째 코딩 테스트 문제 풀이 영상을 올렸습니다!

... 더 보기

달레의 코딩 테스트

www.youtube.com

달레의 코딩 테스트

 • 

댓글 1 • 저장 27 • 조회 3,936



리트코드 102. Binary Tree Level Order Traver

... 더 보기

Binary Tree Level Order Traversal | 알고달레

알고달레

Binary Tree Level Order Traversal | 알고달레

여기는 나름 구력이 있던 곳인디 기존 경영진이 일감빼돌리고 사업 보다는 잿밥에 관심이 많아보이더니 이제는 적자로 전환된지는 수년째. 최대주주 계속 바뀌고 CB에 유증에 2차전지 사업했다 이번에 또 이종산업 진출. 엉망이 되어버린 회사.

... 더 보기

손오공, 최대주주 변경 주식양수도 계약...클라쎄오토 인수 완료

파이낸셜뉴스

손오공, 최대주주 변경 주식양수도 계약...클라쎄오토 인수 완료

조회 314


욕심많은 주니어는 이 두가지를 꼭 경계하세요!

오늘은 욕심이 많은 사람이 빠지기 쉬운 함정을 정확하게 꼬집는 글이 있어 소개 드리려고 합니다. 글에서는 '주니어'를 타겟으로 잡고 있지만, 주니어가 아니더라고 욕심이 많은 사람이면 (저를 포함해서😅) 뼈를 때리는 글 같아요. 개인적으로는 두번째인 '산만함'의 문제가 더 와닿았는데요. 항상 머릿속에 이것도 하고싶고, 저것도 하고싶고 조급한 마음이 많다보니 오히려 뭔가를 시작해서 팍 밀고 나가는 에너지가 부족하단 생각이 제 스스로 든 적이 있거든요. 비슷한 상황이 본인에게도 해당된다는 생각이 든다면 한번쯤... 더 보기

Jaehyun Lee on LinkedIn: 욕심많은 주니어는 이 두가지를 꼭 경계하세요! 제가 접해본 주니어 분들 중에서 흥미로운 유형이 하나 있습니다. 성장 욕구도 있고... | 16 comments

www.linkedin.com

Jaehyun Lee on LinkedIn: 욕심많은 주니어는 이 두가지를 꼭 경계하세요! 제가 접해본 주니어 분들 중에서 흥미로운 유형이 하나 있습니다. 성장 욕구도 있고... | 16 comments

 • 

댓글 5 • 저장 93 • 조회 4,167


🙉 달레의 찐팬이 되어주실래요? 💕

... 더 보기