Callosum: An RPC Tranport Library
- Web Service
- Difficulty Experienced
- 2018-08-19 (일요일) 15:40 - 16:20
- 한국어
- 101
- Photography and recording is allowed
Slide
https://speakerdeck.com/achimnol/pycon-kr-2018-callosum-an-rpc-transport-library
Video
https://www.youtube.com/watch?v=3V4-9JfQEvg
Description
저는 Backend.AI를 개발하면서 2017년 파이콘에서 aiotools 라이브러리를 공개한 바 있습니다. 이번에는 그 연장선에서 aiozmq를 대체할 새로운 asyncio 기반 RPC Transport 라이브러리인 Callosum을 소개하고자 합니다.
Callosum은 단순함을 목표로 설계되었고 암호화된 통신을 기반으로 대용량 스트리밍과 사용자가 선택한 IDL 기반의 메시징을 동시에 지원합니다. (GitHub : https://github.com/lablup/callosum)
aiozmq는 공식 ZeroMQ 바인딩 라이브러리인 pyzmq가 asyncio를 정식 지원하기 전까지 많이 사용되었던 asyncio용 ZeroMQ 바인딩 라이브러리입니다. 기본적인 read/write API 외에도 Python 클래스의 메소드를 자동으로 원격에서 별도의 프로토콜 선언 없이 일반 Python 함수처럼 호출할 수 있는 간단한 RPC 기능을 aiozmq.rpc라는 하위 패키지로 함께 제공합니다. 본 발표에서는 더 강력한 기능과 함께 이를 대체하고자 직접 개발한 Callosum RPC Transport 라이브러리를 소개합니다.
대상 청중
이 발표는 Python 언어에 대해서는 잘 알고, asyncio에 대해서는 기본 개념을 알고, HTTP/RPC 라이브러리를 사용해봤거나 직접 만들어본 경우 또는 네트워킹 프로그래밍을 해본 중급~고급 청중들을 대상으로 합니다.
프로젝트 이름에 대하여
Corpus Callosum은 “뇌량” 또는 “뇌들보”라고 불리는 뇌 조직의 명칭입니다. 좌뇌와 우뇌 반구를 연결하는 신경 축삭 다발로, 좌뇌와 우뇌의 서로 다르게 특화된 기능 영역들이 정보를 주고받는 데 필수적인 구조물입니다. (예: 왼쪽 눈으로 본 글자 영상을 우뇌의 시각 중추에서 처리 후 좌뇌의 언어 중추로 보내 의미 해석)
대용량 스트리밍과 RPC가 모두 가능하다는 점과 단일 통신 채널을 멀티플렉싱하여 활용한다는 점에서 뇌량의 이름을 따오게 되었습니다. 그리고 IDL과 같이 인자 검사·변환·직렬화와 관련한 계층은 사용자가 선택할 수 있도록 남겨두었다는 점에서 그냥 RPC가 아닌 “RPC Transport” 라이브러리라고 이름을 붙였습니다.
개발 동기
Backend.AI 개발 초기부터 aiozmq.rpc를 활용해왔는데, 2018년 들어 asyncio 공식지원이 포함된 pyzmq v17이 발표되면서 현재 aiozmq는 개발이 중단되었습니다. 따라서 이를 대체할 RPC 라이브러리가 필요한 상황이 되었습니다.
가장 간단한 방법은 이미 존재하는 asyncio 호환 RPC 라이브러리를 활용하여 기능을 확장하는 것인데, 다음과 같은 이유로 이를 선택하지 않았습니다.
- Transport 계층 확장의 어려움 : gRPC, Thrift, Nirum 모두 별도의 서비스 정의를 작성하는 IDL이 있는데, 코드 생성기를 통해 만들어진 모듈이 내가 원하는 transport 계층의 특성을 만족하지 않는 경우 이를 수정하기가 어렵습니다.
Backend.AI의 개발 로드맵에 따르면 다중 클라우드 또는 사용자의 로컬 PC와 클라우드를 직접 연동하는 기능이 예정되어 있는데, 이를 위해서는 다음과 같은 transport 계층의 추가 기능들이 필요합니다: - 사전 발급된 공개키·비밀키 쌍에 의한 클라이언트 인증과 end-to-end 암호화 통신
- RPC 클라이언트가 여러 쓰레드 또는 서버에서 나눠서 실행되더라도 같은 API를 호출할 때 동일 ephemeral key에 대해서 실행 및 응답 순서 보장
- 대용량 데이터의 업로드·다운로드를 위한 스트리밍 지원과 선택적 메시지 및 스트림 압축이 가능해야 함
- 서버-클라이언트 역할 뒤집기 또는 양방향 RPC의 미지원 : 일반적인 RPC 라이브러리에서는 네트워크 관점에서의 서버-클라이언트가 RPC 서비스 관점에서의 서버-클라이언트와 동일합니다. 하지만 Backend.AI에서는 네트워크 관점에서는 Agent가 Manager로 연결을 맺지만, RPC 관점에서는 Manager와 Agent가 상호 서비스 호출을 할 수 있어야 합니다. (예: Manager는 Agent에게 컨테이너 생성 요청, Agent는 Manager에게 자신의 상태 변화에 대한 이벤트 통지) 기존 RPC 라이브러리들은 이러한 양방향 서비스를 지원하지 않거나 서버-클라이언트를 이중으로 개발해야 합니다.
API나 RPC의 Transport 계층으로 현재 가장 많이 사용되는 것은 HTTPS일 것입니다. 하지만 역시 몇 가지 이유로 이를 선택하지 않았습니다.
- 보안 계층인 SSL의 인증서 관리의 복잡함 : 서버와 클라이언트 상호 인증이 가능한 가장 강력한 보안 기능을 제공하지만, 미리 등록된 public key에 의한 클라이언트 인증만 하면 되는 상황에서 CA 관리까지 할 필요는 없었습니다.
- ephemeral key를 공유하는 서로 다른 요청에 대한 응답 순서 보장 기능의 미비 : 어차피 이건 새로 짜야 합니다.
- RPC와 스트리밍 맥락을 구분하면서 상위 계층과 상호작용하려면 직접 많은 코드를 짜야 합니다.
즉, HTTP와 RPC의 매개자 역할을 하는 라이브러리가 필요한데, 바로 그것이 Callosum의 역할입니다.
개발 지향점
- 단순함 : aiozmq.rpc보다 단순할 것
- 네트워킹에 집중 : 스트리밍, 보안인증, 메시지 순서보장 등을 중점적으로 다루고, Callosum 본체 자체는 별도 IDL 없이도 사용 가능할 것
- 확장성 : 필요하다면 사용자가 Protobuf, Nirum, Thrift, MessagePack, JSON 등 임의의 IDL 컴파일러 및 직렬화 방식을 자유롭게 선택할 수 있도록 할 것
- 오류 전파 : asyncio는 취소 및 타임아웃 오류에 대한 별도 처리가 필요한데, 이를 고려한 정확한 오류 전파 메커니즘 내장
- MVP (minimum-viable product) : 최초 API 구현부터 바로 기존 코드에 적용 가능한 상태로 유지하며 확장 기능들을 하나씩 붙여나가는 방식으로 개발
특징
- ZeroMQ 백엔드 : pyzmq + 클라이언트 인증 및 암호화 통신은 CurveZMQ 활용
- flat namespace 기반 API 라우팅
- 메시지 헤더와 메타데이터 처리는 내장하되, 메시지 본문에 대한 IDL/직렬화는 사용자 정의 가능
- 메시지 본문 및 스트리밍 데이터의 snappy 압축 지원
- 단일 채널의 멀티플렉싱을 통한 RPC 및 대용량 스트리밍 동시 지원