2017-09-27 1 views
1

Cong 드라이버 버전 2.4.3을 사용하여 MongoDB 버전 3.4.4에 연결 중입니다. 나는 3 명의 회원 복제 세트 (1 차, 1 차, 1 차 중재자)를 가지고있다. 필자는 연결 스트링에 대다수의 글쓰기 문제를 설정했습니다. 기본 노드와 보조 노드가 모두 온라인 상태 일 때 아무런 문제없이 데이터베이스에 쓸 수 있습니다. 하지만 기본 오프라인 상태로 만들 때 문제가 있습니다.MongoDB - 우려 쓰기 대다수 - 스트림 끝까지 읽으려고 시도했습니다.

string connectionString = "mongodb://USERNAME:[email protected],SECONDARY/?replicaSet=MyReplicaSet&w=majority"; 

    var client = new MongoClient(connectionString); 
    IMongoDatabase database = client.GetDatabase("test"); 
    IMongoCollection<BsonDocument> collection = database.GetCollection<BsonDocument>("people"); 

    Console.WriteLine($"Number of documents: {collection.Count(FilterDefinition<BsonDocument>.Empty)}"); 

    collection.InsertOne(new BsonDocument("name", DateTime.Now.ToString("dd-MM-yyyy HH:mm:ss"))); 

    Console.WriteLine($"Number of documents: {collection.Count(FilterDefinition<BsonDocument>.Empty)}"); 

내가 차를 오프라인으로 할 때, 보조 선출 도착하고 난 여전히 데이터베이스에 기록 할 수 있습니다 (I는 새로 선출 된 차의 데이터베이스에서 문서를 볼 수 있습니다) :이 코드를 사용하고 있습니다. 그러나 collection.InsertOne에 대한 호출은 MongoDBConnectionException을 던지는 끝 :

나는 대부분의 쓰기 문제를 설정하지 않으면
MongoDB.Driver.MongoConnectionException: An exception occurred while receiving a message from the server. ---> System.IO.EndOfStreamException: Attempted to read past the end of the stream. 
    at MongoDB.Driver.Core.Misc.StreamExtensionMethods.ReadBytes(Stream stream, Byte[] buffer, Int32 offset, Int32 count, CancellationToken cancellationToken) 
    at MongoDB.Driver.Core.Connections.BinaryConnection.ReceiveBuffer() 
    --- End of inner exception stack trace --- 
    at MongoDB.Driver.Core.Connections.BinaryConnection.ReceiveBuffer() 
    at MongoDB.Driver.Core.Connections.BinaryConnection.ReceiveBuffer(Int32 responseTo, CancellationToken cancellationToken) 
    at MongoDB.Driver.Core.Connections.BinaryConnection.ReceiveMessage(Int32 responseTo, IMessageEncoderSelector encoderSelector, MessageEncoderSettings messageEncoderSettings, CancellationToken cancellationToken) 
    at MongoDB.Driver.Core.ConnectionPools.ExclusiveConnectionPool.AcquiredConnection.ReceiveMessage(Int32 responseTo, IMessageEncoderSelector encoderSelector, MessageEncoderSettings messageEncoderSettings, CancellationToken cancellationToken) 
    at MongoDB.Driver.Core.WireProtocol.CommandWireProtocol`1.Execute(IConnection connection, CancellationToken cancellationToken) 
    at MongoDB.Driver.Core.Servers.Server.ServerChannel.ExecuteProtocol[TResult](IWireProtocol`1 protocol, CancellationToken cancellationToken) 
    at MongoDB.Driver.Core.Servers.Server.ServerChannel.Command[TResult](DatabaseNamespace databaseNamespace, BsonDocument command, IElementNameValidator commandValidator, Func`1 responseHandling, Boolean slaveOk, IBsonSerializer`1 resultSerializer, MessageEncoderSettings messageEncoderSettings, CancellationToken cancellationToken) 
    at MongoDB.Driver.Core.Operations.BulkUnmixedWriteOperationBase.ExecuteProtocol(IChannelHandle channel, BsonDocument command, Func`1 responseHandling, CancellationToken cancellationToken) 
    at MongoDB.Driver.Core.Operations.BulkUnmixedWriteOperationBase.ExecuteBatch(IChannelHandle channel, BatchableSource`1 requestSource, Int32 originalIndex, CancellationToken cancellationToken) 
    at MongoDB.Driver.Core.Operations.BulkUnmixedWriteOperationBase.ExecuteBatches(IChannelHandle channel, CancellationToken cancellationToken) 
    at MongoDB.Driver.Core.Operations.BulkUnmixedWriteOperationBase.Execute(IChannelHandle channel, CancellationToken cancellationToken) 
    at MongoDB.Driver.Core.Operations.BulkMixedWriteOperation.ExecuteBatch(IChannelHandle channel, Run run, Boolean isLast, CancellationToken cancellationToken) 
    at MongoDB.Driver.Core.Operations.BulkMixedWriteOperation.Execute(IWriteBinding binding, CancellationToken cancellationToken) 
    at MongoDB.Driver.OperationExecutor.ExecuteWriteOperation[TResult](IWriteBinding binding, IWriteOperation`1 operation, CancellationToken cancellationToken) 
    at MongoDB.Driver.MongoCollectionImpl`1.ExecuteWriteOperation[TResult](IWriteOperation`1 operation, CancellationToken cancellationToken) 
    at MongoDB.Driver.MongoCollectionImpl`1.BulkWrite(IEnumerable`1 requests, BulkWriteOptions options, CancellationToken cancellationToken) 
    at MongoDB.Driver.MongoCollectionBase`1.InsertOne(TDocument document, InsertOneOptions options, CancellationToken cancellationToken) 
    at ReplicaSetTest.Program.Main(String[] args) in C:\Code\TFS\Published Register\Main\ReplicaSetTest\Program.cs:line 57 

그때 내가 어떤 문제가 없습니다. 나는 MongoDB에 대한 많은 경험이 없으므로 잘못된 일이 무엇인지 잘 모르겠다. 누구든지이 문제의 원인을 추적하기 시작해야한다고 제안 할 수 있습니까?

감사합니다,

데이비드

답변

1

그러나 collection.InsertOne에 대한 호출이

을 먼저 MongoDBConnectionException을 던지는 끝은 쓰기 문제의 대부분은 클라이언트가 다수로부터 승인을 요청하는 것을 의미한다 (기본 노드를 포함해야 함). 따라서 클라이언트 응용 프로그램은 기본 노드와 보조 노드 중 하나에서 응답을 기다립니다. 이 다이어그램은 Verify Write Operations to Replica Sets을 참조하십시오.

수신 확인 쓰기 대기 기간 동안 기본 노드가 계단 아래에 있으면 기본 노드에 대한 클라이언트 연결이 끊어집니다. 2 차 서버는 노드의 상태가 SECONDARY에서 PRIMARY로 변경되었으므로 설정된 연결을 삭제하려고 시도합니다 (Replica Set Member States 참조). 이것은 클라이언트가 응답을 기대하고 있지만 결코 오지 않을 것이므로 클라이언트에 대한 연결 (스트림)을 잃게됩니다. 따라서 다음과 같이 표시됩니다.

System.IO.EndOfStreamException: Attempted to read past the end of the stream 

이 예외를 catch하고 쓰기의 특성에 따라 적절하게 처리해야합니다.

MongoDB v3.6에는 transient network errors/replica set elections 처리를 제공하는 Retryable Writes이 있다는 것을 알고 싶을 수도 있습니다.

또한 배포가 Primary with Two Secondaries 대신 Primary with a Secondary and an Arbiter 인 것으로 나타났습니다. 데이터 노드가 2 개 밖에없고 그 중 하나가 작동 중지 된 경우 쓰기 문제는 대부분 충족되지 않습니다. 쓰기 작업은 복제본 집합의 (대다수)에 의해 수신되어야하지만 활성 데이터 보유 멤버는 하나뿐입니다. 중재자를 2 차 구성원으로 전환하는 것을 고려하십시오.

+0

대단히 감사합니다. 훌륭한 답변입니다. – dlarkin77

관련 문제