在 MongoDB 副本集中读取自己的写入。随意一致性不起作用?
Read own writes in a MongoDB replicaset. Casual consistency not working?
我在 3 成员副本集中使用 mongodb,试图读取我自己的写入。但是,我似乎从我的读取中得到了过时的数据。根据 documentation,通过 read/write 和 "majority" 关注,它应该保证:
"Read operations reflect the results of write operations that precede them."
从 2018 年开始,this post 中也有同样的说法:
The causal read R1 with read concern majority waits to see T1 majority committed before returning success.
不过,我好像没那么幸运。下面的代码插入一个用户并立即尝试通过 ID 找到同一用户。这是在一个循环中完成的,在失败之前只需要 1-3 次迭代 "User not found".
IMongoCollection<User> collection = MongoDatabase.GetCollection<User>("UserCollection")
.WithReadConcern(ReadConcern.Majority)
.WithWriteConcern(WriteConcern.WMajority)
.WithReadPreference(ReadPreference.Secondary);
Random rnd = new Random();
while (true)
{
User newUser = new User
{
Email = $"{rnd.Next(int.MinValue, int.MaxValue)}@gg.com"
};
collection.InsertOne(newUser);
if (newUser.Id == ObjectId.Empty)
{
throw new Exception("Id is empty");
}
var findFluent = collection.Find(Builders<User>.Filter.Eq(x => x.Id, newUser.Id));
User foundUser = findFluent.FirstOrDefault();
if (foundUser == null)
{
throw new Exception("User not found");
}
}
我已经为 read/write 指定了 "Majority" 问题。为了测试这一点,我将 "Secondary" 指定为阅读首选项。如果我将 "Primary" 指定为读取首选项,这将永远不会失败(显然)。
我做错了什么?
首先,your link中描述的因果一致性需要在会话中执行操作。我没有在您的代码中看到会话使用。
其次,majority read concern 的意思是:
read concern "majority" guarantees that the data read has been acknowledged by a majority of the replica set members (i.e. the documents read are durable and guaranteed not to roll back).
这不能保证返回的数据是文档的最新版本。如果您正在进行辅助读取,您将获得截至该辅助节点的集群时间提交给大多数节点的数据,这可能滞后于主节点的集群时间。
根据 this note 你需要一个会话来获得与大多数阅读关注的因果一致性。
我在 3 成员副本集中使用 mongodb,试图读取我自己的写入。但是,我似乎从我的读取中得到了过时的数据。根据 documentation,通过 read/write 和 "majority" 关注,它应该保证:
"Read operations reflect the results of write operations that precede them."
从 2018 年开始,this post 中也有同样的说法:
The causal read R1 with read concern majority waits to see T1 majority committed before returning success.
不过,我好像没那么幸运。下面的代码插入一个用户并立即尝试通过 ID 找到同一用户。这是在一个循环中完成的,在失败之前只需要 1-3 次迭代 "User not found".
IMongoCollection<User> collection = MongoDatabase.GetCollection<User>("UserCollection")
.WithReadConcern(ReadConcern.Majority)
.WithWriteConcern(WriteConcern.WMajority)
.WithReadPreference(ReadPreference.Secondary);
Random rnd = new Random();
while (true)
{
User newUser = new User
{
Email = $"{rnd.Next(int.MinValue, int.MaxValue)}@gg.com"
};
collection.InsertOne(newUser);
if (newUser.Id == ObjectId.Empty)
{
throw new Exception("Id is empty");
}
var findFluent = collection.Find(Builders<User>.Filter.Eq(x => x.Id, newUser.Id));
User foundUser = findFluent.FirstOrDefault();
if (foundUser == null)
{
throw new Exception("User not found");
}
}
我已经为 read/write 指定了 "Majority" 问题。为了测试这一点,我将 "Secondary" 指定为阅读首选项。如果我将 "Primary" 指定为读取首选项,这将永远不会失败(显然)。
我做错了什么?
首先,your link中描述的因果一致性需要在会话中执行操作。我没有在您的代码中看到会话使用。
其次,majority read concern 的意思是:
read concern "majority" guarantees that the data read has been acknowledged by a majority of the replica set members (i.e. the documents read are durable and guaranteed not to roll back).
这不能保证返回的数据是文档的最新版本。如果您正在进行辅助读取,您将获得截至该辅助节点的集群时间提交给大多数节点的数据,这可能滞后于主节点的集群时间。
根据 this note 你需要一个会话来获得与大多数阅读关注的因果一致性。