我第一次尝试了 mongo 副本集。
我在 ec2 上使用 ubuntu 并启动了三个实例。我使用了每个实例的私有 IP 地址。我选择了主要的,下面是代码。
mongo --host Private IP Address
rs.initiate()
rs.add(“Private IP Address”)
rs.addArb(“Private IP Address”)
在这一点上一切都很好。当我访问 http://ec2-xxx-xxx-xxx-xxx.compute-1.amazonaws.com:28017/_replSet 站点时,我看到我有一个主要、次要和仲裁者。
好的,现在进行测试。
在主要创建数据库时,代码如下:
use tt
db.tt.save( { a : 123 } )
在二级上,然后我这样做并得到以下错误:
db.tt.find()
error: { "$err" : "not master and slaveOk=false", "code" : 13435 }
我对 mongodb 和复制非常陌生,但我认为如果我在一个中做某事,它会转到另一个。那么,如果我在一个记录中添加一条记录,我必须做什么才能跨机器复制?
您必须设置“辅助好的”模式以让 mongo shell 知道您允许从辅助读取。这是为了保护您和您的应用程序不会意外执行最终一致的读取。您可以在 shell 中执行此操作:
rs.secondaryOk()
之后,您可以从辅助节点正常查询。
关于“最终一致性”的说明:在正常情况下,副本集辅助节点在一秒或更短的时间内拥有与主节点相同的所有数据。在非常高的负载下,您写入主服务器的数据可能需要一段时间才能复制到辅助服务器。这被称为“副本滞后”,从滞后的辅助读取被称为“最终一致”的读取,因为虽然新写入的数据会在某个时候出现(除非网络故障等),但它可能不会立即可用。
编辑:您只需要在从辅助节点查询时设置 secondaryOk
,并且每个会话只需设置一次。
要避免每次都输入 rs.slaveOk()
,请执行以下操作:
创建一个名为 replStart.js
的文件,其中包含一行:rs.slaveOk()
然后在您启动 Mongo shell 时包含 --shell replStart.js
。当然,如果您在本地连接到单个实例,这不会节省任何输入。
rs.slaveOk()
添加到您的 ~/.mongorc.js
文件中,该文件将在启动 mongo shell 时自动执行。
~/.mongorc.js
中并将自定义配置放在 replStart.js
或 adminStart.js
或其他任何内容中很有用。
在mongodb2.0
你应该输入
rs.slaveOk()
在辅助 mongod 节点中
这只是给使用 Ruby 驱动程序处理此问题的任何人的注意事项
我在使用 Ruby Gem 时遇到了同样的问题。
要在 Ruby 中设置 slaveOk,您只需在创建客户端时将其作为参数传递,如下所示:
mongo_client = MongoClient.new("localhost", 27017, { slave_ok: true })
https://github.com/mongodb/mongo-ruby-driver/wiki/Tutorial#making-a-connection
mongo_client = MongoClient.new # (optional host/port args)
请注意,“args”是第三个可选参数。
我到这里搜索相同的错误,但来自 Node.js native driver。我的答案是 campeterson 和 Prabhat 的答案组合。
问题是 readPreference
设置默认为 primary
,然后以某种方式导致令人困惑的 slaveOk
错误。我的问题是我只想从任何节点读取我的副本集。我什至没有连接到它作为副本集。我只是连接到任何节点以从中读取。
将 readPreference
设置为 primaryPreferred
(或更好地设置为 ReadPreference.PRIMARY_PREFERRED
常量)为我解决了这个问题。只需将其作为选项传递给 MongoClient.connect()
或 client.db()
或任何 find()
、aggregate()
或其他函数。
https://docs.mongodb.com/v3.0/reference/read-preference/#primaryPreferred
http://mongodb.github.io/node-mongodb-native/3.6/api/Collection.html(搜索readPreference)
const { MongoClient, ReadPreference } = require('mongodb');
const client = await MongoClient.connect(MONGODB_CONNECTIONSTRING, { readPreference: ReadPreference.PRIMARY_PREFERRED });
警告:slaveOk() 已弃用,可能会在下一个主要版本中删除。请改用secondaryOk()。 rs.secondaryOk()
slaveOk 不再起作用了。需要使用 readPreference https://docs.mongodb.com/v3.0/reference/read-preference/#primaryPreferred
例如
const client = new MongoClient(mongoURL + "?readPreference=primaryPreferred", { useUnifiedTopology: true, useNewUrlParser: true });
我只是为数据库提供商的尴尬情况添加了这个答案。
在我们的案例中发生的事情是主数据库和辅助数据库反向移动(主要到辅助,反之亦然),我们得到了同样的错误。
因此,请检查数据库状态的配置设置,这可能会对您有所帮助。
将 readPreference 添加为 PRIMARY
const { MongoClient, ReadPreference } = require('mongodb');
const client = new MongoClient(url, { readPreference: ReadPreference.PRIMARY_PREFERRED});
client.connect();
slaveOk()
已弃用,可能会在下一个主要版本中删除。请改用secondaryOk()
。