아무리 열심히 밀어도 RAM에 맞지 않는 MongoDB 및 데이터 세트


12

이것은 시스템에 따라 다르지만, 임의의 절벽을지나 실제 문제에 빠질 가능성은 거의 확실합니다. 좋은 RAM 대 디스크 공간 비율을 위해 어떤 종류의 규칙이 있는지 궁금합니다. 우리는 다음 시스템 라운드를 계획하고 있으며 RAM, SSD 및 새로운 노드 각각에 대해 얼마를 선택해야합니다.

그러나 이제 일부 성능 세부 정보가 필요합니다!

단일 프로젝트 실행의 일반적인 워크 플로 중에 MongoDB는 쓰기 비율이 매우 높습니다 (70-80 %). 처리 파이프 라인의 두 번째 단계에 도달하면 처리 전반부에 식별 된 레코드를 중복 제거해야하므로 읽기가 매우 높습니다. 이는 "작업 집합을 RAM으로 유지"하는 워크 플로이며 이러한 가정을 중심으로 설계하고 있습니다.

전체 데이터 세트는 지속적으로 최종 사용자 파생 소스의 임의 쿼리로 적중됩니다. 빈도는 불규칙하지만 크기는 일반적으로 매우 작습니다 (10 개 문서 그룹). 이는 사용자를 대상으로하므로 응답은 "지루한"임계 값 인 3 초 미만이어야합니다. 이 액세스 패턴은 캐시에있을 가능성이 훨씬 적으므로 디스크 적중이 발생할 가능성이 큽니다.

2 차 처리 워크 플로우는 며칠, 몇 주 또는 몇 달이 지난 이전 처리 실행에 대한 높은 읽기이며, 자주 실행되지 않지만 여전히 복잡해야합니다. 이전 처리 실행에서 문서의 최대 100 %에 액세스합니다. 캐시 워밍의 양이 도움이 될 수는 없습니다.

완성 된 문서 크기는 다양하지만 중간 크기는 약 8K입니다.

일반 프로젝트 처리에서 높은 읽기 부분은 읽기 트래픽을 분배하는 데 도움이되는 복제본 사용을 강력하게 제안합니다. 내가 읽고 다른 곳에서 비슷한 규칙이있을 경우 우리가 심각 훨씬 빠른 SSD의 사용을 고려되기 때문에 HD-GB에 1:10 RAM-GB가 좋은 규칙 -의 - 엄지 손가락 느린 디스크는 것을, 나는 알고 싶습니다 빠른 디스크의 경우

캐시에서 모든 것이 실제로 작동하지 않는 방식으로 Mongo를 사용하고 있다는 것을 알고 있습니다. 그래서 그러한 사용에서 살아남을 수있는 시스템을 설계하는 방법을 찾고 있습니다. 전체 데이터 집합 가능성이 반년 이내에 TB의 대부분을하고 성장 유지합니다.


어려운 질문은 잘 제기되었습니다.
gWaldo

IO에 대해 정직하게 튜닝하기 전에 쓰기 잠금 문제가 발생하는 것처럼 들립니다. 쓰기로 DB를 망치면 기본 IO의 속도에 관계없이 쿼리가 중단 될 정도로 쓰기 잠금을 오래 유지할 수 있습니다. Fusion IO와 같은 기능은 쓰기 잠금을 약간 줄일 수 있지만 시간이 조금 걸리므로 실제로 해결되지는 않습니다.
MrKurt

@MrKurt 내가 알아 내려고하는 부분은 개별 복제본 노드를 만들 수있는 방법 외에도 샤드가 필요할 때입니다. 내 잠정 사양에는 PCIe 기반 SSD 카드가 포함되어 있습니다.
sysadmin1138

아, 알았다 처음부터 샤딩을 고려할 수도 있습니다. 단일 서버 샤딩을 많이 수행합니다. 쓰기 잠금을 피하고 전체 코어에 효과적으로 쓰기를 확장 할 수 있습니다. 또한 나중에 서버간에 샤드를 쉽게 이동할 수 있습니다.
MrKurt

답변:


5

이것은 많은 작은 포인트가 될 것입니다. 그러나 슬프게도 귀하의 질문에 대한 단일 답변은 없습니다.

MongoDB를 사용하면 OS 커널이 메모리 관리를 처리 할 수 ​​있습니다. 문제에서 가능한 한 많은 RAM을 버리는 것 외에도 작업 세트를 '능동적으로 관리'하기 위해 수행 할 수있는 작업은 몇 가지뿐입니다.

쓰기를 최적화하기 위해 할 수있는 한 가지는 먼저 해당 레코드를 쿼리하여 (읽기 수행) 작업 메모리에 있도록하는 것입니다. 이렇게하면 프로세스 전체 Global Lock (v2.2에서 DB 별이되어야 함)과 관련된 성능 문제를 피할 수 있습니다.

RAM 대 SSD 비율에 대한 엄격한 규칙은 없지만 SSD의 원시 IOPS를 사용하면 훨씬 낮은 비율로 이동할 수 있다고 생각합니다. 내 머리 꼭대기에서, 1 : 3은 아마도 당신이 가고 싶은 가장 낮은 것입니다. 그러나 비용이 높고 용량이 적 으면 어쨌든 그 비율을 낮춰야 할 것입니다.

'쓰기 대 읽기 단계'와 관련하여, 일단 레코드가 작성된 후에는 거의 업데이트되지 않는다는 것을 올바르게 읽고 있습니까? 이 경우 두 개의 클러스터를 호스팅하는 것이 좋습니다. 정상적인 기입 클러스터, 및 변형되지 않은 "숙성"데이터 클러스터를 최적화 읽기 [X 기간] . 이 클러스터에서 슬레이브 읽기를 확실히 활성화합니다. (개인적으로 DB의 객체 문서에 날짜 수정 값을 포함 시켜서 관리합니다.)

Prod로 들어가기 전에로드 테스트 기능이 있다면 perf는 지옥에서 지옥을 모니터링합니다. MongoDB는 종종 VM에 배포 될 것이라는 가정하에 작성되었으며 (참조 시스템은 EC2에 있음) VM에 샤딩하는 것을 두려워하지 마십시오.


처리하는 동안 초기 문서 스텁이 생성 된 다음 처리의 첫 번째 부분에서 다양한 하위 단계에 의해 지속적으로 업데이트됩니다. 우리는 우리가하고있는 확장의 양을 줄이기 위해 초기 생성시 핸드 패딩을 수행 할 가능성을 평가했지만 현재 쓰기 잠금 백분율은 매우 낮습니다.
sysadmin1138

RAM에 기록하기 위해 기록하기 전에 레코드를 읽는 것은 좋은 조언이 아닙니다. 2.0 이후 (2011 년 중반) MongoDB는 액세스 할 데이터가 RAM에없는 경우 항복을 했으므로 잠금을 수행 한 이후로 그렇게하면 아무런 이유없이 서버에 여분의 읽기와 여분의 왕복이 발생합니다. 어쨌든 그 기간 동안 개최되지 않습니다.
Asya Kamsky

13

이것은 여기에 게시 된 다른 답변에 대한 부록으로 의도되었으며 여기에서 고려해야 할 많은 관련 요소에 대해 토론합니다. 그러나 랜덤 액세스 유형 시스템에서 효율적인 RAM 사용률과 관련하여 종종 간과되는 또 다른 요소가 있습니다.

Linux를 실행하여 readahead의 현재 설정을 확인할 수 있습니다 blockdev --report(일반적으로 sudo / root 권한이 필요함). 각 디스크 장치마다 한 행씩 테이블을 인쇄합니다. RA 열에는 readahead 값이 포함됩니다. 이 값은 512 바이트 섹터의 수입니다 (섹터 크기가 기본값이 아닌 경우-이 포스트를 작성할 당시에는 더 큰 크기의 디스크도 커널에 의해 512 바이트 섹터로 처리됨). 디스크 액세스.

다음을 실행하여 주어진 디스크 장치에 대한 미리 읽기 설정을 설정할 수 있습니다.

blockdev --setra <value> <device name>

소프트웨어 기반 RAID 시스템을 사용하는 경우 각 디스크 장치와 RAID 컨트롤러에 해당하는 장치에서 미리 읽기를 설정하십시오.

이것이 왜 중요한가? 글쎄, readahead는 MongoDB가 순차적 액세스-RAM에 대한 읽기를 최적화하기 위해 사용하려는 동일한 리소스를 사용합니다. 회전 디스크 (또는 회전 디스크와 같은 방식으로 작동하는 EBS-내가보고있는 장치)에서 순차적으로 읽기를 수행 할 때 주변 데이터를 RAM으로 가져 오면 성능이 크게 향상되고 검색 시간이 단축되고 올바른 환경에서는 인상적인 결과를 얻을 수 있습니다.

MongoDB와 같은 시스템에서 액세스가 일반적으로 데이터 세트에서 무작위로 액세스되는 시스템의 경우 다른 곳에서 더 잘 사용되는 메모리를 낭비합니다. 다른 곳에서 언급 한 바와 같이 MongoDB의 메모리를 관리하는 시스템은 요청이있을 때 미리 읽기에 메모리 청크를 할당하므로 MongoDB가 효과적으로 사용할 RAM이 줄어 듭니다.

올바른 판독 헤드 크기를 선택하는 것은 까다 롭고 하드웨어, 구성, 블록 크기, 스트라이프 크기 및 데이터 자체에 따라 다릅니다. 예를 들어 SSD로 이동하는 경우 낮은 설정을 원하지만 데이터에 따라 낮은 수준을 사용하게됩니다.

설명 : 미리 읽기가 전체 단일 문서를 가져 와서 디스크로 돌아갈 필요가 없는지 확인하고 싶습니다. 디스크의 섹터는 일반적으로 512 바이트이므로 미리 읽기없이 전체 문서에서 16 개의 디스크 액세스가 필요합니다. 16 개 이상의 섹터에 대한 미리 읽기가있는 경우 한 번의 디스크 여행만으로 전체 문서를 읽을 수 있습니다.

실제로 MongoDB 인덱스 버킷은 8k이므로, 어쨌든 16 번 이하의 판독을 설정하지 않으려는 경우 또는 하나의 인덱스 버킷에서 2 번의 디스크 액세스가 필요합니다. 일반적인 모범 사례는 현재 설정으로 시작하여 절반으로 줄인 다음 RAM 사용률과 IO를 다시 평가 한 다음 계속 진행하는 것입니다.


1
집에 하드웨어를 설치하면 유용한 정보를 얻을 수 있습니다. 감사!
sysadmin1138

3

최종 사용자 쿼리에 복제본을 사용하고 다른 컴퓨터에서 워크 플로를 수행하는 것을 고려해야합니다.

1:10의 룰을 사용하여 1TB의 디스크 스토리지에 대한 약 128GB의 RAM을보고 있습니다. 오늘날 일부 저렴한 SSD는 60K IOPS 이상에 도달한다고 주장하지만 SSD와 함께 RAID를 사용하는지 여부에 따라 실제 수치는 약간 다를 수 있습니다. 그렇다면 RAID 카드도 매우 중요합니다. .

이 게시물 당시 128GB DDR3 ECC 램에서 256GB로 전환하면 1U 인텔 서버에서 약 2,000 달러가 추가되는 것으로 보이며, 이는 1TB 데이터와 1 : 5 비율을 제공합니다. 더 나은 비율. 가능한 빨리 작업을 완료해야하는 경우 더 많은 RAM이 도움이 될 것입니다. 그러나 정말 긴급한가요?

ext4에서 "noatime, data = writeback, nobarrier"와 같은 파일 시스템 튜닝도 수행해야하며, 커널 설정을 약간 조정하고 성능을 최대한 활용해야 할 수도 있습니다. 체계.

RAID를 사용하는 경우 RAID-10을 선택하는 것이 좋으며 적절한 RAID 컨트롤러를 사용하면 성능이 크게 향상되지만 사용 가능한 공간이 절반으로 줄어 듭니다. 사용 가능한 공간을 절반으로 줄이지 않고 적절한 성능 향상을 원할 경우 RAID50을 살펴볼 수도 있습니다. RAID 실행의 위험은 더 이상 드라이브에서 TRIM에 액세스 할 수 없기 때문에 데이터를 이동하고 RAID를 분리하고 드라이브를 트리밍하고 RAID를 다시 만들어야한다는 것을 의미합니다.

궁극적으로 원하는 복잡성, 지출 비용 및 작업 처리 속도를 결정해야합니다. 또한 빠른 응답이 필요한 최종 사용자 쿼리에 Mongo를 사용할 수 있지만 다른 것을 사용하여 데이터를 처리 할 수 ​​있기 때문에 MongoDB가 이상적인 데이터베이스인지 평가할 것입니다. 몇 초 안에 준비하지 않아도됩니다. 또한 여러 시스템에보다 쉽게 ​​워크로드를 분산시킬 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.