다중 테넌트 데이터베이스 아키텍처에서 점점 더 많은 테넌트 처리


26

각 테넌트의 응용 프로그램 인스턴스에 대해 별도의 데이터베이스가있는 공용 서버에서 적당한 수의 고객 (테넌트)을 처리하는 것은 비교적 간단하며 일반적으로 올바른 방법입니다. 현재 각 테넌트에 고유 한 데이터베이스 인스턴스가있는 애플리케이션의 아키텍처를보고 있습니다.

그러나 문제는이 응용 프로그램에 많은 수의 사용자가있는 많은 수의 테넌트 (5,000-10,000), 단일 테넌트에 대해 2,000 명이있을 수 있다는 것입니다. 매주 몇 명의 테넌트가 시스템을 확장하도록 지원해야합니다.

또한 모든 테넌트 및 해당 사용자에게 공통 로그인 프로세스가 표시됩니다 (즉, 각 테넌트는 고유 한 URL을 가질 수 없음). 이를 위해서는 중앙 집중식 로그인 프로세스와 시스템을 데이터베이스에 동적으로 추가하고 사용자를 등록하는 수단이 필요합니다.

  • 등록 및 데이터베이스 생성 프로세스를 어떻게 강력하게 자동화 할 수 있습니까?

  • 시스템에서 테넌트 데이터베이스를 작성하고 등록하는 과정에서 성능 또는 잠금 문제가 발생할 가능성이 있습니까? 이것이 문제가 될 수 있다고 생각되면 누구나 완화 할 수있는 방법을 제안 할 수 있습니까?

  • 사용자 자격 증명이 특정 테넌트 데이터베이스와 연결되지만 사용자가 공통 페이지 (예 : 모두 동일한 로그인 URL을 통해)를 통해 로그인 할 수 있지만 홈 응용 프로그램이 특정 테넌트 데이터베이스에있는 방식으로 중앙 인증을 관리하는 방법 ). 테넌트는 자체 로그인 및 권한을 유지할 수 있어야하지만 중앙 로그인 시스템은이를 인식해야합니다. 누구든지 이것을 할 수있는 방법을 제안 할 수 있습니까?

  • 여러 데이터베이스 서버를 추가하여 '스케일 아웃'해야하는 경우, 서버 (사용자 가장 등)에서 사용자 ID를 관리 할 때 어떤 문제를 해결해야하는지 제안 할 수 있습니까?


1
이와 같은 상황을 처리 할 필요는 없었지만 내 직관은 처리 할 수 ​​있다고 생각되는만큼 많은 테넌트 데이터베이스가있는 서버를 미리 구성하여 테넌트 롤아웃을 처리 한 다음 사전 구축 된 테넌트 데이터베이스를 새로운 테넌트로 할당하는 것입니다. 가입하십시오. 따라서 테넌트 DB를 배포하는 동안 리소스 경합에 대해 걱정할 필요가 없습니다.
Joel Brown

1
5,000 ~ 10,000 명의 임차인과 가까운 곳에 있습니까? 그리고 모든 임차인이 2,000 명의 사용자 범위에 있습니까? 내 시스템에서 단일 테넌트에 대한 응용 프로그램의 최대 사용자 수는 약 100 명이라고 생각합니다. 그리고 20 명 정도만이 지속적으로 활동했습니다. 산업 / 응용 프로그램이 무엇인지 물어볼 수 있습니까?
Aaron Bertrand

@AaronBertrand 서비스는 부분적으로 무료이며 부분적으로 지불되는 학습 관리 시스템입니다.
coddey

답변:


25

하단 (500 테넌트 / 10000 사용자)에서 이것이 내가 한 방법입니다. 먼저, 전체적으로 중앙에 있고 테넌트 및 사용자에 대한 모든 정보를 포함하는 "제어"데이터베이스가 있습니다 (실제로 SQL 인증 로그인으로 관리하고 싶지는 않습니다). 다음 테이블이있는 "Control"이라는 데이터베이스를 상상해보십시오.

CREATE TABLE dbo.Instances
(
  InstanceID INT PRIMARY KEY,
  Connection VARCHAR(255)
  --, ...
);

INSERT dbo.Instances SELECT 1, 'PROD1\Instance1';
INSERT dbo.Instances SELECT 1, 'PROD2\Instance1';
-- ...

CREATE TABLE dbo.Tenants
(
  TenantID INT PRIMARY KEY,
  Name NVARCHAR(255) NOT NULL UNIQUE,
  InstanceID INT -- Foreign key tells which instance this tenant's DB is on
  --, ...
);

INSERT dbo.Tenants SELECT 1, 'MyTenant', 1;
-- ...

CREATE TABLE dbo.Users
(
  UserID INT PRIMARY KEY,
  Username VARCHAR(320) NOT NULL UNIQUE,
  PasswordHash VARBINARY(64), -- because you never store plain text, right?
  TenantID INT -- foreign key
  --, ...
);

INSERT dbo.Users SELECT 1, 'foo@bar.com', 0x43..., 1;

새 테넌트를 추가 한 경우 관리자가 UI에서 확인을 클릭 할 때가 아니라 데이터베이스를 동적으로 빌드하지만 5 분마다 큐에서 새 데이터베이스를 가져 오는 백그라운드 작업이 있었고 모델을 single_user로 설정했습니다. 그런 다음 각 새 데이터베이스를 순차적으로 작성했습니다. (a) 관리자 사용자가 데이터베이스 생성을 기다리는 것을 방지하고 (b) 두 관리자 사용자가 동시에 데이터베이스를 만들려고하거나 모델을 잠그는 기능을 거부하는 것을 피하기 위해 (새 데이터베이스를 만들 때 필요함) ).

데이터베이스는 이름 구성표 Tenant000000xxxx표현되었습니다 Tenants.TenantID. 이로 인해 이름 BurgerKingMcDonalds, KFC등인 모든 종류의 데이터베이스를 보유하는 대신 유지 보수 작업이 매우 쉬워졌습니다 . 우리는 패스트 푸드가 아니라 단지 예로 사용했습니다.

우리가 의견에서 제안한 것처럼 수천 개의 데이터베이스를 사전 할당하지 않은 이유는 관리자 사용자가 일반적으로 테넌트가 얼마나 커질 지, 우선 순위가 높은지 등을 알기 때문입니다. 따라서 UI에서 기본 선택 항목이있었습니다. 초기 크기 및 자동 증가 설정, 데이터 / 로그 파일이 전송되는 디스크 하위 시스템, 복구 설정, 연결을 끊을 백업 일정 및 사용 균형을 맞추기 위해 데이터베이스를 배포 할 인스턴스에 대한 스마트도 결정합니다 ( 우리의 관리자는 이것을 무시할 수 있습니다). 데이터베이스가 생성되면 테넌트 테이블이 선택한 인스턴스로 업데이트되고 테넌트에 대한 관리자가 생성되었으며 관리자가 자격 증명을 전자 메일로 보내 새로운 테넌트에게 전달했습니다.

단일 진입 점을 사용하는 경우 여러 테넌트가 동일한 사용자 이름을 가진 사용자를 가질 수 없습니다. 모든 사용자가 회사에서 일하고 회사 전자 메일 주소를 사용하는 경우 전자 메일 주소를 사용하는 것이 좋습니다. 우리의 솔루션은 결국 두 가지 이유로 더 복잡해졌습니다.

  1. 둘 이상의 고객을 위해 일하는 컨설턴트가 있었으며 여러 사람에게 액세스해야했습니다.
  2. 실제로 여러 명의 세입자로 구성된 세입자가있었습니다.

그래서 TenantUsers한 명의 사용자가 여러 테넌트와 연결될 수 있는 테이블이 생겼습니다.

처음에 사용자가 로그인하면 앱은 제어 데이터베이스의 연결 문자열 만 알게됩니다. 로그인이 성공하면 찾은 정보를 기반으로 연결 문자열을 작성할 수 있습니다. 예 :

SELECT i.Connection
  FROM dbo.Instances AS i
  INNER JOIN dbo.Tenants AS t
  ON i.InstanceID = t.InstanceID
  INNER JOIN dbo.TenantUsers AS u
  ON i.TenantID = u.TenantID
  WHERE u.UserID = @UserID;

이제 앱이 사용자의 데이터베이스 (각 사용자가 기본 테넌트를 가짐)에 연결하거나 사용자가 액세스 할 수있는 테넌트 중에서 선택할 수 있습니다. 그런 다음 앱은 단순히 새 연결 문자열을 검색하고 해당 테넌트의 홈 페이지로 리디렉션합니다.

제안한이 10MM 사용자 영역에 들어가면 균형을 잘 잡기 위해 반드시 필요합니다. 서로 다른 제어 데이터베이스에 연결하는 다른 진입 점을 갖도록 응용 프로그램을 연합 할 수 있습니다. 각 테넌트에 서브 도메인 (예 : TenantName.YourApplicationDomain.com)을 제공하는 경우 추가 스케일 아웃이 필요할 때이를 방해하지 않고 DNS / 라우팅을 사용하여 씬 뒤에서이를 수행 할 수 있습니다.

@Darin과 같이 여기에는 더 많은 것이 있습니다. 여기서 표면을 긁적입니다. 무료 상담이 필요한 경우 알려주십시오. :-)


경험을 공유해 주셔서 감사합니다. 실제로 나를 깨우 쳤습니다. 그러나 당신은 이미 Non-free를 썼습니다. :(
coddey

1
내 요점은 무료 조언에 할당 할 시간이 너무 많다는 것입니다. :-)
Aaron Bertrand

+1-이전에 사용한 것과 거의 동일한 방식입니다. ~ 같은 수의 세입자도 실제로 잘 작동했습니다.
AdaTheDev

마스터 데이터베이스와 테넌트 데이터베이스 간의 관계를 처리하는 방법은 무엇입니까? (트리거 등을 사용하지 않고)
Jitendra Pancholi

@jitendra 실제로 많은 옵션이 아닙니다-테넌트 데이터베이스에 마스터 데이터베이스의 데이터와 관련이 필요한 데이터가 얼마나 있습니까? 나는 또한 방아쇠에 대한 대중적인 두려움을 이해하고 있는지 잘 모르겠습니다. 올바르게 작성된 방아쇠는 두려워 할 것이 없습니다 ...
Aaron Bertrand

10

당신은 자신에게 매우 흥미로운 프로젝트가 있습니다. 나는 적어도 SQL Server에서 큰 것을 구현하려는 사람을 직접 본 적이 없습니다. 내가 당신의 게시물을 읽을수록 더 많은 질문이 나옵니다 ...

최악의 시나리오 인프라 스트럭처 측면 (실제로는 비즈니스 측면에서 가장 좋은 시나리오)에는 10K 데이터베이스에 2k 사용자가 필요합니다. 사용자는 20,000,000 명입니다. 20M SQL Server 로그인 관리에 성공하지 못할 것입니다. IMO. 서버에서 서버로 이동하고 ID 충돌과 일치하지 않는 ID를 감시하고 sys.server_principals에서 SQL Server가 20M 행으로 어떻게 작동하는지 잘 모르겠습니다. 또한 웹 앱은 단일 또는 매우 적은 수의 사용자로 연결하려고 할 것입니다. DSN 문자열이 동일하지 않으면 IIS는 연결을 풀링 할 수 없습니다. DSN 문자열의 속성 중 하나는 사용자 이름입니다. 다른 사용자는 풀링이 없음을 의미합니다.

자신의 사용자 자격 증명 체계를 롤업해야합니다. 사용자가 속한 테넌트를 파악한 다음 웹 코드에서 적절한 데이터베이스를 선택해야합니다. 사용자 메타 데이터는 중요하며, 어딘가에 저장해야하고, 클러스터링 또는 미러링이 필요하고, 빨라야하고, 보안 측면에서 잘 보호되어야합니다 (IOW, 암호화하십시오.). 여기서 SQL이 좋은 아이디어라고 가정하면,이 데이터베이스를 서버 테넌트 인스턴스에서 멀리 유지합니다. 이것은 보안 관점과 부하 관점에서 도움이되지만 일단 사용자가 확인되고 웹 응용 프로그램이 다른 인스턴스의 올바른 데이터베이스로 조정되면 해당 사용자 메타 데이터에 대한 쿼리가 더 이상 없을 것입니다. 사용자.

빠른 질문 : 두 명의 다른 테넌트에 속하는 두 명의 다른 사용자가 동일한 사용자 이름을 가질 수 있어야합니까?

또 다른 빠른 질문 : FuBar, Inc.에서 근무한다고 말하면 어떻게 알 수 있습니까? FuBar가 사용자 목록을 제공하고 사용자 이름 목록을 다시 제공합니까? 아니면 자체 프로비저닝을 수행합니까?

다중 인스턴스로 이동해야합니다. 이러한 사용자 중 일부라도 한 번에 응용 프로그램을 사용하기로 결정하면 단일 인스턴스가 녹습니다. 모든 요청을 한 번에 실행할 수있는 충분한 작업자 스레드가 없습니다. 동시에 1000 명의 사용자 만 인스턴스에 도달하면 작업자 스레드가 부족하여 요청이 쌓이고 대기하기 시작합니다. 나는 이것이 일어나는 것을 보았다; 가장 가까운 증상은 사용할 수있는 작업자 스레드가 없기 때문에 새 연결이 인스턴스에 로그인 할 수 없다는 것입니다. 수명이 매우 짧은 경우 앱이 살아남을 수 있습니다. 그렇지 않거나 앱이 까다로워지면 사용자에게 오류가 발생합니다.

시작할 테넌트가 많지 않더라도 미래와 자동화에 대한 생각을 시작해야합니다. 서버가 다운되어 온라인으로 가져올 테넌트 10 개가 너무 길어서 서비스가 너무 늦어서 문제에서 벗어날 길을 쓸 때까지 고객과 곧 고객이 될 것입니다.

오버로드 된 서버에서 약간로드 된 (또는 새로운) 서버로 데이터베이스를 이동하는 방법이 필요합니다. 가동 중지 시간을 확보 할 수 있는지 여부는 SLA에 따라 다릅니다.

SalesForce와 같은 특정 응용 프로그램을 제공하고 있습니까? 아니면 이러한 데이터베이스가 테넌트에 넣고 싶은 컨테이너일까요?

데이터베이스가 얼마나 큽니까? 크기가 크지 않으면 템플릿을 제공하는 백업 파일에서 복원 할 수 있습니다. (이것은 모델 데이터베이스와 크게 다르지 않지만 SQL 6.5를 사용한 이후로 실제로 모델을 사용하는 사람을 보지 못했습니다.) 템플릿이 새 데이터베이스 이름으로 복원되면 그런 다음 특정 테넌트에 필요한 새 데이터베이스를 사용자 정의하십시오. 테넌트가 있기 전에는 사용자 지정을 수행 할 수 없습니다. 데이터베이스가 큰 경우 새 테넌트에 공간이 필요하기 전에 미리 복원하는 것을 제외하고는 동일한 기본 절차를 따를 수 있습니다. 이러한 데이터베이스 몇 개를 인스턴스 당 하나씩 보관할 수 있습니다. 너무 많이두면 필요한 것보다 더 많은 하드웨어 및 / 또는 스토리지를 구매해야합니다.

이것이 자신의 앱인 경우 스키마 업데이트를 어떻게 처리합니까? 웹앱으로 연결되는 단일 URL을 사용하는 경우 데이터베이스 버전을 코드 버전과 동일하게 유지하는 방법은 무엇입니까?

더 이상 사용하지 않는 데이터베이스를 어떻게 탐지하고 파괴합니까? A / R 그룹이 누군가 3 개월 동안 청구서를 지불하지 않았다고 말할 때까지 기다리십니까?

테넌트가 권한을 관리하는 경우 앱의 내부 작업에 대한 이해가 있거나 앱의 역할 구조가 매우 단순함을 의미합니다. 대략적인 예로 Blogger와 같은 것을 사용하면 사용자는 (게시물 읽기), (게시물 읽기 및 댓글 작성), (... 및 게시물 만들기), (... 및 다른 사람의 게시물 편집), (... 다른 사용자 비밀번호) 또는 (... 등) 서로 다른 권한 세트 각각에 대한 역할을 갖고 사용자를 한 역할 또는 다른 역할에 할당하는 것은 어렵지 않지만 앱이 'GRANT'문을 실행하는 것을 원하지 않습니다. 계층 구조가 있고 상속에 의존하는 역할을 살펴보면 혼란 스러울 수 있습니다. 사용자를 홍보하거나 강등하려는 경우 모든 관련 역할에서 사용자를 끌어 낸 다음 필요한 역할 하나에 다시 추가한다고합니다. 오,

여기에 표면 만 긁은 것으로 생각되며이 게시물은 이미 너무 깁니다. 당신이 정말로 필요한 것은 책, 또는 이것을 한 사람의 백서입니다. 그들이 경쟁 우위라고 생각하면 대부분의 사람들은 말하지 않을 것입니다.


의견을 주셔서 감사합니다. 실제로 프로젝트는 흥미 롭습니다. 단어 제한으로 인해 의견을 매우 정확하게 유지하십시오. 테넌트에 관계없이 각 테넌트가 약 120-150 개의 테이블을 갖게되는 학습 관리 시스템입니다. 복잡성을 더욱 줄이기 위해 DNS CNAME 매핑이 tenant1.abc.com과 같이 사용됩니다. 이제 비등점은 올바른 방식으로 디자인하여 공유 한 모든 제안을 수용하고 걱정하고 있습니다. 백서를 얻는 것은 칭찬 할 만하지 만 쉽지는 않을 것입니다. 가능하다면 더 많은 의견을 구하십시오. !!!!
coddey
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.