Java 当ReplicaSet MongoDB中的节点出现故障时,更改事件流停止工作

Java 当ReplicaSet MongoDB中的节点出现故障时,更改事件流停止工作,java,mongodb,changestream,Java,Mongodb,Changestream,我对mongodb(版本4.2)有一个问题,特别是变更流功能 我有一个ReplicaSet集群,由1个主集群、1个辅助集群和1个仲裁器组成,在我使用API mongodb驱动程序sync 4.2.0-beta1的java代码中,我对感兴趣的集合有一个.watch()进程。 如下图所示: MongoClient MongoClient=MongoClients.create(“mongodb://localhost:27017,localhost:27018,localhost:27019/?re

我对mongodb(版本4.2)有一个问题,特别是变更流功能

我有一个ReplicaSet集群,由1个主集群、1个辅助集群和1个仲裁器组成,在我使用API mongodb驱动程序sync 4.2.0-beta1的java代码中,我对感兴趣的集合有一个.watch()进程。 如下图所示:

MongoClient MongoClient=MongoClients.create(“mongodb://localhost:27017,localhost:27018,localhost:27019/?replicset=replica”);
MongoDatabase=mongoClient.getDatabase(“测试”);
MongoCollection collectionStream=database.getCollection(“myCollection”);
List pipeline=Arrays.asList(聚合.match(Filters.and(Filters.in)(“operationType”,Arrays.asList)(“插入”、“更新”、“替换”、“失效”)));
MongoCursor=collectionStream.watch(pipeline).fullDocument(fullDocument.UPDATE_LOOKUP).iterator();
ChangeStreamDocument streamdevent=cursor.next();
System.out.println(“流化事件:+streamedEvent”);
基本上,这条河运行良好。发生插入/更新操作时,会识别该事件并正确传输文档。 但是,当两个节点中的一个(主节点或次节点,一个承载数据的节点)发生故障时,观察者停止传输任何内容。 更新/插入操作在数据库上继续正常,但流被阻止。一旦我重新启动两个节点中的一个,流立即正确恢复,并向我显示以前未流的事件。 另一方面,如果仲裁器节点下降,则流继续正常工作

下面是我的rs.conf()文件,如您所见,WriteConcern参数为1

{
"_id" : "replica",
"version" : 31,
"protocolVersion" : NumberLong(1),
"writeConcernMajorityJournalDefault" : true,
"members" : [
    {
        "_id" : 0,
        "host" : "host1:27017",
        "arbiterOnly" : false,
        "buildIndexes" : true,
        "hidden" : false,
        "priority" : 1000,
        "tags" : {
            
        },
        "slaveDelay" : NumberLong(0),
        "votes" : 1
    },
    {
        "_id" : 1,
        "host" : "host2:27017",
        "arbiterOnly" : false,
        "buildIndexes" : true,
        "hidden" : false,
        "priority" : 1,
        "tags" : {
            
        },
        "slaveDelay" : NumberLong(0),
        "votes" : 1
    },
    {
        "_id" : 4,
        "host" : "host2:27018",
        "arbiterOnly" : true,
        "buildIndexes" : true,
        "hidden" : false,
        "priority" : 0,
        "tags" : {
            
        },
        "slaveDelay" : NumberLong(0),
        "votes" : 1
    }
],
"settings" : {
    "chainingAllowed" : true,
    "heartbeatIntervalMillis" : 500,
    "heartbeatTimeoutSecs" : 3,
    "electionTimeoutMillis" : 3000,
    "catchUpTimeoutMillis" : -1,
    "catchUpTakeoverDelayMillis" : 30000,
    "getLastErrorModes" : {
        
    },
    "getLastErrorDefaults" : {
        "w" : 1,
        "j" : false,
        "wtimeout" : 0
    },
    "replicaSetId" : ObjectId("5f16a4e1e1c622bbea578576")
}}
有人能帮我解决这个问题吗

更新: 为了解决此行为,在每个节点的每个.conf文件中,我将replication.enableMajorityReadConcern设置为false,以禁用ReadConcernMain。 无论如何,按照此设置,通过停止一个主节点或辅助节点,我总是在控制台中得到以下异常:

Exception in thread "main" com.mongodb.MongoExecutionTimeoutException: Error waiting for snapshot not less than { ts: Timestamp(1605805914, 1), t: -1 }, current relevant optime is { ts: Timestamp(1605805864, 1), t: 71 }. :: caused by :: operation exceeded time limit
    at com.mongodb.internal.connection.ProtocolHelper.createSpecialException(ProtocolHelper.java:239)
    at com.mongodb.internal.connection.ProtocolHelper.getCommandFailureException(ProtocolHelper.java:171)
    at com.mongodb.internal.connection.InternalStreamConnection.receiveCommandMessageResponse(InternalStreamConnection.java:359)
    at com.mongodb.internal.connection.InternalStreamConnection.sendAndReceive(InternalStreamConnection.java:280)
    at com.mongodb.internal.connection.UsageTrackingInternalConnection.sendAndReceive(UsageTrackingInternalConnection.java:100)
    at com.mongodb.internal.connection.DefaultConnectionPool$PooledConnection.sendAndReceive(DefaultConnectionPool.java:490)
    at com.mongodb.internal.connection.CommandProtocolImpl.execute(CommandProtocolImpl.java:71)
    at com.mongodb.internal.connection.DefaultServer$DefaultServerProtocolExecutor.execute(DefaultServer.java:259)
    at com.mongodb.internal.connection.DefaultServerConnection.executeProtocol(DefaultServerConnection.java:202)
    at com.mongodb.internal.connection.DefaultServerConnection.command(DefaultServerConnection.java:118)
    at com.mongodb.internal.connection.DefaultServerConnection.command(DefaultServerConnection.java:110)
    at com.mongodb.internal.operation.CommandOperationHelper.executeCommand(CommandOperationHelper.java:345)
    at com.mongodb.internal.operation.CommandOperationHelper.executeCommand(CommandOperationHelper.java:336)
    at com.mongodb.internal.operation.CommandOperationHelper.executeCommandWithConnection(CommandOperationHelper.java:222)
    at com.mongodb.internal.operation.CommandOperationHelper$5.call(CommandOperationHelper.java:208)
    at com.mongodb.internal.operation.OperationHelper.withReadConnectionSource(OperationHelper.java:583)
    at com.mongodb.internal.operation.CommandOperationHelper.executeCommand(CommandOperationHelper.java:205)
    at com.mongodb.internal.operation.AggregateOperationImpl.execute(AggregateOperationImpl.java:189)
    at com.mongodb.internal.operation.ChangeStreamOperation$1.call(ChangeStreamOperation.java:325)
    at com.mongodb.internal.operation.ChangeStreamOperation$1.call(ChangeStreamOperation.java:321)
    at com.mongodb.internal.operation.OperationHelper.withReadConnectionSource(OperationHelper.java:583)
    at com.mongodb.internal.operation.ChangeStreamOperation.execute(ChangeStreamOperation.java:321)
    at com.mongodb.internal.operation.ChangeStreamOperation.execute(ChangeStreamOperation.java:60)
    at com.mongodb.client.internal.MongoClientDelegate$DelegateOperationExecutor.execute(MongoClientDelegate.java:178)
    at com.mongodb.client.internal.ChangeStreamIterableImpl.execute(ChangeStreamIterableImpl.java:204)
    at com.mongodb.client.internal.ChangeStreamIterableImpl.cursor(ChangeStreamIterableImpl.java:158)
    at com.mongodb.client.internal.ChangeStreamIterableImpl.iterator(ChangeStreamIterableImpl.java:153)
    at com.softstrategy.ProvaWatcher.ProvaWatcherApplication.main(ProvaWatcherApplication.java:34)
另一方面,如果我在everyfile.conf节点中注释掉默认情况下的enableMajorityReadConcern,则不会出现该异常

因此,我提出以下两个问题:

  • 为什么只有当ReadConcern设置为false并且节点down是数据承载节点时才会引发该异常
  • 为什么当仲裁器节点关闭时,无论ReadConcern设置如何,都不会引发该异常

  • 谢谢

    对于PSA体系结构,如果其中一个数据承载节点不可用,则大多数数据承载节点不再存在。也就是说,您可以使用w:1插入,但不能使用w:mostute,并且您将无法执行多数读取

    每次使用更改流多数读取关注点:

    禁用“多数”读关注将禁用对MongoDB 4.0及更早版本的更改流的支持。对于MongoDB 4.2+,禁用读关注点“多数”对变更流可用性没有影响

    这也隐含在给定的

    总订单

    MongoDB 3.6有一个全局逻辑时钟,使服务器能够在分片集群中对所有更改进行排序。应用程序将始终按照应用于数据库的顺序接收更改

    只有在多数读取的情况下才能进行总排序

    如果希望更改流在其中一个数据承载节点不可用时继续生成事件,请使用PSS体系结构


    您也可以尝试禁用4.2+上的读关注多数,但这还有第一个链接中所述的其他问题。

    对于PSA体系结构,如果任一数据承载节点不可用,则大多数数据承载节点不再存在。也就是说,您可以使用w:1插入,但不能使用w:mostute,并且您将无法执行多数读取

    每次使用更改流多数读取关注点:

    禁用“多数”读关注将禁用对MongoDB 4.0及更早版本的更改流的支持。对于MongoDB 4.2+,禁用读关注点“多数”对变更流可用性没有影响

    这也隐含在给定的

    总订单

    MongoDB 3.6有一个全局逻辑时钟,使服务器能够在分片集群中对所有更改进行排序。应用程序将始终按照应用于数据库的顺序接收更改

    只有在多数读取的情况下才能进行总排序

    如果希望更改流在其中一个数据承载节点不可用时继续生成事件,请使用PSS体系结构


    您也可以尝试在4.2+上禁用read concern多数,但这还有第一个链接中所述的其他问题。

    您是否可以包括
    rs.conf()的输出。成员
    并锁定
    日志
    文件中包含
    s:“F”
    的任何条目您是否可以包括
    rs.conf()的输出.members
    并锁定
    日志
    文件中包含
    s:“F”
    的任何条目。我理解您关注的是“WriteConcern”参数,但在我的副本集中,通过读取rs.conf()文件(我刚刚在答案中包含),您可以看到该参数等于1。流无论如何都不工作。。。。你怎么解释呢?尽管如此,如果我禁用ReadConcernMaster,当其中一个数据承载节点发生故障时,我会得到一个MongoExecutionTimeoutException(我关于please的问题)。我不明白我错在哪里…读关注点,而不是写关注点。用所有相关信息更新此问题,而不是创建重复的问题。我理解您关注的是“WriteConcern”参数,但在我的副本集中,通过阅读rs.conf()文件(我刚刚在答案中包含了该文件),您可以看到,该参数等于1。流无论如何都不工作。。。。你怎么解释呢?尽管如此,如果我禁用ReadConcernMaster,当其中一个数据承载节点发生故障时,我会