gpt4 book ai didi

MongoDB - 写关注多数 - 试图读取超过流的末尾

转载 作者:可可西里 更新时间:2023-11-01 10:14:29 26 4
gpt4 key购买 nike

我正在使用 2.4.3 版的 C# 驱动程序连接到 3.4.4 版的 MongoDB。我有一个 3 成员副本集(一个主要的,一个次要的,一个仲裁者)。我在我的连接字符串中设置了对 majority 的写入关注。当主节点和辅助节点都在线时,我可以毫无问题地写入数据库。但是当我使主要服务器脱机时遇到了麻烦。我正在使用这段代码:

    string connectionString = "mongodb://USERNAME:PASSWORD@PRIMARY,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)}");

当我让主服务器脱机时,次要服务器被选出,我仍然可以写入数据库(我可以在新选出的主服务器上看到数据库中的文档)。但是对 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 没有太多经验,所以我不知道出了什么问题。谁能建议我应该从哪里开始追查这个问题的原因?

谢谢,

大卫

最佳答案

But the call to collection.InsertOne ends up throwing a MongoDBConnectionException

首先,写关注多数意味着客户端请求大多数副本集(必须包括主节点)的确认。因此,客户端应用程序将等待来自主节点和您的一个辅助节点的响应。参见 Verify Write Operations to Replica Sets对于这个图表。

如果在确认写入的等待期间主节点降级,则与主节点的客户端连接将丢失。辅助节点也会尝试清除任何已建立的连接,因为节点的状态已从 SECONDARY 更改为 PRIMARY(另请参见 Replica Set Member States)。这将导致客户端丢失连接(流),因为客户端期待回复,但它永远不会到来。因此,你得到:

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

您应该 try catch 此异常,并根据写入的性质进行适当处理。

您可能还想知道在 MongoDB v3.6 中,有 Retryable Writes提供 transient 网络错误/副本集选举的处理。

此外,我还注意到您的部署由 Primary with a Secondary and an Arbiter 组成而不是 Primary with Two Secondaries .如果您只有 2 个数据承载节点并且其中一个已关闭,则将无法满足写入关注的大多数。由于它要求写入操作被副本集的多数接收,但只有一个数据承载成员处于事件状态。请考虑将仲裁者转换为次要成员。

关于MongoDB - 写关注多数 - 试图读取超过流的末尾,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46447883/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com