왜 Golang인가?

어떤 도구이든 그 쓰임새를 잘 알고 적절한 곳에 배치하면 좋을 일이다. 그저 유행이라 한번 끄적여볼 게 아니라 무엇이 이 도구를 돋보이게 하는지 알면 좋지 않을까? 그런 의미에서 Go가 어떤 도구인지 간략하게 알아보자.

동시성! 그리고 Cloud Native

Golang으로 작성한 세계 최대의 GitHub 저장소는 어디인가?  Kubernetes가 그곳이다. Kubernetes와 그 산하의 다양한 프로젝트 외에도 Docker, Terraform 등 다양한 곳에서 Golang을 이용한다. 그리고 이러한 프로젝트는 대부분 클라우드 플랫폼의 도래와 그 탄생(또는 번영)을 함께 한다. 이쯤되면 Golang의 어떤 면이 클라우드 시스템과 맞는지 고민해볼 여지가 생기지 않은가?

대부분의 클라우드 시스템은 API를 통해 인프라스트럭쳐를 제어한다. 문제는 API 를 한번만 호출해서 끝나는 일은 좀처럼 없다는 것이다. AWS RDS를 원하는 상태로 띄우려면 API를 몇 번이나 호출해야 하는가?  Database Subnet 같은 주변 여건을 이미 다 파악한 상태라 하더라도 RDS를 생성하는데 한 번, RDS의 Parameter group 등을 조정하는데 다시 한 번 API 를 호출해야 한다. 그나마 이는 명시적인 API 호출에 한정한 것이고 실제로는 인증과 권한 확인에도 API 호출이 필요하다. API마다 요청과 응답 사이에 상당한 시간이 소요되기 마련이고 RDS 생성과 같은 일에는 적어도 수 분이 추가로 필요하기 때문에 전체 작업은 적지 않은 인내가 필요하다.

자, 이제 RDS 백여대를 통제하는 시스템을 상상해보자. 이 시스템은 외부 트래픽 동향, 백업 등 정책 변경 외의 수십 가지 메트릭과 조건을 추적하고 상황의 변화에 따라 시스템을 유연하게 조정한다. 그런 탓에 일분에 API를 백 여번 호출한다. 그런데 불행하게도 어떤 API는 응답 시간이 평균 45초에 달한다.

이러한 시스템에선 동시성 확보가 필수적이다. RDS 인스턴스를 한 대씩 다뤘다간 일이 제때 끝나지 않는다. 극단적으로 말하자면 인스턴스 백여대를 저글링하듯 한번에 다뤄야 한다. 그러므로 동시성을 강조하는 언어가 각광 받을 수 밖에 없다.

다루기 쉽다

동시성을 (잘 / 그럭저럭) 다루는 언어는 많다. Scala, Erlang, C++ 등등. 그러나 동시성 모델을 단순화한 정도는 서로 다르다. 대부분의 Cloud Native 시스템이 하는 일은 단순하다. external-dns라는 Kubernetes 플러그인이 하는 일이라곤 주어진 조건에 맞춰 로드밸런서에 도메인을 부여하는 게 전부이다. 그런 시스템을 스칼라나 C++로 구축한다면 배보다 배꼽이 크다는 말이 딱 맞다.

배포하기 쉽다

간단히 말해 런타임 시스템이 필요하지 않다. Python이나 JVM 계열의 언어와 달리 운영체제와 프로그램 바이너리만 있으면 된다. VM 런타임의 버전이나 호환성 같은 문제는 신경 쓸 필요없다. 그렇다 보니 배포가 쉽고 그 크기도 작다.

일반적인 애플리케이션이라면 부차적인 장점에 그칠테지만 Kubernetes 처럼 클라우드 인프라를 떠받치는 시스템에선 매우 중요한 요소이다. 배포판의 크기가 크면 시스템을 부트스트래핑하는데 시간이 더 걸린다. 네트워크 환경에 따라 이런 지연은 사고로 이어지기도 한다. 더불어 다수의 컴포넌트가 상호작용하는 분산시스템인 경우, 컴포넌트 하나하나의 크기를 합치면 상당한 규모가 된다. 시스템이 크면 배라, 테스트, 그리고 운영 전반에 고통이 가중된다.

동적 시스템에 적응한다

클라우드 시스템은 동적이다. AWS의 EC2 인스턴스는 수 분 내에 m5.xlarge에서 m5.4xlarge 로 업그레이드할 수 있다. Kubernetes 같은 Container orchestration 시스템 내에선 더 극적이다. 수 초 내에 더 많은 리소스를 확보할 수 있다. 과거와 비교하면 애플리케이션의 외적인 여건은 많이 개선됐다.

그러나 의외로 응용프로그램은 이러한 외적 여건의 변화를 활용하지 못한다. vCPU가 두 배로 늘면 무엇하나? 응용프로그램의 성능은 이에 맞춰 증가하지 않는데. 메모리가 두 배로 늘면 뭐하나? JVM 힙의 크기는 그대로인데. 물론 JVM 힙의 크기를 동적으로 설정하는 기법이 있다. 하지만 우리는 이보다 나은 시스템이 필요하다. 사람이 개입하지 않아도 각 상황에 적합한 설정값으로 작동하는 시스템이 필요하고 Golang은 이를 제공한다.

요약

결론적으로 Golang은 현대적인 클라우드 기반의 시스템을 구축하기에 적합하다.  Go는 결코 완벽하지 않고 만능이지 않다. 그럼에도 몇 가지 장점의 조합은 클라우드 네이티브 시스템을 구축하는데 매우 유용하다.

단, 앞서 언급한 장점이 핵심요소가 아닌 애플리케이션이라면 Go를 고집할 이유가 없다. 동시성보단 비즈니스 로직이 중요한 일반적인 상거래 시스템을 구축한다면 Spring Boot (그리고 그 외의 또다른 도구)가 낫다. Gorilla고 뭐고 Go 기반의 웹 프레임워크는 복잡한 비즈니스 로직을 단순화하는데 그다지 유용하지 않다. 당장 API 파라미터의 유효성을 확인하는 것만 해도 손이 많이 간다. Cloud  환경을 적절히 지원하면서 탄탄한 미들웨어와 커뮤니트를 등에 엎은 Spring Boot가 이런 상황에선 더 강력하다. 또한 데이터 기반의 제품을 구축한다면 파이썬이나 R 같은 언어로 프로타이핑을 빠르게 진행하는 편이 좋다. 데이터를 유연하게 다루는 능력은 Go의 장점이 아니다. 연장은 그 쓰임새가 있다. 벽을 부수는 일에 드라이버를 고집할 이유는 없다.

Advertisements

최 재훈

블로그, 페이스북, 트위터 고성능 서버 엔진, 데이터베이스, 지속적인 통합 등 다양한 주제에 관심이 많다.
Close Menu