mongodb - 在 MongoDB 副本集中读取自己的写入。随意的一致性不起作用?
问题描述
我在一个 3 成员副本集中使用 mongodb,试图读取我自己的写入。然而,我似乎从我的阅读中得到了陈旧的数据。根据文档,通过“多数”问题进行读/写,它应该保证:
“读操作反映了它们之前的写操作的结果。”
2018年的这篇文章中也有同样的说法:
具有读取关注多数的因果读取 R1 等待看到 T1 多数已提交,然后返回成功。
然而,我似乎没有这么幸运。下面的代码插入一个用户,并立即尝试通过 ID 找到同一用户。这是在一个循环中完成的,只需要 1-3 次迭代,它就会因“找不到用户”而失败。
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");
}
}
我已经为读/写指定了“多数”问题。为了测试,我将“次要”指定为阅读偏好。如果我将“Primary”指定为读取首选项,这将永远不会失败(显然)。
我究竟做错了什么?
解决方案
首先,您的链接中描述的因果一致性需要在会话中执行操作。我没有在您的代码中看到会话使用。
其次,大多数阅读关注意味着:
读取关注“多数”保证读取的数据已被大多数副本集成员确认(即读取的文档是持久的并且保证不会回滚)。
这并不能保证返回的数据是文档的最新版本。如果您正在执行辅助读取,您将获得截至该辅助节点的集群时间提交给大多数节点的数据,这可能落后于主节点的集群时间。
根据this note,您需要一个会话来获得与大多数阅读关注点的因果一致性。
推荐阅读
- javascript - 如何将我的域名扩展名从cars.net 更改为cars.com?
- macos - NSSavePanel“字符串”?
- javascript - Video.js - 如何向 video.js 播放器添加多个音轨?
- php - 如何通过按钮从列表中传递变量
- php - 将新的 XML 数据插入 XML 的特定位置
- python - Twitter API:使用 Python 抓取可用于地理参考推文的数据
- python - 为什么函数里面的client会报错?
- python - 查找特定字符串的行并在该行之后读取文本文件
- swiftui - 在 SwiftUI 中的行之间均匀分布换行文本
- exec - 打开管道进行写入时程序堆栈