When a MongoDB instance gets into a Rollback state, and the rollback data is greater than 300MB of data, you have to manually intervene. It will stay in a rollback state until you take action to save/remove/move that data, the (now secondary) should then be resynced to bring it back in line with the primary. This does not have to be a full resync, but that is the simplest way.
Multiple rollbacks are a symptom rather than the cause of a problem. Rollback only happens when a secondary that was not in sync (either due to lag or an issue with replication) becomes primary and takes writes. So, the problems that cause that to happen in the first place are what need to be taken care of - the rollback itself is something you need to deal with as an admin - there are too many potential pitfalls for MongoDB to reconcile the data automatically.
If you want to simulate this again for testing purposes, I have outlined how to do so here:
http://comerford.cc/2012/05/28/simulating-rollback-on-mongodb/
Eventually, this data will be stored in a collection (in the local DB) rather than dumped to disk, which will present opportunities to deal with it more effectively:
https://jira.mongodb.org/browse/SERVER-4375
At the moment though, once a rollback occurs, as you found, manual intervention is required.
Finally, the manual contains similar information to Kristina's blog now:
https://docs.mongodb.com/manual/core/replica-set-rollbacks
I'm not sure what documentation you've read so apologies if I'm repeating anything here.
To distribute reads to secondary nodes, most drivers allow you to set a readPreference value for the current session. Clients set read preference on a per-connection basis. With slaveOk, the driver should will always send queries to the secondaries, if they're available.
Distributing reads to secondaries requires the use of
ReplicaSetConnection with ReadPreference.SECONDARY.
See “rs.slaveOk()” for more information and this link.
In the mongo shell, to enable secondary reads, issue the following command :
rs.slaveOk()
The PHP documentation for it is here but I'm guessing that may be the documentation you're referring to.
As a FYI, here's an old discussion about it on the MongoDB Google Group.
If you're still having issues, I'd recommend using the MongoDB Google Group and providing some further information such as the version of MongoDB you're using, the version of the PHP driver, your log files, rs.conf() and rs.status().
As a FYI, you have to be careful with read scaling as sending too many reads to the secondaries can often result in the secondaries lagging the primary and becoming stale, thus requiring a full resync.
Best Answer
If you are using sharding, then the "load balancer" is the mongos process - actually it is more like a router - it keeps an in-memory copy of the config database and can make decisions based on the shard key.
If you mean load balancing across identical replica sets or across the members of the set, then there is a feature request to have mongos handle that scenario too (https://jira.mongodb.org/browse/SERVER-1594), however given how the drivers operate it is not really necessary (it would make the drivers less complex though).
In a single replica set, you cannot distribute writes, they all must go to the primary. You can distribute reads to the secondaries already, via Read Preferences as you deem appropriate. The driver keeps track of what is a primary and what is a secondary and routes queries appropriately.