10 억 행 처리 및 계산을위한 데이터베이스 설계


10

약 5000 pr의 속도로 실시간 GPS 데이터를 수신합니다. 분 (4 개의 TCP 서버에서). 각 서버는 단일 연결을 사용하여 데이터를 삽입하고 삽입물 사이에 데이터를 버퍼링합니다. 15 분 정도마다 서비스는이 데이터를 가져 와서 트립으로 처리합니다. 여행이 생성되면 사용자가지도에서 경로를보고자하는 경우에만 실제 GPS 데이터는 그리 중요하지 않습니다.

문제는 데이터베이스가 삽입되는 데이터 속도를 유지하기 위해 고심하고 있다는 것입니다. 때때로로드가 증가하면 인서트 시간이 갑자기 크게 (> 30 초) 증가하여 더 많은 데이터를 버퍼링 할 수있어 인서트가 커지고 인서트 지속 시간이 길어집니다.

현재 디자인에 대한 의견과 성능을 개선하기위한 아이디어, 일부 질문에 대한 답변 및 사람들이 가질 수있는 기타 팁을 알려 드리겠습니다.

현재 디자인

데이터는 현재 일주일을 나타내는 테이블로 분리되며 1 년이 지난 데이터는 보조 데이터베이스에 아카이브됩니다. 전체 내용은 편집 가능한보기로 결합되어 있으며 삽입 및 읽기에 모두 사용됩니다.

테이블 디자인

  • ID (PK, 고유 식별자)
  • DeviceId (FK, int)
  • PersonId (FK, int)
  • VehicleId (FK, int)
  • 토큰 ID (FK, int)
  • UtcTime (PK, datetime2 (3))
  • 위도 (부동)
  • 경도 (float)
  • 속도 (smallint)
  • 제목 (smallint)
  • 위성 (tinyint)
  • IOData (이진 (100))
  • IgnitionState (tinyint)
  • UserInput (tinyint)
  • CreateTimeUtc (datetime2 (3))

지수

  • DeviceId_CreateTimeUtc_Desc
  • DeviceId_UtcTime_Desc (클러스터)
  • PersonId_UtcTime_Desc
  • TokenId_UtcTime_Desc
  • VehicleId_UtcTime_Desc

매주 현재 색인을 포함하여 약 10GB를 차지하며 현재 주 데이터베이스에 약 300GB의 데이터가 있습니다.

기본 데이터베이스의 데이터 테이블에는 파일이 1 인 자체 파일 그룹이 있지만 기본 데이터베이스의 다른 모든 테이블과 동일한 디스크에 있습니다. 보조 데이터베이스는 다른 디스크에 있지만 동일한 시스템에 있습니다.

새 테이블 파티션 (주)을 사용할 때 매주 인덱스 재 구축 작업을 실행하고 있다고 생각합니다. 축소가 수행되지 않습니다.

머신은 메모리가 12GB 인 8 코어 HP이며 주 데이터베이스를 보유한 디스크는 RAID 10을 실행합니다.

아이디어

  • 기본 데이터베이스에 저장된 데이터의 양을 최대 1 개월로 제한하십시오. 최소한 백업 / 복원을 위해 데이터베이스를보다 관리하기 쉽게 만들지 만, 이렇게하면 성능이 향상 될 것으로 기대할 수 있습니까?
  • 현재 데이터에 대해 파일 그룹에 2 개의 파일을 작성하여 2 개의 다른 물리적 파티션에 분배
  • 현재 데이터를 보유한 마스터-슬레이브 데이터베이스를 생성하여 다른 데이터베이스에서 삽입 및 읽기가 수행됩니다.
  • SSD 디스크에 현재 데이터의 파일을 넣습니다 (미러링은 SSD 디스크와 성능 차이가 있습니까?)

더 많은 정보가 필요하면 알려주십시오. 성능에 영향을 미치는 끔찍한 요소가 많으며 성능을 조정하는 여러 가지 방법이 있습니다.


의견은 긴 토론을위한 것이 아닙니다. 이 대화는 채팅 으로 이동 되었습니다 .
Paul White 9

답변:


8

분당 5000 개의 인서트는 초당 약 83 개의 인서트입니다. 초당 400 개의 실제 행이 삽입 된 5 개의 인덱스가 있습니다. 워크로드가 메모리에 있으면 가장 작은 서버에도 문제가되지 않습니다. 이것이 내가 생각할 수있는 가장 비효율적 인 방법을 사용하여 행 단위로 삽입 된 경우에도 마찬가지입니다. 초당 83 개의 간단한 쿼리는 CPU 관점에서 흥미롭지 않습니다.

아마 당신은 디스크 바운드입니다. 대기 통계 또는를 보면이를 확인할 수 있습니다 STATISTICS IO.

버퍼 풀에 모든 공간이 없기 때문에 쿼리가 다른 페이지를 많이 만질 수 있습니다. 이로 인해 빈번한 페이지 읽기와 임의의 디스크 쓰기가 발생할 수 있습니다.

점점 증가하는 키로 인해 실제로 물리적으로 만 삽입되는 테이블을 상상해보십시오. 작업 세트는 마지막 페이지 인 한 페이지입니다. 이것은 지연 IO 또는 검사 점 프로세스가 테이블의 "끝"을 디스크에 기록 할 때 순차적 IO를 생성합니다.

무작위로 삽입 된 삽입물이있는 테이블을 상상해보십시오 (기본 예 : guid 키). 여기서는 모든 페이지가 작업 세트입니다. 각 삽입마다 임의의 페이지가 터치되기 때문입니다. IO는 무작위입니다. 작업 세트와 관련하여 최악의 경우입니다.

당신은 중간에 있습니다. 색인은 구조 (SomeValue, SequentialDateTime)입니다. 제 1 성분은 제 2 성분에 의해 제공된 순차를 부분적으로 무작위 화한다. SomeValue인덱스에 무작위로 삽입 된 삽입 점이 많을 수 있도록 " "에 대해 가능한 값이 약간 있다고 생각 합니다.

데이터가 일주일에 10GB 테이블로 분할되어 있다고합니다. 작업 세트가 10GB로 제한되어 있기 때문에 좋은 시작점이 될 것입니다 (읽을 수있는 모든 것을 무시하십시오). 그러나 12GB의 서버 메모리를 사용하면 모든 관련 페이지가 메모리에 남아있을 수 없습니다.

매주 "파티션"의 크기를 줄이거 나 서버 메모리를 조금 늘릴 ​​수 있다면 아마 괜찮을 것입니다.

나는 주 초에 인서트가 끝보다 빠를 것으로 기대합니다. 특정 데이터 크기로 벤치 마크를 실행하고 성능 탱크가 나타날 때까지 서버 메모리를 점차 줄임으로써 개발 서버에서이 이론을 테스트 할 수 있습니다.

이제 모든 읽기 및 쓰기가 메모리에 적합하더라도 임의의 더티 페이지 플러시 IO가있을 수 있습니다. 이를 제거하는 유일한 방법은 인덱스에서 같은 위치에 쓰는 것입니다. 인덱스를 변환 할 수 있다면 많은 도움이 될 순차 키를 사용할 수 있습니다.

빠른 솔루션으로 클라이언트와 기본 테이블 사이에 버퍼링 계층을 추가합니다. 스테이징 테이블에 15 분의 쓰기를 누적하여 주기적으로 플러시 할 수 있습니다. 이는로드 스파이크를 제거하고보다 효율적인 계획을 사용하여 큰 테이블에 씁니다.


1
@usr 매우 포괄적이고 잘 설명 된 답변에 감사드립니다! 우리는 실제로 얼마나 많은 영향을 줄지 모르는 서버 메모리 증가에 대해 논의했습니다. 그러나 지금 우리는 그렇게하는 매우 매력적인 이유가 있습니다. 약 10000 개의 기기 ID 준비 테이블과 관련하여 인덱스가없는 테이블을 제안한 다음 X 분마다 기본 테이블에 삽입하는 작업입니까?
sondergard

@usr 등록 클러스터 된 인덱스를 순차적으로 변환하기위한 제안은 auto-inc를 추가 할 수 있습니다. ID 열 (정수)을 지정하고 순차 유지를 위해 클러스터 된 인덱스를이 열로 변경 하시겠습니까? 테이블 전체에서 고유하지는 않지만 기본 키가있는 한 괜찮습니다.
sondergard

1
준비 테이블이 작고 쿼리를 계속 사용할 수 있으면 인덱스를 생성 할 필요가 없습니다. 그러나 당신은 할 수 있습니다.; 한 가지 전략은 CI를 ID 열에 작성하는 것입니다 (말씀하신대로). CI가 크고 다른 인덱스가 작은 지 궁금합니다. CI 쓰기는 이제 순차적이므로 문제에 훨씬 덜 기여합니다. 의미있는 크기 차이가있는 경우이 전략이 가장 효과적입니다.; 또 다른 아이디어는 하루에 하나의 테이블을 갖는 것입니다. 매월 병합 될 수도 있습니다.
usr

CI에 대한 ID 열을 생성하는 방법을 살펴 봤지만 불행히도 분할 뷰에서는 불가능합니다 (ID 열이 허용되지 않고 기본값이 없으며 모든 열이 삽입에 포함되어야 함). 이 컨설턴트에 의해 추천되었다하더라도 아마으로 파티션 된 뷰는 잘못 선택 디자인했다
sondergard

2
진지하게, 같은 문제에 직면 한 사람이라면, 많은 쓰기와 약간의 읽기만 있다면 끝에 추가하고 인덱싱을 지연시키고 싶을 것입니다. 반면에 빠른 읽기를 원하고 삽입하는 데 시간이 걸리지 않으면 클러스터형 인덱스가 필요합니다.
tiktak
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.