programing

MongoDB에서 커서란 무엇입니까?

closeapi 2023. 5. 16. 22:39
반응형

MongoDB에서 커서란 무엇입니까?

우리는 결국 발생하는 것에 대해 어려움을 겪고 있습니다.cursor not found exceptions모피아 쿼리를 위해 SO에 대한 힌트를 찾았습니다. 메모리 소모가 클 수도 있습니다.

이제 배경에 대해 좀 더 알고 싶습니다. 누가 영어로 커서(MongoDB)가 실제로 무엇인지 설명할 수 있을까요?왜 계속 열려있거나 찾을 수 없습니까?


설명서에서는 커서를 다음과 같이 정의합니다.

쿼리의 결과 집합에 대한 포인터입니다.클라이언트는 커서를 통해 반복하여 결과를 검색할 수 있습니다.기본적으로 커서는 10분 동안 사용하지 않으면 시간 초과됩니다.

하지만 이것은 그다지 말이 되지 않습니다.아마도 정의하는 것이 도움이 될 수 있습니다.batch설명서에 다음 내용도 나와 있으므로 쿼리 결과의 경우

MongoDB 서버는 쿼리 결과를 일괄적으로 반환합니다.배치 크기는 최대 BSON 문서 크기를 초과하지 않습니다.대부분의 쿼리에서 첫 번째 배치는 101개의 문서를 반환하거나 1메가바이트를 초과할 만큼의 문서만 반환합니다.후속 배치 크기는 4MB입니다. [...] 색인 없이 정렬 작업을 포함하는 쿼리의 경우, 서버는 결과를 반환하기 전에 정렬을 수행하기 위해 메모리에 있는 모든 문서를 로드해야 합니다.

참고: 문제의 쿼리에서 우리는 정렬 문을 전혀 사용하지 않지만 또한 사용하지도 않습니다.limit그리고.offset.

다음은 사이의 비교입니다.toArray()는 "a" "a" "a" "a" 에 있습니다.find()Node.js MongoDB 드라이버에 있습니다.공통 코드:

var MongoClient = require('mongodb').MongoClient,
assert = require('assert');

MongoClient.connect('mongodb://localhost:27017/crunchbase', function (err, db) {
    assert.equal(err, null);
    console.log('Successfully connected to MongoDB.');

    const query = { category_code: "biotech" };

    // toArray() vs. cursor code goes here
});

여기 위 섹션에 있는 코드가 있습니다.

    db.collection('companies').find(query).toArray(function (err, docs) {
        assert.equal(err, null);
        assert.notEqual(docs.length, 0);

        docs.forEach(doc => {
            console.log(`${doc.name} is a ${doc.category_code} company.`);
        });

        db.close();
    });

문서에 따르면,

호출자는 결과를 저장하기에 충분한 메모리가 있는지 확인할 책임이 있습니다.

다음은 방법을 사용하는 커서 기반 접근 방식입니다.

    const cursor = db.collection('companies').find(query);

    cursor.forEach(
        function (doc) {
            console.log(`${doc.name} is a ${doc.category_code} company.`);
        },
        function (err) {
            assert.equal(err, null);
            return db.close();
        }
    );
});

forEach()메모리에 있는 모든 데이터를 가져오는 대신 애플리케이션으로 데이터를 스트리밍합니다. find()제공할 문서 중 일부를 사용하려고 할 때까지 데이터베이스에 실제로 요청하지 않으므로 커서를 즉시 만듭니다.cursor우리의 질문을 설명하는 것입니다. 매 개 수변째의 두 번째 :cursor.forEach에는 오류가 발생할 때 수행할 작업이 나와 있습니다.

코드의 에서, 그것은 초버서전기에의그, 은것드코입니다.toArray()데이터베이스를 강제로 호출한 것입니다.그것은 우리가 모든 서류가 필요하고 그것들이 그 안에 있기를 원한다는 것을 의미했습니다.array.

:MongoDB데이터를 일괄적으로 반환합니다.는 커서에서 아래이애커서(응용 프로그램)까지의 .MongoDB:

MongoDB 커서 그래픽

forEach 성이뛰남보다 더 잘 됩니다.toArray우리가 마지막에 도달할 때까지 서류가 들어오는 대로 처리할 수 있기 때문입니다.와 대조합니다.toArray모든 문서가 검색되고 전체 배열이 작성될 때까지 기다립니다.이는 드라이버와 데이터베이스 시스템이 협력하여 결과를 애플리케이션에 배치한다는 사실로부터 아무런 이점을 얻지 못한다는 것을 의미합니다.배치는 메모리 오버헤드 및 실행 시간 측면에서 효율성을 제공하기 위한 것입니다.가능하면 애플리케이션에서 이 기능을 활용하십시오.

저는 결코 mongodb 전문가는 아니지만 지난 1년 동안 중간 크기의 mongo 시스템에서 작업한 관찰 사항을 추가하고 싶습니다.또한 커서가 일반적으로 작동하는 방식에 대해 훌륭한 걸음걸이를 보여준 @xameeramir에게 감사드립니다.

커서 손실 예외의 원인은 여러 가지일 수 있습니다.제가 주목한 것 중 하나는 이 답변에 설명되어 있습니다.

커서는 서버 측에 있습니다.복제본 집합에 배포되지 않지만 작성 시 기본 인스턴스에 존재합니다.즉, 다른 인스턴스가 주 인스턴스로 인계되면 커서가 클라이언트에 손실됩니다.이전 프라이머리가 아직 작동 중이고 주변에 있으면 쓸모가 없을 수도 있습니다.제 생각에 그것은 잠시 후에 쓰레기로 수거된 것 같습니다.따라서 mongo 복제본 세트가 불안정하거나 네트워크가 불안정한 경우 오랜 시간 실행 중인 쿼리를 수행할 때 운이 좋지 않습니다.

커서가 반환할 내용의 전체 내용이 서버의 메모리에 맞지 않으면 쿼리 속도가 매우 느릴 수 있습니다.서버의 RAM은 실행 중인 가장 큰 쿼리보다 커야 합니다.

이 모든 것은 더 나은 설계를 통해 부분적으로 피할 수 있습니다.장기간 실행 중인 쿼리가 큰 사용 사례의 경우 큰 데이터베이스 대신 여러 개의 작은 데이터베이스 컬렉션을 사용하는 것이 좋습니다.

컬렉의션.find메서드는 커서를 반환합니다. 이 커서는 쿼리 필터와 일치하는 문서 집합(결과 집합이라고 함)을 가리킵니다.결과 집합은 쿼리에 의해 반환되는 실제 문서이지만 데이터베이스 서버에 있습니다.

에는 예를 , 클이언램예들어를에프로그트라,,▁the,mongo셸, 커서를 얻을 수 있습니다.커서는 결과 집합으로 작업하기 위한 API 또는 프로그램과 같다고 생각할 수 있습니다.커서에는 결과 집합에 대한 일부 작업을 수행하기 위해 실행할 수 있는 많은 메서드가 있습니다.일부 메소드는 결과 집합 데이터에 영향을 주고 일부 메소드는 결과 집합에 대한 상태 또는 정보를 제공합니다.

커서가 결과 집합에 대한 정보를 유지하므로 다른 커서 방법을 적용하여 결과 집합 데이터를 사용할 때 일부 정보가 변경될 수 있습니다.이러한 방법과 정보를 사용하여 응용 프로그램에 적합합니다. 즉, 쿼리된 데이터를 사용하여 수행할 작업을 선택할 수 있습니다.


되는 몇 및커 와 일 반 여 사 하 작 업 세 트 과 결 용 을 서 능 적 기 으 로 및 법 사 는 되 방 용 ▁working ▁using ▁setmongo개요:

count()method는 결과 집합의 문서 수를 처음에는 쿼리의 결과로 반환합니다.이 값은 커서의 수명 중 어느 시점에서도 항상 일정합니다.이것은 정보입니다.이 정보는 커서가 닫히거나 소진된 후에도 동일하게 유지됩니다.

결과 집합에서 문서를 읽을 때 결과 집합이 모두 사용됩니다.완전히 지치면 더 이상 읽을 수 없습니다.hasNext()읽을 수 있는 문서가 있는지 여부를 알려줍니다. 부울 true 또는 false를 반환합니다.next() 가능한합니다. 사용가먼반다니환합(으)로 합니다.hasNext그리고 나서 합니다.next이 두 가지 방법은 일반적으로 결과 집합 데이터를 반복하는 데 사용됩니다.다른 반복 방법은 다음과 같습니다.forEach().

데이터는 서버에서 일괄적으로 검색되며, 기본 크기입니다.첫 번째 배치로 문서를 읽고 모든 문서를 읽었을 때 다음과 같습니다.next()집합에서 까지 다음 합니다.이 배치 크기를 구성할 수 있으며 상태를 가져올 수도 있습니다.

만약 당신이 그것을 적용한다면.toArray()그러면 결과 집합의 나머지 모든 문서가 클라이언트 컴퓨터의 메모리에 로드되고 JavaScript 배열로 사용할 수 있습니다.그리고 결과 집합 데이터가 모두 소진됩니다.다음과 같은 것들hasNext는 메드가반니다됩환을 합니다.false 리고그고.next오류가 발생합니다(커서를 다 쓰면 커서에서 데이터를 읽을 수 없습니다).이 메서드는 모든 결과 집합 데이터를 클라이언트의 메모리(어레이)에 로드합니다.결과 집합이 큰 경우 메모리를 소모할 수 있습니다.

itcount()결과 집합에 남아 있는 문서의 를 반환하고 커서를 소모합니다.

다음과 같은 커서 방법이 있습니다.isClosed(),isExhausted(),size()데이터로 작업할 때 커서와 기본 결과 집합에 대한 상태 정보를 제공합니다.

이러한 기능은 커서와 결과 집합의 기본 기능입니다.다양한 커서 방법이 있으며, 사용자는 이 방법이 어떻게 작동하는지 확인하고 더 나은 이해를 얻을 수 있습니다.

참조:


의 예mongo개요:

다음과 같이 합니다.test컬렉션에는 200개의 문서가 있습니다(명령을 동일한 순서로 실행).

  • var cur = db.test.find( { } ).limit(25)25개의 문서로만 결과 집합을 만듭니다.
  • 그렇지만,cur.count()쿼리 필터의 실제 문서 수에 해당하는 200을 표시합니다.
  • hasNext()돌아올 것입니다true.
  • next()문서를 반환합니다.
  • itcount()24를 반환합니다(커서를 소모합니다).
  • itcount()다시 0을 반환합니다.
  • cur.count()여전히 200을 표시합니다.

이 오류는 대용량 데이터 집합이 있고 해당 데이터에 대해 배치 처리를 수행하는 경우에도 발생하며 각 배치가 기본 커서 라이브 시간을 초과하는 총 시간을 초과하는 경우에 발생합니다.

그런 다음 처리가 완료될 때까지 이 커서가 만료되지 않음을 mongo에 알리도록 기본 시간을 변경해야 합니다.

제한 시간 없음 문서 확인

커서는 호출을 통해 반환되는 개체입니다.db.collection.find()MongoDB 컬렉션의 문서(SQL "행"에 해당하는 NoSQL)를 반복할 수 있습니다(NoSQL "표"에 해당).

클러스터가 안정적이고 구성원이 없는 경우 상태가 중단되거나 변경되면 커서를 찾을 수 없는 가장 가능성이 높은 이유는 다음과 같습니다.

기본 유휴 커서 시간 초과는 10분이지만 >= 3.6 버전에서는 기본 세션 시간 초과가 30분인 세션에도 커서가 연결되므로 noCursorTimeout() 옵션으로 커서가 만료되지 않도록 설정하더라도 세션 시간 초과가 30분으로 제한됩니다.세션 시간 초과로 인해 커서가 삭제되지 않도록 하려면 주기적으로 코드를 체크인하고 sessionRefresh 명령을 실행해야 합니다.

   db.adminCommand({"refreshSessions" : [sessionId]})

다음 배치를 가져오기 전에 데이터로 작업을 수행할 경우 커서가 삭제되지 않도록 세션을 30분 더 연장합니다.자세한 방법은 여기에서 문서를 확인하십시오.

https://docs.mongodb.com/manual/reference/method/cursor.noCursorTimeout/

언급URL : https://stackoverflow.com/questions/36766956/what-is-a-cursor-in-mongodb

반응형