SQL Server 데이터베이스 샤딩-공통 데이터 / 비 샤딩 데이터로 수행 할 작업


10

우리는 대규모 엔터프라이즈 급 데이터베이스를 보유하고 있습니다. 비즈니스 모델의 일부로 모든 웹 사용자는 매월 같은 시간에 웹 서버에 접속하여 SQL 상자를 망치게됩니다. 트래픽은 매우 무거 우며 회사가 커질수록 계속 커집니다. sql proc 최적화가 수행되었으며 하드웨어는 이미 매우 높은 수준으로 확장되었습니다.

우리는 회사의 성장과 미래의 부하를 처리 할 수 ​​있도록 지금 데이터베이스를 분할하려고합니다.

어떤 특정 데이터를 샤딩해야하는지 결정했습니다. 그것은 우리의 데이터베이스의 부분 집합으로 많이 활용됩니다.

그러나 내 질문은 공통적이며 보편적 인 비 샤드 데이터에 관한 것입니다. 이와 같은 데이터의 예로는 인벤토리 테이블 또는 직원 테이블, 사용자 테이블 등이 있습니다.

이 공통 / 유니버설 데이터를 처리하는 두 가지 옵션이 있습니다.

1) 설계 1-공통 / 유니버설 데이터를 외부 데이터베이스에 배치합니다. 모든 쓰기가 여기에서 발생합니다. 그런 다음이 데이터는 각 샤드로 복제되어 각 샤드가이 데이터를 읽고 t-sql procs에서이 데이터에 대한 내부 조인을 허용합니다.

2) 디자인 2-각 샤드에 모든 공통 / 유니버설 데이터의 자체 사본을 제공하십시오. 각 샤드가 이러한 테이블에 로컬로 쓰도록하고 SQL 병합 복제를 사용하여 다른 모든 샤드에서이 데이터를 업데이트 / 동기화합니다.

디자인 # 1에 대한 우려

1) 트랜잭션 문제 : 샤드에 데이터를 쓰거나 업데이트 한 다음 예를 들어 1 개의 저장된 프로 시저에서 공통 / 유니버설 테이블을 쓰거나 업데이트해야하는 상황이 발생하면 더 이상이를 쉽게 수행 할 수 없습니다. 데이터는 이제 별도의 SQL 인스턴스 및 데이터베이스에 존재합니다. 이러한 쓰기가 별도의 데이터베이스에 있기 때문에 이러한 쓰기를 트랜잭션으로 래핑 할 수 있는지 확인하려면 MS DTS를 포함해야 할 수도 있습니다. 여기서 성능은 문제가되며 샤드 및 공통 데이터에 쓰는 프로세스에는 재 작성이 필요할 수 있습니다.

2) 참조 무결성 손실. 데이터베이스 간 참조 무결성을 수행 할 수 없습니다.

3) 공통 데이터를 새로운 범용 데이터베이스에 쓰지만 샤드에서 공통 데이터를 읽는 것을 알 수 있도록 시스템의 넓은 영역을 레코딩합니다.

4). 데이터베이스 트립 증가 위의 # 1과 같이 샤드 데이터와 공통 데이터를 업데이트해야하는 상황이 발생하면 데이터가 별도의 데이터베이스에 있으므로 여러 번의 왕복을 수행하여이 작업을 수행합니다. 여기에 약간의 네트워크 대기 시간이 있지만 위의 3만큼이 문제에 대해 걱정하지 않습니다.

디자인 # 2에 대한 우려

디자인 # 2에서 각 샤드는 모든 공통 / 유니버설 데이터의 자체 인스턴스를 가져옵니다. 이는 공통 데이터에 참여하거나 업데이트하는 모든 코드가 오늘날처럼 계속 작동 / 실행됨을 의미합니다. 개발 팀에서 필요한 레코딩 / 재기록은 거의 없습니다. 그러나이 디자인은 병합 복제에 전적으로 의존하여 모든 샤드에서 데이터를 동기화합니다. dbas는 매우 숙련되어 있으며 병합 복제가이를 처리하지 못할 수 있으며 병합 복제가 실패해야하는 경우,이 실패로부터의 복구가 크지 않으며 우리에게 매우 부정적인 영향을 줄 수 있다는 점에 매우 우려하고 있습니다.

누군가 디자인 옵션 # 2를 사용했는지 알고 싶습니다. 또한 내가 보지 못한 3 또는 4 디자인 옵션을 간과하는지 알고 싶습니다.

미리 감사드립니다.


10
이 경우 "매우 큰 규모의 엔터프라이즈 데이터베이스"와 "이미 매우 높은 수준으로 확장 된 하드웨어"란 무엇입니까? 10에서 10 번, 샤딩은 해결책이 아니므로 해결하려는 문제가 무엇인지 궁금합니다.
Mark Storey-Smith

5
진지하게, 당신은 당신의 웹 서버가 당신의 SQL 박스를 "해머"라고 말합니다. 읽는 비율은 무엇입니까? 현재 데이터의 실제 상태에 따라 성능, 비용 또는 복잡성에 대한 절충을 통해 샤딩없이 읽기를 확장하는 방법에는 여러 가지가 있습니다. 물론 유휴 상태의 데이터가 얼마나 빨리 필요한지에 따라 다시 쓰기를 대기시키는 방법이 있습니다.
Aaron Bertrand

3
이 특정 진술은 "하드웨어는 이미 매우 높은 수준으로 확장되었습니다." 이 하드웨어 확장에 무엇이 들어갔습니까?
swasheck

2
64 개의 논리 프로세서가 있고 CPU에 병목 현상이 있습니까? CPU를 정확히 구동하고 다시 컴파일하는 것은 무엇입니까? 당신은 알고 있습니까?
Aaron Bertrand

1
샤딩이 끝나면 바지를 확인하십시오.
swasheck

답변:


5

귀하의 질문은 이것에 초점을 맞췄습니다.

그러나 내 질문은 공통적이며 보편적 인 비 샤드 데이터에 관한 것입니다. 이와 같은 데이터의 예로는 인벤토리 테이블 또는 직원 테이블, 사용자 테이블 등이 있습니다.

샤딩을 수행 할 때 모든 샤드에 표시해야하는 데이터가 있으면 몇 가지 속성으로 해당 데이터를 분류해야합니다.

자주 바뀌나요? 귀하의 예에서는 재고, 직원 및 사용자를 나열했습니다. 일반적으로 인벤토리는 매우 빠르게 변경되지만 직원 레코드는 정기적으로 만 변경됩니다 (예 : 하루에 수백 건의 업데이트).

각 샤드가 얼마나 지연 될 수 있습니까?인벤토리가 지속적으로 변경 될 수 있지만 일반적으로 이와 같은 테이블에서 많은 지연 (분 또는 몇 시간)을 허용 할 수 있습니다. 재입고 할 수없는 수량이 매우 한정된 고유 상품을 판매하는 경우 (원본 아트 워크 생각) 해당 데이터를 전혀 분할하지 않으며 원래 데이터베이스 만 쿼리합니다. 그러나 대부분의 온라인 상점에서는 매일 모든 품목을 판매하지 않으며 어쨌든 빨리 물건을 재입고 할 수 있으므로 실제로는 밀리 초 단위의 재고가 필요하지 않습니다. 실제로, 대부분의 경우 0 또는 1 인 In-Stock 플래그 만 필요하며 중앙 프로세스는 해당 플래그를 업데이트합니다. 그렇게하면 아이템의 모든 업 / 다운 범프를 모든 샤드에 밀어 넣을 필요가 없습니다. 반면 직원 또는 사용자 데이터는

샤딩 된 테이블에서 샤딩되지 않은 테이블로 조인 하시겠습니까? 이상적으로는 여기에 대한 대답은 '아니오'입니다. 데이터를 얻기 위해 두 개의 별도 쿼리를 한 다음 앱 측에서 조인해야합니다. 이것은 앱 관점에서 훨씬 어려워 지지만 각 소스에서 최신 데이터를 얻을 수있는 기능을 제공합니다.

이 원본 데이터입니까, 아니면 복사 되었습니까?이 질문을 생각할 수있는 또 다른 방법은 무엇을 백업해야하며 얼마나 자주해야합니까? 일반적으로 대량의 샤딩 환경에서는 백업이 최대한 빠르고 작기를 원합니다. (결국 각 노드를 보호해야하며 모든 샤드가 같은 시점에 DR로 페일 오버되기를 원합니다. 다른 샤드보다 최신 데이터가있는 샤드가 없어야합니다.) 이는 샤드 된 데이터와 샤드 된 데이터는 동일한 서버에 있더라도 완전히 별도의 데이터베이스에 있어야합니다. 샤드 (원래) 데이터의 지속적인 트랜잭션 로그 백업이 필요할 수 있지만 샤드되지 않은 데이터는 전혀 백업하지 않아도됩니다. 모든 샤드에 백업하지 않고 직원 또는 사용자 테이블을 단일 진실 소스에서 새로 고치는 것이 더 쉬울 것입니다. 그래도 모든 데이터가 단일 데이터베이스에 있다면

이제 귀하의 우려에 대해 :

"거래 문제 ... 더 이상 쉽게 할 수 없습니다." 옳은. 샤드 시나리오에서는 트랜잭션 개념을 창 밖으로 내 보냅니다. 샤드 데이터의 경우 클러스터 인스턴스 장애 조치 또는 재시작으로 인해 샤드가 온라인 및 온라인 상태가되고 다른 샤드가 일시적으로 다운 될 수 있습니다. 언제든지 시스템의 일부에 대한 장애를 계획해야합니다.

"교차 데이터베이스 참조 무결성을 수행 할 수 없습니다." 옳은. 단일 서버를 여러 서버로 분할하면 빅 보이 팬츠를 착용하고 특정 시점 백업, 테이블 간의 관계 및 여러 소스. 지금 당신과 당신의 코드에 있습니다.

"공통 데이터를 새로운 범용 데이터베이스에 쓰지만 샤드에서 공통 데이터를 읽을 수 있도록 시스템의 넓은 영역을 레코딩합니다." 여기에서도 정정하십시오. 쉬운 버튼은 없지만 일단 앱에 내장하면 미친 것처럼 확장 할 수 있습니다. 이 작업을 수행하는 가장 쉬운 방법 은 앱의 연결을 reads나누는 것 입니다.

"데이터베이스 트립 증가." -예, 데이터를 여러 서버로 나누면 앱이 네트워크에 더 많이 도달해야합니다. 핵심은 캐싱을 구현하여이 데이터 중 일부를보다 저렴한 처리량의 잠금없는 시스템에 저장할 수 있도록하는 것입니다. 가장 빠른 쿼리는 결코 만들 수없는 쿼리입니다.

또한 개별 샤드의 성능 조정, 샤드마다 다른 백업 / 복구 전략 및 스키마 배포 문제와 같은 다중 테넌트 데이터베이스를 분할하는 데 더 많은 장단점을 제시했습니다.


0

높은 수준에서 데이터를 분할 (또는 가로 분할)하는 일반적인 방법은 트랜잭션 테이블을 분할하고 마스터 수준 테이블을 복제하는 것입니다. 대부분의 기술 솔루션과 마찬가지로, 이것은 물론 일련의 문제를 해결하고 완전히 새로운 문제를 만들어냅니다. 그러나 우리 모두 지금까지 익숙하지 않습니까? ;-)

그러나 SQLServer가 가장 적합한 솔루션인지 여부는 의문입니다. 워크로드가 OLTP와 비슷하거나 DW / BI와 유사합니까?

건배, 데이브 시스 크


-2

가능한 세 번째 옵션. 블랙 박스 샤딩 대신 관계형 샤딩을 사용하면 전체 데이터베이스를 샤딩하고 배포 할 수 있어야합니다. 데이터베이스는 기존의 관계형 데이터 모델을 기반으로하기 때문에 어떤 서버에 어떤 데이터가 저장되어 있는지와 그 위치를 알고 있으므로 모든 데이터를 '공통 / 유니버설'로 간주 할 수 있습니다. 전체 샤딩 프로세스를보다 쉽게 ​​수행 할 수 있도록 dbShards를 확인하십시오.


3
이 답변은 관계형 샤딩, 블랙 박스 샤딩, 수행 방식, 왜 다른 것보다 나은지, 바람직하게는 고용주가 dbShards라는 입장에 대한 설명 없이는 의미가 없습니다.
예레미야 페 쉬카
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.