mongodb not using local database in replica set - mongodb

I have 4 servers each hosting a website and a mongo replica set.
MongoDB version: v3.4.13
Driver: PHP
Server 1 is PRIMARY.
Located on the west coast
Server 2 is SECONDARY with tag: { location: 'east' }
Located on the east coast
I'm connecting to the db with connection string: mongodb://localhost:27017/?replicaSet=rs&readPreference=nearest&readPreferenceTags=location:east
Server 3 and 4 are SECONDARY with no tags.
I want server 2 to read from it's local database, but instead it is reading from primary (or another secondary, I can't tell, but it's definitely not reading from it's local database)
I suspect it's not reading from it's own SECONDARY db because there is about a 3 second lag for any query I run.
How can I tell server 2 to read from it's own local SECONDARY db?

Include readPreferenceTags in your connection string. Refer to the online doc.
By the way, you shouldn't have a even number of nodes in a replica set unless one of them has no voting right.

SOLUTION: All servers within the cluster need to be able to connect to all other servers within the cluster.
Turns out, some of my secondary's weren't able to connect to the other secondary's because of some rules placed in my iptables.
Once all servers within the cluster were able to connect to each other the speed increased dramatically.

Related

Mongo Replica Endpoint

I have some questions about the mongo replica
mongo replica
If I make 1 primary and 2 secondary MongoDB for replication. So I have 3 endpoints to 3 different DB and my apps can only write on primary DB. what if suddenly my primary shutdown and secondary DB take over the primary. Then how to automatically change the endpoint in my apps? should I use mongos (mongo routes)? but it needs sharding if I remember correctly.
Thank you.
All nodes in a replica set work together to have identical data. Secondary nodes may lag behind the primary, but you don't get "3 different DB". There is only one database of which copies exist on each node.
All MongoDB drivers know to monitor replica set members and discover which is the primary one automatically. You need to configure some drivers to do so by providing the replica set name, others do it automatically by default when they connect to a replica set node. Look up "connecting to replica set" in your driver documentation.
In a proper connection string you will provide all three RS members, e.g.
mongodb://mongodb0.example.com:27017,mongodb1.example.com:27017,mongodb2.example.com:27017/?replicaSet=myRepl
The client will detect the PRIMARY and will use it. I guess, most drivers will re-connect automatically if the PRIMARY node changes.
Most drivers will detect the PRIMARY automatically if you provide the ReplicaSet name, i.e.
mongodb://mongodb0.example.com:27017/?replicaSet=myRepl
would connect to the PRIMARY even if it is not mongodb0.example.com. However, if mongodb0.example.com does not run, then you don't connect at all. So, it is beneficial to provide all ReplicaSet members in the connection string.
See Connection String URI Format
mongos is needed only to connect to a Sharded Cluster.

MongoDB replica set - virtual IP , downtime questions

I have 3 questions regarding a replica set on mongodb on windows:
I currently have a standalone running with data on it, if I create a replica set (adding 2 secondries) will I have a downtime or I can create the replica set and adding 2 secondries while the standalone (now the primary) still running?
Will the 2 secondries copy all the data from the primary? Also data that was written to standalone before it became part of replica set?
Once there is an election a secondry become a primary but then it means the primary is on differnt IP + Port, this means I also need to change my write to the new primary by myself or mongodb doing it by himself? or need to use virtual ip?
Have a look at Convert a Standalone to a Replica Set.
You need to change the configuration file and restart the MongoDB, so you have a downtime of your MongoDB.
Yes, whenever you add a new member to a replica set then MonogDB performs a Initial Sync to the new secondary
You would need to change your connection, see Connect to a MongoDB Replica Set. The connection string contains all replica set members and the client will connect (by default) to the primary.
Actually you don't have to put all replica set members in your connection string, the client will discover them automatically. However, if you put only one member and by chance this member is down then you have no connection.

Setting up mongo replication in production

How do you setup mongodb replication in production environments? I started using cloud formation with this template but it crashes half way. I want to setup mongo so that it has one primary and two replications.
I haven't found a good tutorial for how to setup Mongo replication.
Some other questions I have are:
How does the failover work, if I have three Ec2 instances each with mongo and the primary fails. Another instance becomes the primary but how does my client PyMongo and Scala Mongo know the IP address of the new primary.
Lets say the primary goes down for 1 hour and there are 2,000 writes. When it goes back up, how does the primary gets updated. Do I need a script for this?
I am trying to do this with flask PyMongo
I ended up testing this on my local machine here is what I found.
Failover is done by the client, in the Mongo URI you specify all your replications and when PyMongo connects to it. He checks to see which one is the primary and writes to that one.
When the database goes back up they all sync to match the same records in the all the databases.
Readthedocs has step by step manual on setting up MongoDB cluster on different platforms, including AWS EC2:
https://mongodb-documentation.readthedocs.io/en/latest/ecosystem/tutorial/install-mongodb-on-amazon-ec2.html#deploy-a-multi-node-replica-set
To provide your clients with working mongo instance you can employ several different strategies. For example:
Set up Route53 failover. Route53 will monitor health instance of primary node, and change DNS record to point to secondary in case of failure.
Use service discovery. Consul, etc, ZooKeeper and doozerd are worth exploring.
In case of failing and then coming back a mongodb node will receive latest data from other nodes — that's just what replica set does.

MongoDB replica with Offline Database

I would like to have Mongo on a server, then to replicate this onto a laptop.
The laptop is needed to leave the network and still be able to read/write, and once back on the network sync these changes with the primary.
At the same time I need the VM (Primary), to still be accessible (read/write).
So when each device is not talking to each other then for them to make themselves primary.
I have set up a very basic replica, Primary on a VM and the Secondary on the machine running the VM. In all examples I have seen it recommends having 3 servers for the replica, but I only need 2!
A couple of questions:
Is this possible with Mongo? If not then any suggestions!
When I turn off the Network adapter on the VM(Primary), the secondary doesn't seem to want to become the primary.
Is it possible to run 2 instance of Mongo, and then use the other instance as the 3 member of the replica.
Any advice would be great, thanks.
MongoDB always needs even number servers. in your case it should be like one primary one secondary and one arbiter. arbiter server instance is responsible for electing new server as primary when current primary goes down.

Can I keep two mongo databases synced?

I have an app that can run in offline mode. If offline it uses a local mongo database, if it has a data connection it will use a remote mongo database.
Is there an easy way to sync these two databases and make sure they both have the union of their collections and documents?
EDIT: Effectively there are two databases that could both have insertions and deletions happening on them that aren't happening on the other. At fixed points in time I would like to have both databases show the union of them both.
For example over a period of time.
DB1.insert(A)
DB1.insert(B)
DB2.insert(C)
DB1.remove(A)
RUN SYNC
DB1 = DB2 = {B, C}
EDIT2: Been doing some reading. It's not the intended purpose but could they be set up as slaves replica sets of the remote and used that way? Problem is that I think replicas need to have a replica hosts must be accessible by way of resolvable DNS. Not sure how the remote could access local host.
You could use replica set but MongoDB doesn’t support master-master replication. Let's assume if you have setup like this:
two nodes with priority 1 which will be used as remote servers
single arbiter to ensure majority if one of remotes dies
5 local dbs with priority set as 0
When your application goes offline, it will stay secondary so you won't be able to perform writes. When you go online it will sync changes from remote dbs but you still need some way of syncing local changes. One of dealing with could be using local fallback db which will be used for writes when you are offline. When you go online, you push all new records to master. A little bit trickier could be dealing with updates but it is doable.
Another problem is that it won't scale up if you'll need to add more applications. If I remember correctly, there is a 12 nodes per replica set limit. For small cluster DNS resolution could be solved by using ssh tunnels.
Another way of dealing with a problem could be using small restful service and document timestamps. Whenever app is online it can periodically push local inserts to remote and pull data from remote db.