ProgramingTip

MongoDB 연결에 대한 .NET 모범 사례?

bestdevel 2020. 12. 4. 19:48
반응형

MongoDB 연결에 대한 .NET 모범 사례?


저는 최근 GitHub에서 C # 드라이버를 사용하여 MongoDB (놀라 울림 빠르다)를 가지고 놀았습니다. 테스트중인 작은 단일 콘솔 앱에서 모든 것이 잘 작동합니다. 단일 단위를 실행하여 8 초 안에 1,000,000 개의 문서 (예, 백만 개)를 추가 할 수 있습니다. for 루프의 범위 밖에서 연결을 사용하는 경우에만이 성능을 얻습니다. 즉, 각 교체에 대해 연결을 유지하고 있습니다. 그것은 인위적인 것입니다.

여러 단계에서 어떻게 작동하는지 확인하기 위해 한 단계 끌어 올릴 생각했습니다. 여러 동시 요청이있는 웹 사이트를 시뮬레이션해야하기 때문에이 작업을 수행합니다. 15 ~ 50 개의 경우에 총 150,000 개의 문서를 삽입합니다. 즉, 실행하고 각 삽입 작업에 대한 새 연결을 생성하면 성능이 중단됩니다.

분명히 연결을 공유, 잠금 또는 풀링 할 방법을 찾아야합니다. 거기에 질문이 있습니다. MongoDB 연결 구조에서 가장 좋은 방법은 무엇입니까? 앱의 수명 동안 연결을 열어 두어야하는 작업에 TCP 연결을 연결하는 데 상당한 지연 시간이 있습니까?

MongoDB, 특히 기본 연결에 대한 실제 세계 또는 경험이 있습니까?

다음은 삽입 작업을 위해 잠긴 정적 연결을 사용하는 스레딩 샘플입니다. 웹 최적화에서 성능과 안정성을 제공 할 수있는 제안을 제공하십시오!

private static Mongo _mongo;

private static void RunMongoThreaded()
{
    _mongo = new Mongo();
    _mongo.Connect();

    var threadFinishEvents = new List<EventWaitHandle>();

    for(var i = 0; i < 50; i++)
    {
        var threadFinish = new EventWaitHandle(false, EventResetMode.ManualReset);
        threadFinishEvents.Add(threadFinish);

        var thread = new Thread(delegate()
            {
                 RunMongoThread();
                 threadFinish.Set();
            });

        thread.Start();
    }

    WaitHandle.WaitAll(threadFinishEvents.ToArray());
    _mongo.Disconnect();
}

private static void RunMongoThread()
{
    for (var i = 0; i < 3000; i++)
    {
        var db = _mongo.getDB("Sample");
        var collection = db.GetCollection("Users");
        var user = GetUser(i);
        var document = new Document();
        document["FirstName"] = user.FirstName;
        document["LastName"] = user.LastName;

        lock (_mongo) // Lock the connection - not ideal for threading, but safe and seemingly fast
        {
            collection.Insert(document);
        }
    }
}

여기에 존재하는 대부분의 답변은 구식 이며 .net 드라이버가 성숙되고 기능이 추가되고 더 이상 적용 할 수 있습니다.

여기에있는 새로운 2.0 드라이버의 문서를 사용 : http://mongodb.github.io/mongo-csharp-driver/2.0/reference/driver/connecting/

.net 드라이버는 이제 코드로부터 안전하며 연결 ​​풀링을 처리합니다. 문서에 따르면

MongoClient 인스턴스는 정적 변수 또는 단일 수명이있는 IoC 컨테이너로 전역 위치에 저장하는 것이 좋습니다.


정적 연결에 대해 모든 것이 기억에 공유 할 것입니다. 원하는 것은 당 하나의 연결입니다.


mongodb-csharp를 사용할 때 ADO 연결처럼 취급합니다. Mongo에서 연결을 생성 할 때 풀에서 연결을 빌려 처리 할 때까지 소유합니다. 따라서 블록을 사용하면 연결이 풀로 돌아갑니다. Mongo 개체를 만드는 것은 쉽게 사용하고 빠릅니다.

for(var i=0;i<100;i++) 
{ 
        using(var mongo1 = new Mongo()) 
        using(var mongo2 = new Mongo()) 
        { 
                mongo1.Connect(); 
                mongo2.Connect(); 
        } 
} 

데이터베이스 로그
Wed Jun 02 20:54:21 연결 허용 127.0.0.1:58214 # 1
Wed Jun 02 20:54:21 연결 허용 127.0.0.1:58215 # 2
Wed Jun 02 20:54:21 MessagingPort recv () errno : 0 오류 없음 127.0.0.1:58214
Wed Jun 02 20:54:21 end connection 127.0.0.1:58214
Wed Jun 02 20:54:21 MessagingPort recv () errno : 0 오류 없음 127.0.0.1:58215
Wed Jun 02 20:54:21 연결구 127.0.0.1:58215

2 개의 연결 만 열렸습니다.

mongodb-csharp 포럼을 사용하여 이것을 모았습니다. http://groups.google.com/group/mongodb-csharp/browse_thread/thread/867fa78d726b1d4


다소 흥미로운 것은 jLinq 개발자가 만든 MongoDB 용 C # 드라이버 인 CSMongo입니다. 다음은 샘플입니다.

//create a database instance
using (MongoDatabase database = new MongoDatabase(connectionString)) {

    //create a new document to add
    MongoDocument document = new MongoDocument(new {
        name = "Hugo",
        age = 30,
        admin = false
    });

    //create entire objects with anonymous types
    document += new {
        admin = true,
        website = "http://www.hugoware.net",
        settings = new {
            color = "orange",
            highlight = "yellow",
            background = "abstract.jpg"
        }
    };

    //remove fields entirely
    document -= "languages";
    document -= new[] { "website", "settings.highlight" };

    //or even attach other documents
    MongoDocument stuff = new MongoDocument(new {
        computers = new [] { 
            "Dell XPS", 
            "Sony VAIO", 
            "Macbook Pro" 
            }
        });
    document += stuff;

    //insert the document immediately
    database.Insert("users", document);

}

연결 풀이 답이 될 것입니다.

이 기능은 개발 중입니다 (자세한 내용은 http://jira.mongodb.org/browse/CSHARP-9 참조 ).

현재 웹 애플리케이션의 경우 가장 좋은 방법은 BeginRequest에서 연결하고 EndRequest에서 연결을 해제하는 것입니다. 하지만 나에게는 Connection Pool이없는 각 요청에 대해 작업이 너무 비싸다고 생각합니다. 그래서 전역 Mongo 객체를 사용하고 모든 스레드에 대해 공유 리소스로 사용하기로 결정했습니다 (지금 github에서 최신 C # 드라이버를 가져 오면 동시성 성능도 약간 향상됩니다).

Global Mongo 객체 사용의 단점을 모르겠습니다. 따라서 다른 전문가가 이에 대해 언급 할 때까지 기다리겠습니다.

하지만 기능 (커넥션 풀)이 완성 될 때까지 함께 살 수있을 것 같아요.


나는 csharp-mongodb 드라이버를 사용하고 있으며 그의 연결 풀에 도움이되지 않습니다. (나는 웹 요청 당 mongodb에 대한 요청이 약 10-20 개 있습니다. (온라인 사용자 150 명-평균) 통계를 모니터링하거나 연결할 수도 없습니다. 쉘에서 mongodb로 예외가 발생합니다.

요청에 따라 연결을 열고 처리하는 저장소를 만들었습니다. 나는 다음과 같은 것들에 의존합니다. 1) 드라이버에 연결 풀이 있습니다. 2) 내 연구 후 (사용자 그룹에 이것에 대해 몇 가지 질문을 게시했습니다)-mongo 개체를 만들고 연결을 여는 것이 큰 작업이 아니라 너무 무거운 작업이라는 것을 이해했습니다.

그러나 오늘 내 생산은 중단됩니다 :( 요청마다 열린 연결을 저장해야 할 수도 있습니다 ...

다음은 사용자 그룹 http://groups.google.com/group/mongodb-user/browse_thread/thread/3d4a4e6c5eb48be3#에 대한 링크입니다.

참고 URL : https://stackoverflow.com/questions/2194047/net-best-practices-for-mongodb-connections

반응형