Multi-tenancy Architecture

profile
BE Developer - 라이언
September 23, 2023
GPT 요약
Thumbnail

안녕하세요.
덴티움 IT팀의 BE Developer 라이언입니다.

오늘은 저희 IT팀에서 Multi-tenancy 아키텍처를 사용하게된 이유를 공유하고 합니다.

조금 특별한 사용자 요구사항

  • 사용자 그룹 별로 격리된 저장소를 제공해야 한다.
  • 사용자 그룹의 각각의 저장소를 백업 또는 복원할 수 있어야 한다.
  • 사용자 그룹을 추가 또는 삭제할 수 있어야 한다.

위의 사용자 요구사항은 사용자 개개인을 대상으로 하는 일반적인 요구사항이 아닌 사용자 그룹이라는 조금 특별한? 항목이 포함되어 있습니다.

예를 들어 저희 회사에는 저(라이언), 쵸지, 루카스, 제이엠, 기원이 포함되어 있는 IT팀이라는 그룹이 있습니다. 바로 위에서 말씀드린 사용자 그룹이란 바로 IT팀과 같이 각각의 사용자가 속해있는 그룹이라고 이해하시면 됩니다.

또한, 격리된 저장소라는 요소도 조금 생소하실거랑 생각합니다. 일반적으로 사용자의 데이터를 하나의 저장소에서 관리합니다. 그렇다고 해서 사용자 모두가 저장소에 포함되어 있는 모든 데이터에 접근할 수 있는 것은 아닙니다. 소프트웨어 즉, 논리적인 어떠한 제어(권한)를 통해 사용자가 접근할 수 있는 데이터를 제한하는 것입니다.

하지만, 위에서 말씀드린 격리된 저장소는 논리적이 아닌 물리적으로 사용자가 접근할 수 있는 데이터를 제한하는 것입니다.

여기서 물리적이라는 단어가 조금 애매? 할 수 있을 것 같습니다. 좀 더 명확하게 설명드리자면,

논리적으로 사용자가 접근할 수 있는 데이터를 제한하면 개발 오류 또는 버그로 인해 또는 사용자의 의도하지 않은 설계로 인해 제한되어야할 데이터에 접근할 수 있는 일이 생길 수 있습니다.

물론, 소프트웨어에는 오류 또는 버그가 없어야 합니다.

"완벽한 소프트웨어는 만들 수 없다." - 앤드류 헌트, 실용주의 프로그래머

실용주의 프로그래머 저자 엔드류 헌트는

"실용주의 프로그래머는 자기 자신 역시 믿지 않는다. 자신의 실수에 대비한 방어책을 마련한다."

라고 말합니다.

개발자의 실수에 의해 논리적으로 데이터 제한이 안되더라도 이에 대한 방어책인 물리적으로 데이터 접근이 제한되는 저장소를 격리된 저장소라고 말씀드릴 수 있습니다.

Multi-Tenancy 아키텍처

Multi-Tenancy-Model

@jjude, jjude.com

앞서 말씀드린 사용자 요구사항을 모두 충족시키기 위해 "Multi-tenancy"라는 아키텍처를 사용하게 되었습니다.

그림에서 볼 수 있듯이 Multi-tenancy 모델은 크게 인스턴스 복제 모델데이터 분리 모델로 나뉠 수 있습니다.

Tip

테넌트(Tenant)는 소프트웨어 인스턴스에 대해 공통이 되는 특정 접근 권한을 공유하는 사용자들의 그룹이다.

인스턴스 복제 모델은 모든 테넌트에 대해서 각각의 서버와 데이터베이스를 제공하는 구조입니다.

데이터 분리 모델은 모든 테넌트가 동일한 서버를 사용하지만 각각의 테넌트 마다 별도의 저장소를 제공하는 구조입니다. 해당 모델은 저장소를 어떻게 분리하는지에 따라 2가지로 나뉘게 됩니다.

  • 데이터베이스 자체를 나누어 저장소를 분리하는 방식 (물리적인 구조)
  • 단일 데이터베이스 내부에서 스키마를 나누어 저장소를 분리 하는 방식 (논리적인 구조)
Tip

데이터베이스 스키마(database schema)는 데이터베이스(Database) 전체 또는 일부의 논리적인 구조를 표현하는 것으로 데이터베이스 내에서 데이터가 어떤 구조로 저장되는지를 나타낸다. 정보통신용어사전

그렇다면, 인스턴스 복제 모델, 데이터베이스 분리 모델, 스키마 분리 모델을 좀더 심층 분석해 보겠습니다.

인스턴스 복제 모델

먼저 개발 측면에서 본다면, 사용자 <-> 서버 <-> 데이터베이스와 같이 단순한 구조로 개발한 후에 이 구조를 복제해서 배포하면 되기 때문에 비교적 쉬운 개발 난이도를 가지고 있습니다.

또한, 성능적인 측면으로 봐도 각각의 테넌트 마다 하나의 완전한 서버, 데이터베이스의 성능을 모두 제공받을 수 있기 때문에 나머지 2가지 모델보다 뛰어 납니다.

쉬운 개발 난이도와 우수한 성능이라는 큰 장점이 있지만 그 만큼 큰 비용과 제한적인 확장성이라는 단점이 존재합니다.

각각의 테넌트 마다 하나의 완전한 서버가 제공되기 때문에 해당 테넌트가 유휴(Idle) 상태라면 무의미한 서버 비용이 지출됩니다.

Tip

유휴 상태는 컴퓨터 시스템이 사용 가능한 상태이나 실제적인 작업이 없는 시간. 계산 처리 시간과 데이터 입출력 처리 시간의 차이 등으로 컴퓨터의 어느 한쪽이 대기 상태에 있는 경우이다. 정보통신용어사전

물론, 테넌트가 유휴(Idle) 상태일 때 해당 서버를 종료하고 할 수도 있습니다. 하지만, 테넌트가 다시 서비스를 사용하려고 할 때 지연 시간(서버 부팅 시간)이 존재하고, 테넌트의 유휴(Idle) 상태를 파악하는 기준도 모호하기 때문에 자칫 잘못하면 매번 지연 시간이 존재하는 최악의 성능을 갖는 서비스를 제공할 수도 있습니다.

또한, 만약 1000개의 테넌트에게 서비스를 제공해야 한다면 1000개의 서버와 1000의 데이터베이스가 필요합니다. 상상만 해도 어마어마한 비용이 들거라 예상됩니다. 이처럼 많은 비용으로 인해 확장성에 있어 제한적입니다.

데이터베이스 분리 모델

해당 모델은 모든 테넌트가 하나의 서버를 공유해서 사용하기 때문에 앞서 말씀드린 인스턴스 복제 모델보단 성능이 조금 낮을 수 있습니다.

하지만, 이부분은 단일 서버 성능을 확장하는 방법이 존재하기 때문에 인스턴스 복제 모델와 동일한 성능은 아니지만 비슷한 성능을 제공할 수 있습니다.

단일 서버 성능을 확장하는 방법은 아래에서 좀 더 자세하게 설며드리겠습니다.

비용 측면에서 본다면 테넌트가 유휴(Idle) 상태일 때 발생하는 무의미한 비용이 줄일 수 있습니다.

하지만 확장성 측면에서 본다면 아직까지 테넌트 마다 각각의 데이터베이스를 제공해야 한다는 제한을 가지고 있습니다.

스키마 분리 모델

앞서 말쓴드린 2가지 모델을 분석해보고 해당 모델을 언뜻 보면 해당 모델이 완벽하다고 생각할 수 있습니다.

단일 서버 성능 확장 방법으로 데이터베이스 분리 모델와 비슷한 성능을 보유하고 테넌트가 유휴(Idle) 상태일 때 발생하는 비용도 없고 단일 데이터베이스를 사용하기 때문에 확장성 측면에서도 제한이 없습니다.

하지만, 단일 데이터베이스에서 스키마 즉, 논리적으로 저장소를 분리한 것이기 때문에 처음 사용자 요구사항인 격리된 저장소(물리적으로 분리된 데이터)를 충족시킬 수 없다는 생각이 들 수도 있습니다.

이 의문은 스키마라는 개념을 좀 더 자세하게 알아보면 해결됩니다.

스키마 개념에서의 논리적인 저장소 분리는 앞서 말씀드린 소프트웨어의 논리적인 분리하고는 조금 다릅니다. 소프트웨어의 논리적인 분리는 개발자에 의해 통제되는 분리입니다. 따라서 개발자의 실수로 인해 분리가 제대로 이루어 지지 않을 수 있습니다.

하지만 스키마 개념에서의 논리적 분리는 데이터베이스 구조적으로 통제되는 분리입니다. 따라서 개발자의 실수로 인해 분리가 제대로 이루어 지지 않는 상황은 배제할 수 있습니다.

분석 요약표

앞서 3가지 모델에 대한 분석을 기반으로 다음과 같이 표로 정리해 볼 수 있습니다.

기준인스턴스 복제 모델데이터베이스 분리 모델스키마 분리 모델
성능⭐️⭐️⭐️⭐️⭐️⭐️⭐️
비용⭐️⭐️⭐️⭐️⭐️⭐️
확장성⭐️⭐️⭐️⭐️⭐️⭐️

좀 더 개선된 아키텍처

Multi-Tenancy 아키텍처의 3가지 모델을 분석해 보며 각각의 장단점을 알아보았습니다.

그 결과 저희 팀에서는 스키마 분리 기반의 Multi-Tenancy 아키텍처를 사용하기로 하였습니다

앞서 조금 언급했듯이 인스턴스 복제 모델 보다는 성능이 조금 아쉬울 수 있는 단점이 존재하였습니다.

그래서 이 단점을 해결하기 위해 구조를 좀 더 개선해 보았습니다.

Structure

위 그림에 대해서 하나씩 살펴 보겠습니다.

  • Tanent 1~N는 사용자 그룹들을 의미합니다.
  • Load Balancer는 Tanent들의 요청을 분산시켜 특정 서버가 과부화되는 것을 방지하는 시스템입니다.
  • Auto Scaling는 가변적으로 App의 개수가 증감하는 시스템입니다.
  • Database의 스키마
    • Common는 각각의 Tenant와 Tenant `스키마를 매칭시켜주는 정보가 포함된 저장소입니다.
    • Default는 신규 Tenant가 생성되면 이에 따라 초기 Tenant 스키마를 설정해야 합니다. 이때 사용되는 정보가 포함된 저장소입니다.
    • Tenant 1~N는 사용자 그룹(Tenant)와 1대1로 매칭되는 구조적(논리적)으로 분리된 저장소입니다.

위에서 과제로 남겨 두었던 단일 서버 성능을 확장하는 방법을 바로 Load BalancerAuto Scaling를 활용하여 Tanent들이 공유해서 사용하는 App의 개수를 조절하여 비용 대비 효율을 극도로 끌어 올리는 것입니다. 저희 IT팀에서는 해당 시스템은 Kubernetes를 활용하였습니다.

결론

이번 글에서는 조금 특별한 사용자 요구사항을 조금 특별한 아키텍처를 사용하여 해결한 경험을 공유드렸습니다. 하지만, 모든 웹 애플리케이션에 Multi-tenancy 아키텍처가 필요한 것은 아니며, 또한 스키마 기반의 분리 방식이 무조건 정답일 수 없습니다.

글 초기에 말씀드린 3가지 사용자 요구사항과 비슷한 문제에 직면하고 계시다면 해당 방안을 시도해 보는 것도 좋을 것 같습니다.

profile
안녕하세요 👏
BE Developer 라이언입니다.