programing

MongoDB 삽입 속도/초를 높이는 방법은 무엇입니까?

css3 2023. 6. 19. 21:55

MongoDB 삽입 속도/초를 높이는 방법은 무엇입니까?

초당 삽입 횟수를 최대화하려고 합니다.저는 현재 초당 약 20,000개의 인서트를 받고 있습니다.사용하는 스레드와 CPU가 많을수록 성능이 저하됩니다(16개의 코어를 사용할 수 있음).현재 2개의 스레드는 16개의 코어 듀얼 프로세서 기계에서 16개의 스레드보다 초당 더 많은 작업을 수행합니다.문제가 무엇인지에 대한 아이디어가 있습니까?제가 몽고드를 하나만 사용해서 그런가요?상황을 지연시킬 수 있는 것은 색인입니까?샤딩을 사용해야 합니까?셰이딩을 할 수 있는 방법이 있는지 궁금합니다. 또한 데이터베이스의 상한선을 유지하는 것도 마찬가지입니다.

제약 조건: 약 300,000개의 삽입/초를 처리해야 하며, 자체 제한(캡)되어야 하며, 비교적 빠르게 쿼리할 수 있어야 합니다.

문제 공간: 주요 휴대폰 회사의 통화 기록(약 30만 삽입/초)을 처리하고 가능한 한 오랫동안(예: 일주일) 해당 통화 기록을 쿼리할 수 있도록 해야 합니다.

#!/usr/bin/perl

use strict;
use warnings;
use threads;
use threads::shared;

use MongoDB;
use Time::HiRes;

my $conn = MongoDB::Connection->new;

my $db = $conn->tutorial;

my $users = $db->users;

my $cmd = Tie::IxHash->new(
    "create"    => "users",
    "capped"    => "boolean::true",
    "max"       => 10000000,
    );

$db->run_command($cmd);

my $idx = Tie::IxHash->new(
    "background"=> "boolean::true",
);
$users->ensure_index($idx);


my $myhash =
    {
        "name"  => "James",
        "age"   => 31,
        #    "likes" => [qw/Danielle biking food games/]
    };

my $j : shared = 0;

my $numthread = 2;  # how many threads to run

my @array;
for (1..100000) {
    push (@array, $myhash);
    $j++;
}

sub thInsert {
    #my @ids = $users->batch_insert(\@array);
    #$users->bulk_insert(\@array);
    $users->batch_insert(\@array);
}

my @threads;

my $timestart = Time::HiRes::time();
push @threads, threads->new(\&thInsert) for 1..$numthread;
$_->join foreach @threads; # wait for all threads to finish
print (($j*$numthread) . "\n");
my $timeend = Time::HiRes::time();

print( (($j*$numthread)/($timeend - $timestart)) . "\n");

$users->drop();
$db->drop();

MongoDB에 쓰기는 현재 글로벌 쓰기 잠금을 필요로 하지만 수집 수준 잠금이 곧 이루어질 것으로 예상됩니다.스레드를 더 많이 사용하면 스레드가 잠금 해제를 기다리는 동안 서로를 차단하므로 동시성 문제가 더 많이 발생할 수 있습니다.

인덱스를 사용하면 속도가 느려집니다. 최상의 삽입 성능을 얻으려면 데이터를 로드한 후에 인덱스를 추가하는 것이 이상적이지만, 예를 들어 고유한 인덱스를 사용하는 경우에는 항상 추가할 수 없습니다.

쓰기 성능을 극대화하려면 샤딩이 최선입니다.이렇게 하면 쓰기 작업을 여러 시스템에 분산함에 따라 훨씬 더 뛰어난 동시성과 더 높은 디스크 I/O 용량을 제공할 수 있습니다.

현재 2개의 스레드는 16개의 코어 듀얼 프로세서 기계에서 16개의 스레드보다 초당 더 많은 작업을 수행합니다.

MongoDB 삽입을 동시에 수행할 수 없습니다.모든 삽입은 쓰기 잠금을 획득해야 합니다.글로벌 잠금인지 수집 단위 잠금인지 확실하지 않지만, 사용자의 경우에는 차이가 없습니다.

따라서 이 프로그램을 멀티 스레드로 만드는 것은 Mongo가 병목 현상이 되는 즉시 큰 의미가 없습니다.

샤딩을 사용해야 합니까?

상한이 있는 컬렉션은 셰이징할 수 없습니다.

삽입 후 인덱스를 작성하는 것이 도움이 된다는 것을 알게 되었습니다.

음.. 몽고드 서버 하나로는 그렇게 많은 성능을 얻을 수 없을 것입니다.

0.3M * 60 * 60 * 24 = 26G 레코드/일, 180G 레코드/주.당신의 레코드 크기는 약 100바이트입니다. 그래서 그것은 2.6입니다.TB 데이터/일인덱싱에 어떤 필드를 사용하는지는 모르겠지만 10-20바이트 미만인지는 의심스럽습니다. 따라서 일주일 내내는 말할 것도 없고 일일 인덱스만 2G가 넘을 것입니다.인덱스는 메모리에 맞지 않을 것이고, 많은 쿼리는 재앙의 좋은 방법입니다.

검색 필드를 기준으로 데이터를 분할하여 수동으로 샤딩해야 합니다.대형 통신 회사라서 복제를 해야 합니다.단일/듀얼 코어 시스템을 많이 구입하면 메인(별) 서버용 코어만 필요합니다.

그나저나 데이터를 어떻게 조회합니까?키 값 상점을 이용할 수 있습니까?

수집을 수동으로 제한하는 것이 어떻습니까?여러 컴퓨터를 공유하고 쿼리에 필요한 색인을 적용한 후 매 시간마다 원하지 않는 문서를 삭제할 수 있습니다.

병목 현상은 글로벌 잠금일 가능성이 높습니다. 삽입 부하가 높은 시계열 데이터 애플리케이션에 대한 MongoDB의 평가에서 이러한 현상을 확인했습니다.샤드 키가 타임스탬프가 아닌지 확인해야 합니다. 그렇지 않으면 모든 삽입이 여러 시스템에 분산되지 않고 동일한 시스템에서 순차적으로 실행됩니다.

MongoDB의 쓰기 잠금은 글로벌하지만 이 "수집 수준 잠금이 곧 출시될 예정"을 인용합니다.

샤딩을 사용해야 합니까?

대답하기가 쉽지 않습니다.하나의 mongod에서 얻을 수 있는 것이 요구 사항을 충족하지 못하는 경우 MongoDB에서 쓰기를 확장할 수 있는 유일한 방법은 샤딩(sharding)이기 때문입니다(다른 인스턴스에 대한 쓰기는 서로 차단하지 않음).

언급URL : https://stackoverflow.com/questions/7265176/how-to-speed-up-mongodb-inserts-sec