SQL Server 2016, Shard 또는 다중 테넌트 시스템이 테넌트별로 별도의 데이터베이스를 통해 테넌트를 격리해야합니까?


12

유스 케이스가 주어지면 :

  • 테넌트 데이터는 상호 대화해서는 안되며, 한 테넌트는 다른 테넌트 데이터가 필요하지 않습니다.
  • 각 테넌트는 잠재적으로 큰 히스토리 데이터 볼륨을 가질 수 있습니다.
  • SQL Server는 AWS EC2 인스턴스에서 호스팅됩니다.
  • 각 세입자는 지리적으로 멀리 떨어져 있습니다.
  • PowerBI Embedded와 같은 타사 시각화 도구를 사용하려는 의도가 있습니다
  • 데이터 볼륨은 시간이 지남에 따라 증가 할 것으로 예상됩니다
  • 시스템 비용이 제한됩니다.
  • 24/7 프로덕션 DBA없이 솔루션을 유지 관리 할 수 ​​있어야합니다
  • 솔루션은 수평으로 확장 할 수 있어야합니다.
  • 총 입주자 수가 50 명 미만

권장되는 아키텍처는 무엇입니까?이 사용 사례에 대한 참조 구현이 있습니까? 많은 사람들이 이미 엔터프라이즈 소프트웨어 개발에서이 문제에 직면했을 것으로 생각합니다.

다중 테넌트 데이터베이스 아키텍처에서 점점 더 많은 테넌트처리 하는 것과는 다른 상황이라고 생각합니다 . 이 질문에 언급 된 유스 케이스는 더 많은 수의 테넌트를 다루며, 이는 거의 (50) 개의 큰 테넌트를 갖는 것과는 다릅니다. 언급 된 아키텍처는 여기에 대한 해결책 일 수 있으며, 이것이 내가 더 알고 싶어하는 것입니다.

답변:


16

샤딩의 문제점은 애플리케이션이 쿼리 할 샤드를 알아야한다는 것입니다. 일반적으로 이것은 클라이언트와 같은 것을 샤딩하여 수행됩니다. 나는 적응거야 내 옛날 블로그 게시물 중 하나를 내 대답으로 사용할 수 있습니다.

많은 클라이언트를위한 응용 프로그램을 구축 할 때 데이터베이스를 디자인하는 일반적인 두 가지 방법이 있습니다.

  • 옵션 A : 모든 클라이언트를 동일한 데이터베이스에 배치
  • 옵션 2 : 클라이언트 당 하나의 데이터베이스 작성

모든 클라이언트를 같은 데이터베이스에두기

간단합니다. 스키마 상단에 Client 테이블을 추가하고 ClientUsers 테이블을 추가하여 사람들이 자신의 데이터 만 볼 수 있도록합니다.

이 방법의 장점 :

더 쉬운 스키마 관리. 개발자가 새 버전의 응용 프로그램을 배포 할 때 하나의 데이터베이스에서만 스키마를 변경하면됩니다. 서로 다른 고객이 동기화되지 않았거나 잘못된 버전을 사용하는 것에 대해 걱정할 필요가 없습니다.

보다 쉬운 성능 조정. 한 곳에서 색인 사용 및 통계를 확인하고, 쉽게 개선을 구현하며, 모든 고객에게 즉시 영향을 확인할 수 있습니다. 수백 또는 수천 개의 데이터베이스를 사용하면 아주 작은 변경이라도 조정하기가 어려울 수 있습니다. 프로 시저 캐시 내용을 확인하고 전체 응용 프로그램에서 가장 집중적 인 쿼리 또는 저장 프로 시저를 확인할 수 있지만 클라이언트마다 별도의 데이터베이스를 사용하는 경우 다른 실행 계획에서 쿼리 사용을 집계하는 데 시간이 더 걸릴 수 있습니다.

외부 API를 쉽게 구축 할 수 있습니다. 외부인이 제품을 빌드 할 수 있도록 전체 데이터베이스에 대한 액세스 권한을 부여해야하는 경우 모든 데이터가 단일 데이터베이스에있는 경우 더 쉽게 수행 할 수 있습니다. API가 여러 서버의 여러 데이터베이스에서 데이터를 그룹화해야하는 경우 개발 및 테스트 시간이 추가됩니다. 반면에,“다중 서버”는 단일 데이터베이스에서 규칙까지의 모든 시나리오에 대한 제한을 암시하기 시작합니다. 하나의 데이터베이스는 일반적으로 모든로드가 하나의 데이터베이스 서버에만 영향을 미칩니다. PowerBI를 사용하면 하나의 데이터베이스에 모든 사람이 있으면 연결 관리가 훨씬 쉬워집니다.

고 가용성 및 재해 복구가 쉬워집니다. 데이터베이스 미러링, 로그 전달, 복제 및 클러스터링을 관리하기가 정말 간단합니다. 데이터베이스 하나만 걱정하면됩니다. 우리는 신속하게 인프라를 구축 할 수 있습니다.

자체 데이터베이스 또는 샤드에 각 클라이언트 배치

여전히 클라이언트 목록이 필요하지만 이제는 디렉토리가됩니다. 각 클라이언트에 대해 샤드도 추적합니다. 시작시 앱이이 테이블을 쿼리하고 RAM에 캐시합니다. 클라이언트에 대한 데이터가 필요한 경우 해당 샤드 (데이터베이스 및 서버)에 직접 연결됩니다.

이 방법의 장점 :

더 쉬운 단일 클라이언트 복원. 고객은 신뢰할 수없는 미트 백입니다. (제외 – 그들은 믿을 수있는 미트 백입니다.) 그들은 모든 데이터를 특정 시점으로 되돌리려 고하는 모든 종류의 "oops"순간을 가지고 있습니다. 동일한 테이블의 다른 클라이언트 데이터 단일 클라이언트 데이터베이스 시나리오에서의 복원은 매우 간단합니다. 단지 클라이언트 데이터베이스를 복원하면됩니다. 다른 사람은 영향을받지 않습니다.

더 쉬운 데이터 내보내기. 고객은 데이터를 손에 넣는 것을 좋아합니다. 그들은 까다로운 공급 업체 잠금 시나리오를 피하면서 원하는 시간에 데이터를 얻을 수 있다는 사실을 알고 보안을 원하며 자체보고를 원합니다. 각 클라이언트의 데이터를 자체 데이터베이스로 분리하면 자체 데이터베이스 백업 사본을 제공 할 수 있습니다. 데이터 내보내기 API를 구축 할 필요가 없습니다.

보다 쉬운 다중 서버 확장 성. 애플리케이션이 단일 서버에서 얻을 수있는 것보다 더 많은 전력을 필요로하는 경우 데이터베이스를 여러 서버로 나눌 수 있습니다. 또한 지리적으로 부하를 분산시켜 아시아나 유럽의 서버를 고객과 더 가깝게 만들 수 있습니다.

보다 쉬운 클라이언트 별 성능 조정. 일부 고객이 다른 기능이나 보고서를 사용하는 경우 모든 사용자의 데이터 크기를 늘리지 않고도 해당 고객을 위해 특수화 된 색인 또는 색인 된보기를 작성할 수 있습니다. 여기에는 약간의 위험이 있습니다. 클라이언트 간의 스키마 차이를 허용함으로써 코드 배포를 조금 더 위험하게 만들고 성능 관리를 더욱 어렵게 만들었습니다.

보다 쉬운 보안 관리. 데이터베이스 당 한 명의 사용자로 보안을 제대로 잠그면 Client X가 Client Y의 데이터에 액세스하는 것에 대해 걱정할 필요가 없습니다. 그러나 모든 사용자에게 단일 로그인 만 사용하는 경우 실제로 이러한 문제를 해결하지 못했습니다.

더 쉬운 유지 관리 기간. 전 세계에 고객이 흩어져있는 글로벌 환경에서는 그룹이나 영역에서 고객을 유지 관리하기 위해 오프라인 상태로 유지하는 것이 더 쉽습니다.

어느 것이 당신에게 옳습니까?

올바른 선택은 없습니다. 회사의 강점과 약점을 알아야합니다. 내 고객 중 두 명을 예로 들어 봅시다.

회사 A는 하드웨어 성능 조정에 탁월합니다. 그들은 실제로 하드웨어에서 가장 마지막 성능을 발휘하는 데 능숙하며 12-18 개월 주기로 SQL Server 하드웨어를 교체하는 것을 신경 쓰지 않습니다. (4-6 개월마다 웹 서버를 새로 고칩니다!) Achilles의 발 뒤꿈치는 극한의 준수 및 보안 요구 사항입니다. 감사 요구 사항이 엄청 나며 수십 대의 서버에서 수천 개의 데이터베이스에 대한 요구 사항을 관리하는 것보다 단일 서버의 단일 데이터베이스에서 방탄 제어를 구현하는 것이 더 쉽습니다. 그들은 하나의 데이터베이스, 하나의 서버, 많은 클라이언트를 선택했습니다.

회사 2는 개발 관행에 탁월합니다. 수천 개의 데이터베이스에서 스키마 변경 및 코드 배포를 관리하는 것은 문제가되지 않습니다. 전 세계에 고객이 있으며 24 시간 내내 해당 고객에 대한 신용 카드 거래를 처리하고 있습니다. 지리적으로로드를 분산시킬 수있는 능력이 필요하며 12-18 개월마다 전세계 서버를 교체하고 싶지 않습니다. 그들은 각 클라이언트마다 하나의 데이터베이스를 선택했으며, 해외 클라이언트를 위해 아시아와 유럽에 SQL Server를 설치하기 시작하면서 비용을 지불하고 있습니다.


"귀하의 경우 PowerBI를 사용하면 하나의 데이터베이스에있는 모든 사람이 연결 관리를 훨씬 쉽게 할 수 있습니다." 지금 PowerBI은 행 수준 보안이없는 임베디드 따라서 하나의 데이터베이스에있는 모든 임차인이 사용 사례에 대한 몇 가지 의문을 일으키는 데, 참조 : community.powerbi.com/t5/Developer/...를 ,이 정보에 비추어 당신이 바꿔을 기쁘게 할 수 이것은 대안을 제안하거나 내 이해를 수정합니까?
DS

또한 "자신의 데이터베이스 또는 샤드에 각 클라이언트를 넣기"는이 두 제안의 차이점을 자세히 설명 할 수 있습니다.
DS

두 개 이상의 데이터베이스에 배포해야하는 것이 사운드를 만드는 것만 큼 나쁘지 않다고 말할 수 있습니다. 2017 년에는 1, 5 또는 900 개의 데이터베이스에 변경 사항을 매우 쉽게 배포 할 수있는 많은 옵션이 있습니다. 특정 고객에 대한 예외가있는 경우 일반적으로 공통 코드를 방해하지 않는 방식으로 데이터베이스에 도입 될 수 있습니다.
Aaron Bertrand

5

다른 답변에서 아직 보지 못한 한 가지 추가 고려 사항.

단일 데이터베이스에서 여러 테넌트를 허용하는 디자인을 사용하면 나중에 유연성을 얻을 수 있습니다. 나중에로드 / 스케일 아웃 / 보안 / 지역 위치 요구에 따라 테넌트는 새 인스턴스에서 currect DB를 복원하여 생성 할 수있는 별도의 데이터베이스를 가져야한다고 제안합니다. 다른 테넌트의 데이터는 어떤 메커니즘을 사용하더라도 여전히 보호됩니다. 현재 사용되지 않는 데이터는 시간이 허락하는대로 기존 데이터베이스와 새 데이터베이스 모두에서 단편을 제거 할 수 있습니다.

그 반대입니다. 많은 테넌트 데이터베이스를 통합하려면 훨씬 더 많은 작업이 필요합니다.


4

정규화가 깨지더라도 멀티 테넌트 모델을 훨씬 쉽게 만드는 한 가지 방법은 테넌트의 모든 테이블에 열을 포함시키는 것입니다. TenantID라고 부를 수 있습니다. 이렇게하면 데이터베이스에 대해 실행되는 모든 쿼리가 모든 테이블에서 TenantID를 필터링 할 수 있으며 데이터베이스 파티셔닝을 사용하여 각 테넌트에 대한 데이터를 격리하고 파티션을 정렬하여 쿼리 속도를 높일 수 있습니다. 이 방법으로 모든 테넌트를 하나의 데이터베이스에 보관하는 것이 훨씬 쉽습니다.

* 항상 정규화를 깨지는 것은 아니지만 가능합니다. 예를 들어, PersonPersonAddress테이블 이있는 경우 입니다. Person표해야합니다 TenantID, PersonID기본 키로. PersonAddress표해야합니다 TenantID, PersonID, AddressTypeID내가 제안하고있는 무슨과 기본 키로.

일반적으로 PersonID충분할 것 입니다. Person테이블을 다시 찾아서을 찾을 수 있기 때문 Tenant입니다. TenantID더 얇은 키가 작동하더라도 이후의 모든 테이블로 넘어갈 것을 제안합니다 .

다른 데이터에서 파생 될 수있는 테이블로 정보를 전달하는 것이 정규화를 위반하는 것으로 간주되었습니다. 그러나 아마도 얇은 키를 사용하는 것이 가장 좋습니다.


감사합니다, 제안에 동의하고 그 위에 추가하려면이 필드를 언급하고 싶습니다. TenantID는 정수 유형이어야하며 GUID가 아닌 성능을 위해 태워졌습니다.
DS

3
그러나 TenantID를 자식 테이블로 가져와도되지만 자식 키를 더 많이 사용한다고해서 정규화가 "파손"된 것은 아닙니다. IDENTITY보다 GUID (더 큰 키)를 선택해도 정규화가 중단되지 않으며 대리자를 전혀 사용하지 않고 더 넓은 자연 키를 선택하지 않습니다.
Aaron Bertrand
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.