[ 일단 지난주 캐치업 ]
지난주에 socket기반 간단한 통신프로그램을 만들었고, 이제는 Redis와 Cloud-run을 이용해서 scale-out이 가능한 형태의 아키텍처로 만들어봐야겠다 생각하고 있었다. 사실 쿠버네티스를 적용시키기에는 공부할게 좀 많아보여서 cloud-run을 사용하게된 것인데 구체적으로 어떻게 만드는 게 좋을지는 계속해서 고민하게 되는 부분이였다.
그러던 와중에 무려 2021년 3월!! 불과 3개월전에 Google의 cloud-run과 kubernetes를 개발하는 개발자가 직접 high-scale chat server를 cloud-run을 통해 빌드한 내용을 포스팅한 것을 찾아냈다. 참고해서 바로 구성해봐야겠다.
[ 이해를 해보자! ]
내가 Cloud-run을 선택한 가장 큰 이유는 auto-scailing이 쉽게 가능해진다는 점이였다. 부가적으로 배포가 간편하고 컨테이너 생태계와 완벽하게 호환된다는 점이 장점이였다. 내용을 끝까지 읽어보니까 Cloud-run을 사용하는 비용은 트래픽에 따라 즉시 스케일링이 가능한 만큼 상당히 비싸다. 따라서 부하가 예측가능해지면 비용이 훨씬 저렴한 가상머신(GCE or GKE)으로 이동시키는 것이 합리적이다.
아키텍쳐 구조를 살펴보면 Cloud-run은 중간에서 컨테이너화 된 서비스를 관리한다. 부하가 많아지면(client 사용자가 많아지면) 컨테이너 인스턴스들을 추가할 것이고, 반대라면 사용하지 않는 컨테이너 인스턴스를 종료시킬 것이다. 따라서 이 서버는 Stateless하다. 이 말은 곧, 과거의 채팅정보를 저장하기 위한 별도의 스토리지를 구성해야 한다는 말인데 일단은 Stateless형태의 서버로 만들어보려고 한다. 추가로, Cloud-run에서 돌아가는 다양한 컨테이너 사이의 데이터 동기화를 위해서 Redis의 Pub/Sub protocol을 사용한다.
[ Redis에서 Pub/Sub protocol이 뭔데? ]
Pub/Sub은 채널을 구독한 subscirber들에게 모든 메세지를 전송하는 것을 의미한다. 구독한 사람들에게 바로 메세지를 보내니 데이터를 저장하지 않는다. 다시말해 새로운 메세지가 발생하면, 영구적인(물론 Life-cycle안에서) TCP connection위에 연결된 모든 구독자들에게 메세지를 보낸다. 이러면 어렵지 않게 데이터의 상태를 동기화시킬 수 있다. Redis는 RabbitMQ나 Kafka와 같이 전문적인 메세징 시스템의 pub/sub처럼 고도화된 기능을 제공하지는 않지만, MemoryDB의 특징을 살려 가볍고 빠른 Pub/Sub기능을 가지고 있다.
[ Container에서는 어느정도 Client를 감당할수 있나? ]
실제 개발부서에 속한 개발자라 그런지 상당히 구체적인 수치를 제공해준다. Cloud-run은 하나의 Container로 다수의 Client들을 동시에 감당할 수 있는데, 현재는 1개의 컨테이너당 대략 250명의 client를 감당할 수 있다고 한다. 그리고 Cloud-Run은 최대 1000개 정도의 컨테이너를 동시에 유지할 수 있으니까 250*1000해서 최대 25만명의 유저를 감당가능하다. 우리 목표는 최대 만명의 유저가 사용할 서비스이기 때문에 굳이 아키텍쳐적으로 걱정할 필요는 없다. 데이터를 Pub/Sub으로 주고받기 위한 Redis또한 걱정할게 없다. Cloud-Memeorystore에 Redis를 배포할 것인데, Cloud-Memeorystore는 인스턴스당 6.5만건의 connection을 지원하기 때문이다.
[ 만들어 보자! ]
이제 실제로 클라우드 환경상에 구성해 보도록 하겠다. 분량이 제법 되어 두번의 포스팅으로 나눠 기록하기로 한다.
구성 단계는 다음과 같다.
1. Cloud MemoryStore에 Redis Instance를 생성한다. (이때 사용할 VPC 네트워크를 선택하고, IP주소를 기록해둔다)
2. VPC Connector를 생성한다. 이것은 Cloud Run service와 Redis를 연결하는 역할을 한다. (이때는 커넥터의 이름을 기록한다.)
3. 생성한 Redis와 VPC connector의 이름을 명시한 application을 Cloud-run에 배포한다.
gcloud beta run deploy chatservice --source=. \
--vpc-connector=[VPC_CONNECTOR_NAME] \
--set-env-vars REDIS_URL=redis://[REDIS_IP]:6379 \
--max-instances=1000 \
--concurrency=250 \
--timeout=3600 \
--allow-unauthenticated
추가 참고중인 내용 :
각 세부 과정에 대한 실제 배포 진행과정과 관련된 포스팅을 이어서 기록하도록 한다.