>  기사  >  운영 및 유지보수  >  MongoDB 디스크 IO 문제에 대한 솔루션

MongoDB 디스크 IO 문제에 대한 솔루션

巴扎黑
巴扎黑원래의
2017-09-04 14:05:441455검색

약간의 헤드라인이지만 다음 세 가지 팁은 실제로 런던 MongoDB 사용자 그룹의 Conversocial 부사장인 Colin Howe가 공유한 내용에서 나온 것입니다.

응용 프로그램: 다음 사항은 보편적으로 적용 가능하지 않습니다. 사용 가능 여부는 사용자의 응용 프로그램 시나리오 및 데이터 특성에 따라 다릅니다.

1. 결합된 대용량 문서 사용

우리는 MongoDB가 문서 데이터베이스이고 각 레코드가 JSON 형식의 문서라는 것을 알고 있습니다. 예를 들어 다음 예와 같이 매일 하나의 통계 데이터가 생성됩니다.

{ metric: "content_count", client: 5, value: 51, date: ISODate("2012-04-01 13:00" ) }

{ metric: "content_count", client: 5, value: 49, date: ISODate("2012-04-02 13:00") }

그리고 결합된 대용량 문서를 사용하는 경우 하나를 결합할 수 있습니다. 이런 방식으로 월별 데이터가 하나의 레코드에 저장됩니다:

{ metric: "content_count", client: 5, Month: "2012-04", 1: 51, 2: 49, ... }

가 저장됩니다 위의 두 가지 방법으로 총 약 7GB의 데이터가 미리 저장되며(머신에는 1.7GB의 메모리만 있음) 테스트에서는 1년 동안의 정보를 읽습니다. 둘 사이의 읽기 성능 차이는 명백합니다.

첫 번째 : 1.6초

두 번째 : 0.3초

그럼 무엇이 문제일까요?

실제 이유는 통합 스토리지가 데이터를 읽을 때 더 적은 수의 문서를 읽을 수 있기 때문입니다. 문서를 메모리에 완전히 저장할 수 없는 경우 비용은 주로 디스크 탐색에 소요되며, 1년치의 데이터를 얻을 때 첫 번째 저장 방법에서는 읽어야 할 문서가 더 많아지기 때문에 디스크 탐색 횟수도 많아집니다. . 그래서 더 느려요.

실제로 MongoDB로 잘 알려진 Foursquare에서는 읽기 성능을 향상시키기 위해 이 방법을 많이 사용하고 있습니다. 이것을 보세요

2 특별한 인덱스 구조를 사용하세요

MongoDB는 기존 데이터베이스와 마찬가지로 B-트리를 인덱스 데이터 구조로 사용한다는 것을 알고 있습니다. 트리형 인덱스의 경우, 핫 데이터를 저장하는 데 사용되는 인덱스의 저장 공간이 집중될수록 인덱스에서 낭비되는 메모리가 줄어듭니다. 따라서 다음 두 가지 인덱스 구조를 비교합니다:

db.metrics.ensureIndex({ metric: 1, client: 1, date: 1})

db.metrics.ensureIndex({ date: 1, metric: 1 , client: 1 })

이 두 가지 다른 구조를 사용하면 삽입 성능의 차이도 분명합니다.

첫 번째 구조를 사용하면 데이터 용량이 2천만개 미만일 때 기본적으로 삽입 속도는 10k/s로 유지될 수 있으며, 데이터 용량이 다시 증가하면 삽입 속도는 2.5k/s로 서서히 감소합니다. 데이터 양이 더 늘어나면 성능이 저하될 수 있습니다.

두 번째 구조를 사용하면 삽입 속도는 기본적으로 10k/s로 안정적일 수 있습니다.

그 이유는 두 번째 구조가 날짜 필드를 인덱스에 먼저 넣기 때문에 인덱스를 구축할 때 새로운 데이터가 인덱스를 업데이트할 때 중간에 업데이트되지 않고 인덱스의 꼬리 부분에서만 수정되기 때문입니다. 너무 일찍 삽입된 인덱스는 후속 삽입 작업 중에 수정이 거의 필요하지 않습니다. 첫 번째 경우에는 날짜 필드가 맨 앞에 있지 않기 때문에 인덱스 업데이트가 트리 구조의 중간에서 자주 발생하여 인덱스 구조에 대규모 변경이 자주 발생합니다.

3. 공간 확보

1번 항목과 동일합니다. 이 점 역시 기존 기계식 하드 디스크의 주요 작동 시간이 디스크 검색 작업에 소비된다는 점에 근거합니다.

예를 들어 1번 항목의 예를 들어 데이터를 삽입하면 올해 데이터에 필요한 모든 공간을 한 번에 삽입합니다. 이렇게 하면 1년 중 12개월 동안의 데이터가 하나의 레코드에 순차적으로 저장됩니다. 그런 다음 읽을 때 1년 동안 데이터를 읽으려면 디스크에서 한 번의 순차 읽기 작업만 필요할 수 있습니다. 이전 12개 읽기의 경우 디스크 검색은 한 번만 수행됩니다.

db.metrics.insert([

{ 측정항목: 'content_count', 클라이언트: 3, 날짜: '2012-01', 0: 0, 1: 0, 2: 0, ... }

{ . ................................, 날짜: '2012-02', ... })

{ . ................................., 날짜: '2012-03', ... })

{ ................................., 날짜: '2012-04', ... } )

{ .................................., 날짜: '2012-05', ... })

{ .................................., 날짜: '2012-06', .. . } )

{ .................................., 날짜: '2012-07 ', ... })

{ .................................., 날짜: '2012- 08', .. . })

{ .................................., 날짜: '2012 -09', .. })

{ .................................., 날짜: ' 2012-10', ... })

{ .................................. , 날짜: '2012-11' , ... })

{ .................. ...., 날짜: '2012-12', ... })

])

결과:

예약된 공간 방식을 사용하지 않으면 1년간의 기록을 읽는 데 62ms가 걸립니다

예약된 공간인 경우 space 방식을 사용하면 1년간의 기록을 읽는 데 62ms가 걸립니다. 6.6ms만 걸립니다

위 내용은 MongoDB 디스크 IO 문제에 대한 솔루션의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.