[sql-server] 수십억 개의 행을위한 최고의 데이터 저장소

수십억 개의 레코드 (1 년에 약 30 억 / 월)에 대한 작은 데이터 비트 (약 50-75 바이트)를 저장할 수 있어야합니다.

유일한 요구 사항은 GUID가 동일한 모든 레코드에 대한 빠른 삽입 및 빠른 조회와 .net에서 데이터 저장소에 액세스 할 수있는 기능입니다.

저는 SQL 서버 전문가이고 SQL Server 가이 작업을 수행 할 수 있다고 생각 하지만 BigTable, CouchDB 및 기타 nosql 솔루션에 대한 모든 논의를 통해 점점 더 전통적인 RDBS의 대안이 될 수 있습니다. 분산 쿼리 및 확장. 나는 cassandra를 시도했고 .net 라이브러리는 현재 컴파일되지 않거나 모두 변경 될 수 있습니다 (cassandra 자체와 함께).

사용 가능한 많은 nosql 데이터 저장소를 살펴 보았지만 강력한 프로덕션 준비 플랫폼으로서의 요구 사항을 충족하는 저장소를 찾을 수 없습니다.

.net에서 액세스 할 수 있도록 360 억 개의 작고 평평한 레코드를 저장해야한다면 무엇을 선택하고 그 이유는 무엇입니까?



답변

~ 3.5TB의 데이터를 저장하고 약 1K / sec 24×7 삽입 및 지정되지 않은 속도로 쿼리하는 것도 SQL Server에서 가능하지만 더 많은 질문이 있습니다.

  • 이에 대한 가용성 요구 사항은 무엇입니까? 99.999 % 가동 시간 또는 95 % 충분합니까?
  • 어떤 신뢰성 요구 사항이 있습니까? 삽입물을 놓치면 백만 달러의 비용이 듭니까?
  • 어떤 복구 가능성 요구 사항이 있습니까? 하루의 데이터를 잃어버린다면 상관 없나요?
  • 어떤 일관성 요구 사항이 있습니까? 쓰기가 다음 읽기에서 표시되도록 보장해야합니까?

내가 강조한 이러한 모든 요구 사항이 필요한 경우 제안하는로드는 어떤 기믹 (샤딩, 파티셔닝 등)을 시도하더라도 관계형 시스템, 모든 시스템에 대한 하드웨어 및 라이센스에 수백만 달러의 비용이들 것입니다. nosql 시스템은 정의상 이러한 모든 요구 사항을 충족하지 못합니다 .

따라서 이미 이러한 요구 사항 중 일부를 완화했습니다. Visual Guide to NoSQL Systems 에서 ‘pick 2 of 3’패러다임을 기반으로 nosql 제품을 비교하는 멋진 시각적 가이드가 있습니다 .

nosql 비교

OP 코멘트 업데이트 후

SQL Server를 사용하면 간단하게 구현할 수 있습니다.

  • 단일 테이블 클러스터 (GUID, 시간) 키. 예, 조각화 될 예정 이지만 조각화는 미리 읽기에 영향을 미치며 중요한 범위 스캔에만 미리 읽기가 필요합니다. 특정 GUID 및 날짜 범위에 대해서만 쿼리하므로 조각화는 그다지 중요하지 않습니다. 예,은 와이드 키이므로 리프가 아닌 페이지는 키 밀도가 낮습니다. 예, 채우기 비율이 좋지 않습니다. 예, 페이지 분할이 발생할 수 있습니다. 이러한 문제에도 불구하고 요구 사항을 고려할 때 여전히 최상의 클러스터 키 선택입니다.
  • 자동 슬라이딩 창을 통해 만료 된 레코드를 효율적으로 삭제할 수 있도록 테이블을 시간별로 분할합니다 . GUID 클러스터링으로 인해 발생하는 빈약 한 채우기 비율 및 조각화를 제거하기 위해 지난달의 온라인 인덱스 파티션 재 구축으로이를 확장합니다.
  • 페이지 압축을 활성화합니다. GUID별로 클러스터 된 키 그룹이 먼저이기 때문에 GUID의 모든 레코드가 서로 옆에 있으므로 페이지 압축 이 사전 압축을 배포 할 수있는 좋은 기회를 제공 합니다 .
  • 로그 파일을위한 빠른 IO 경로가 필요합니다. 로그가 초당 1K 삽입을 유지하기위한 짧은 지연 시간이 아닌 높은 처리량에 관심이 있으므로 스트리핑 이 필수입니다.

분할 및 페이지 압축에는 각각 Enterprise Edition SQL Server가 필요하며 Standard Edition에서는 작동하지 않으며 둘 다 요구 사항을 충족하는 데 매우 중요합니다.

참고로 레코드가 프런트 엔드 웹 서버 팜에서 가져온 경우 각 웹 서버에 Express를 배치하고 백 엔드에 INSERT 대신 SEND로컬 연결 / 트랜잭션을 사용하여 백 엔드에 정보를 입력합니다. 웹 서버와 같은 위치에있는 Express에서. 이것은 솔루션에 훨씬 더 나은 가용성 스토리를 제공합니다.

그래서 이것이 SQL Server에서 수행하는 방법입니다. 좋은 소식은 직면하게 될 문제가 잘 이해되고 해결책이 알려져 있다는 것입니다. 그렇다고 Cassandra, BigTable 또는 Dynamo로 달성 할 수있는 것보다 이것이 반드시 더 나은 것은 아닙니다. 나는 SQL이 아닌 일에 대해 더 많은 지식을 가진 사람에게 그들의 주장을 주장하도록 할 것입니다.

프로그래밍 모델, .Net 지원 등에 대해서는 언급 한 적이 없습니다. 솔직히 대규모 배포에는 관련이 없다고 생각합니다. 그들은 개발 프로세스에서 큰 차이를 만들지 만, 일단 배포되면 ORM 오버 헤드가 성능을 저하시키는 경우 개발 속도는 중요하지 않습니다. 🙂


답변

대중적인 믿음과는 달리 NoSQL은 성능이나 확장성에 관한 것이 아닙니다. 이는 주로 소위 Object-Relational 임피던스 불일치를 최소화하는 것이지만 수평 확장 성 대 RDBMS 의보다 일반적인 수직 확장 성에 관한 것이기도 합니다.

빠른 삽입 및 빠른 조회의 간단한 요구 사항에 대해서는 거의 모든 데이터베이스 제품이 가능합니다. 관계형 데이터 또는 조인을 추가하거나 적용해야하는 복잡한 트랜잭션 논리 또는 제약 조건이있는 경우 관계형 데이터베이스가 필요합니다. NoSQL 제품은 비교할 수 없습니다.

스키마없는 데이터가 필요한 경우 MongoDB 또는 CouchDB와 같은 문서 지향 데이터베이스를 사용하는 것이 좋습니다. 느슨한 스키마가 이들의 주요 매력입니다. 저는 개인적으로 MongoDB를 좋아하고 몇 가지 맞춤형보고 시스템에서 사용합니다. 데이터 요구 사항이 지속적으로 변경 될 때 매우 유용합니다.

다른 주요 NoSQL 옵션은 BigTable 또는 Cassandra와 같은 분산 키-값 저장소입니다. 이는 상용 하드웨어를 실행하는 많은 컴퓨터에서 데이터베이스를 확장하려는 경우 특히 유용합니다. 그들은 분명히 서버에서도 잘 작동하지만 SQL Server 또는 Oracle 또는 수직 확장을 위해 설계된 기타 데이터베이스뿐만 아니라 고급 하드웨어를 활용하지 않으며 분명히 관계형이 아니며 정규화를 시행하는 데 좋지 않습니다. 또는 제약. 또한 아시다시피 .NET 지원은 기껏해야 불안정한 경향이 있습니다.

모든 관계형 데이터베이스 제품은 제한된 종류의 파티셔닝을 지원합니다. BigTable이나 다른 DKVS 시스템만큼 유연하지 않고 수백 대의 서버에 쉽게 분할 되지는 않지만 실제로 원하는 것처럼 들리지 않습니다. 데이터를 적절하게 인덱싱하고 정규화하고 강력한 하드웨어 (특히 여유가있는 경우 SSD)에서 데이터베이스를 실행하고 다음과 같은 경우 2 개 또는 3 개 또는 5 개의 물리적 디스크로 분할하는 한 수십억 개의 레코드 수를 처리하는 데 매우 능숙합니다. 필요한.

위의 기준을 충족하고 기업 환경에서 일하고 있고 적절한 하드웨어 및 데이터베이스 최적화에 지출 할 돈이 있다면 지금은 SQL Server를 고수 할 것입니다. 돈이 많이 들고 저가형 Amazon EC2 클라우드 컴퓨팅 하드웨어에서이를 실행해야하는 경우 대신 Cassandra 또는 Voldemort를 선택하는 것이 좋습니다 (.NET으로 작업 할 수 있다고 가정).


답변

수십억 행 집합 크기로 작업하는 사람은 거의 없으며 대부분의 경우 스택 오버플로에서 이와 같은 요청을 볼 때 데이터는보고되는 크기에 가까운 곳에 없습니다.

매월 360 억, 30 억, 이는 대략 하루 1 억, 시간당 416 만, 분당 ~ 70k 행, 시스템에 초당 1.1k 행이 12 개월 동안 지속적으로 들어오는데, 이는 다운 타임이 없다고 가정합니다.

그 수치는 긴 마진으로 불가능하지 않습니다. 저는 더 큰 시스템을 수행했지만 실제로 의미하는 수량인지 다시 확인하고 싶습니다. 실제로이 수량을 가진 앱은 거의 없습니다.

저장 / 검색과 관련하여 언급하지 않은 매우 중요한 측면은 오래된 데이터의 노화입니다. 삭제는 무료가 아닙니다.

일반적인 기술은 파티셔닝이지만 GUID 기반의 조회 / 검색은 전체 12 개월 동안 일치하는 모든 값을 가져와야한다고 가정하면 성능이 저하됩니다. GUID 열에 클러스터형 인덱스를 배치하면 읽기 / 쓰기를 위해 관련 데이터가 클러스터링되지만 이러한 양과 삽입 속도에서는 조각화가 너무 높아 지원할 수 없으며 바닥에 떨어집니다.

또한 이것이 OLTP 유형 응답 속도를 가진 심각한 응용 프로그램 인 경우, 대략 2.7TB의 데이터 인덱싱 오버 헤드가 거의 없다고 가정 할 때 대략적인 추측에 의한 경우 매우 적절한 하드웨어 예산이 필요하다고 제안합니다.

SQL Server 진영에서 살펴볼 수있는 유일한 것은 대규모 데이터 마트에 대해 고속을 제공하기 위해 데이터를 분할하고 이에 대해 병렬 쿼리를 실행하도록 설계된 새로운 병렬 데이터웨어 하우스 에디션 (madison)입니다.


답변

“저는 수십억 개의 레코드 (1 년에 약 30 억 / 월)에 대해 작은 데이터 비트 (약 50-75 바이트)를 저장할 수 있어야합니다.

유일한 요구 사항은 GUID가 동일한 모든 레코드에 대한 빠른 삽입 및 빠른 조회와 .net에서 데이터 저장소에 액세스 할 수있는 기능입니다. “

2009 년 초에이 작업을 수행했기 때문에 SQL Server에서 이것이 가능하다는 것을 경험을 통해 말할 수 있습니다. 그리고 지금까지도 여전히 작동하며 매우 빠릅니다.

테이블은 256 개의 파티션으로 분할되었습니다.이 버전은 2005 SQL 버전이라는 점을 명심하십시오. 우리는 정확히 말씀하신대로 GUID로 정보를 저장하고 GUID로 빠르게 검색했습니다.

내가 떠났을 때 우리는 약 2-3 억 개의 레코드를 가지고 있었고 데이터 보존 정책이 막 인스턴스화 되려고했지만 데이터 검색은 여전히 ​​꽤 좋았습니다 (UI를 통하는 경우 1-2 초, RDBMS의 경우 그 이하).

짧게 말하면 GUID 문자열에서 8 번째 문자 (즉, 중간 어딘가)를 가져와 SHA1이 해시하고 작은 정수 (0-255)로 캐스팅하고 적절한 파티션에 저장하고 가져올 때 동일한 함수 호출을 사용했습니다. 다시 데이터.

더 많은 정보가 필요하면 나에게 ping을 …


답변

다음 문서에서는 Microsoft SQL에서 160 억 개의 행 테이블을 가져오고 사용하는 방법에 대해 설명합니다 .
http://sqlmag.com/t-sql/adventures-big-data-how-import-16-billion-rows-single-table .

기사에서 :

내 경험에서 얻은 몇 가지 팁은 다음과 같습니다.

  • 정의 된 클러스터형 인덱스가있는 테이블에 데이터가 많을수록 정렬되지 않은 레코드를 테이블로 가져 오는 속도가 느려집니다. 어느 시점에서 실용적 이기에는 너무 느려집니다.
  • 테이블을 가능한 가장 작은 파일로 내보내려면 기본 형식으로 만드십시오. 이것은 문자 데이터보다 이진 필드에서 더 간결하게 표현되기 때문에 대부분 숫자 열을 포함하는 테이블에서 가장 잘 작동합니다. 모든 데이터가 영숫자이면 기본 형식으로 내보내는 것으로 많은 것을 얻을 수 없습니다. 숫자 필드에 널을 허용하지 않으면 데이터를 더 압축 할 수 있습니다. 필드가 널 입력 가능하도록 허용하는 경우 필드의 이진 표현에는 뒤에 오는 데이터 바이트 수를 나타내는 1 바이트 접 두부가 포함됩니다.
  • BCP 카운터 변수가 4 바이트 정수이므로 2,147,483,647 개 이상의 레코드에 대해 BCP를 사용할 수 없습니다. MSDN이나 인터넷에서 이에 대한 참조를 찾을 수 없었습니다. 테이블
    이 2,147,483,647 개 이상의 레코드 로 구성된 경우 청크로 내보내
    거나 고유 한 내보내기 루틴을 작성해야합니다.
  • 미리 채워진 테이블에 클러스터형 인덱스를 정의하면 많은 디스크 공간이 필요합니다. 내 테스트에서 내 로그는
    완료되기 전에 원래 테이블 크기의 10 배로 폭발했습니다 .
  • BULK INSERT 문을 사용하여 많은 레코드를 가져올 때 BATCHSIZE 매개 변수를 포함하고
    한 번에 커밋 할 레코드 수를 지정합니다 . 이 매개 변수를 포함하지 않으면
    전체 파일을 단일 트랜잭션으로 가져 오므로
    많은 로그 공간 이 필요합니다.
  • 클러스터형 인덱스가있는 테이블로 데이터를 가져 오는 가장 빠른 방법은 먼저 데이터를 사전 정렬하는 것입니다. 그런 다음
    ORDER 매개 변수와 함께 BULK INSERT 문을 사용하여 가져올 수 있습니다 .


답변

간과 된 것 같은 특이한 사실이 있습니다.

기본적으로 하루에 3 천만 행을 삽입 한 후 동일한 GUID (아마도 20 행)로 모든 행을 가져 와서 모두 다시 가져올 수 있는지 확인해야합니다.

20 개의 열만 필요하면 GUID의 클러스터되지 않은 인덱스가 제대로 작동합니다. 파티션간에 데이터 분산을 위해 다른 열에 클러스터링 할 수 있습니다.

데이터 삽입에 대해 질문이 있습니다. 어떻게 삽입되고 있습니까?

  • 특정 일정 (분당, 시간당 등)에 대한 대량 삽입입니까?
  • 이 데이터는 어떤 소스 (플랫 파일, OLTP 등)에서 가져 오나요?

방정식의 한쪽을 이해하는 데 도움이되도록 이것에 대한 답이 필요하다고 생각합니다.


답변

Amazon Redshift는 훌륭한 서비스입니다. 질문이 원래 2010 년에 게시되었을 때는 사용할 수 없었지만 이제는 2017 년에 주요 플레이어입니다. Postgres에서 분기 된 열 기반 데이터베이스이므로 표준 SQL 및 Postgres 커넥터 라이브러리가 함께 작동합니다.

보고 목적, 특히 집계에 가장 적합합니다. 단일 테이블의 데이터는 Amazon 클라우드의 여러 서버에 저장되고 정의 된 테이블 distkey를 통해 배포되므로 분산 된 CPU 성능에 의존합니다.

따라서 SELECT 및 특히 집계 된 SELECT는 매우 빠릅니다. 대용량 데이터로드는 Amazon S3 csv 파일에서 COPY 명령을 사용하여 수행하는 것이 좋습니다. 단점은 DELETE 및 UPDATE가 평소보다 느리다는 것입니다. 그렇기 때문에 Redshift는 주로 초국적 데이터베이스가 아니라 데이터웨어 하우스 플랫폼에 더 가깝습니다.