KubeCon 2019 - The story of Why we migrate to gRPC and How we go about it (Spoti
The story of Why we migrate to gRPC and How we go about it
Matthias Grüter. Engineering Manager in the infrastructure group.
- gRPC based infrastructure로 전환한 이유
- gRPC based infrastructure로 전환한 방법
- 2500여 개의 내부 service
- ingress로 들어오는 request 가 초당 8백만 (Query for Second
- 서비스 간 통신에는 자체 개발한 protocol을 사용하고 있었음. (이름은 Hermes)
- RPC 프레임워크가 아니라 통신 프로토콜이었음. gRPC보다는 http와 비교대상.
- 동작에는 문제 없음
그런데 왜 바꾸어야 했나?
- 자체 개발한 거라서..
- 신규인력에게 학습시켜야 할 요소.
- 스포티파이는 RPC 전문 기업도 아님. 데이터센터도 직접 관리하기 싫어서 클라우드로 전환하는 마당에..
- Ecosystem 자체가 없음. 필요로 하는 기능은 전부 개발해야 함. 디버깅 / 로드밸런싱 등 여러 기능을 직접 구현하는 건 리소스 낭비.
왜 gRPC인가?
- 오픈소스, 퍼포먼스 좋음, HTTP/2 based. Standard 존재. CNCF 산하 프로젝트, Strong-typed... 여러 가지가 있지만
- 우리가 중요하게 생각했던 세 가지 features.
Proto
proto. 정확히는 protobuf definition file.
- proto 파일로 how to call your service / what to expect back 을 알 수 있음.
- Code Generation
- proto definition file을 중요시하기. first-class citizen으로 간주하고, 모든 작업의 시작이 되도록
- proto 파일을 관리하는 shared Repository 운영
- versioning -> 여러 proto file에서 이름만 바꾸는 식으로 versioning하는 건 비추. just rely on protobuf, being backward compatible.
- 새로운 작업을 해야 하면, 패키지를 새로 만드는 것을 추천함.
Resiliency
현재 interceptor에서 retry 로직 적용 가능.
gRPC Core에서 proposal로 올라온 retry hedging은 아래와 같다.
- Fanning out the request to all the backends, until you get some response.
- 응답을 받는 순간, 다른 모든 request는 canceled.
단, 이렇게 될 경우 Cascading Failure (Thundering Herd) 발생 가능.
- retry Throttling: 클라이언트에서 retry 시도할 수 있는 최대치를 지정. 최대 retry 수를 넘어가면 더 이상 요청을 보내지 않음.
- pushback: 서버 쪽에서 클라이언트에게 '일정 시간 뒤 request를 다시 보내도록' 요청하는 것.
- 요청마다 timeout을 설정하는 대신 Deadline을 설정하는 것. deadline을 초과하면 요청은 자동으로 cancel된다.
- GCP 클라우드와 호환되는 통신 프로토콜, Edge(mobile client)에도 적용 가능.
Load Balancing / Routing
- Server Side : 클라이언트가 요청 보내면, 서버 앞단의 프록시가 알아서 백엔드로 load balancing
- 장점: Simple. 클라이언트 코드가 간단해짐.
- 단점: extra hop에서 생기는 latency
- Client Side : 클라이언트에서 Load balancing 로직 실행
- 장점: no extra hop
- 단점: 클라이언트 코드가 복잡해짐
Hermes를 사용하던 시절 -> 프로토콜에서 제공하는 로드밸런싱이 없으므로 client-side Load balancing 사용중이었음
gRPC에서는 Lookaside LB를 사용할 수 있음
- client-side LB에서 load balancing 관련된 로직을 Central Core로 따로 빼내는 식.
- LookAside LB에서 백엔드 서버의 정보를 토대로 로드밸런싱 수행, 클라이언트에게 '백엔드 서버 리스트'를 전달함.
- rollout strategies / routing strategy 진행할 때에도 유용함.
- 결국 Client에서 처리할 로직 일부를 공통로직으로 분리 -> service Mesh 철학과도 유사한 지점이 있음
- Lookaside LB를 gRPC client의 control plane이라고도 볼 수 있기 때문
문제는, migration이 쉽지 않다. 정확히는 hermes를 쓰고 있는 회사에서 'Not hermes' 하도록 만드는 작업이 어렵다.
- Autonomous Team을 꾸리고, 권한과 신뢰를 부여함. 이 작업이 회사 차원에서 더 나은 길로 가는 초석임을 자발적으로 안내할 수 있는.
- "Use gRPC" 가 아니라 Why This Makes Sense를 끊임없이 설명하도록 했고, 전환 과정에서 발생하는 failure는 learning experience
Autonomy (자율) != Freedom (자유)
- High Autonomy / Low Alignment -> 각자 자기 하고 싶은 것만 진행... Goal 달성 불가
- Low Autonomy / High Alignment -> Top-down 방식. hard to Scale / Empowering.
Golden Path 제공. 개발자포털에서 각 기술영역별로 Path 제공 - Least Resistence일 뿐 강제는 아님.
- gRPC를 Golden Path로 적용, hermes를 golden path에서 제외.
- = gRPC를 쓰는 게 right / easy choice임.
Golden Path 적용할 경우의 이점 (Carrot) 제공. hermes의 경우 gRPC에 비해 ecosystem이 없다는 문제가 있었으므로, 도입 시의 이점은 쉽게 어필이 가능했음.
하지만 Migration을 자율에만 맡기면, 영원히 끝나지 않을 수 있다. 어느 정도는 강제책이 필요함. hermes의 End of Life를 설정한다던가.. 언젠가는 migrate할 수밖에 없도록.