Html "> in a previous article, we introduced the mongos startup process. At the end of the article, we introduced how mongos uses balancer for balancing, let's continue with the implementation method today.
First, let's take a look at the class diagram of Balancer and related implementation policies:
You can see that the Balancer class contains a BalancerPolicy pointing to a balancing policy, which searches for and collects chunks to be migrated.
Here, let's take a look at the class definition of Balancer, as follows:
// Balace. h
Class Balancer: public BackgroundJob {
Public:
Balancer ();
Virtual ~ Balancer ();
// BackgroundJob methods
Virtual void run ();
Virtual string name () const {return "Balancer ";}
Private:
Typedef BalancerPolicy: ChunkInfo CandidateChunk;
Typedef shared_ptr <CandidateChunk> CandidateChunkPtr;
// Mongos name (hostname: port)
String _ myid;
// Balancer Start Time
Time_t _ started;
// Number of chunks to be moved forward
Int _ balancedLastTime;
// Balance policy (determine the chunks to be migrated)
BalancerPolicy * _ policy;
// Initialize and check whether the balancer can be linked to the servers. This method may throw a network exception.
Bool _ init ();
/**
* Collect information about shards and chunks that may need to be migrated
* @ Param conn: Point to config server (s) Connection
* @ Param candidateChunks (IN/OUT): chunks that may need to be migrated
*/
Void _ doBalanceRound (DBClientBase & conn, vector <CandidateChunkPtr> * candidateChunks );
/**
* Migrate chunk one by one and return the number of chunks for the final migration
* @ Param candidateChunks the chunks that may need to be migrated
* @ Return number of chunks implements tively moved
*/
Int _ moveChunks (const vector <CandidateChunkPtr> * candidateChunks );
/* Mark the balancer as active in config server (s .*/
Void _ ping (DBClientBase & conn );
// Returns true if all configdb services are available.
Bool _ checkOIDs ();
};
It can be seen that the balancer inherits from the BackgroundJob, so it runs in the background mode. After learning about the methods and attributes of this class, let's take a look at the calling process of starting balancer. go () in the main mongos function. Because the balancer inherits from the BackgroundJob, you need to take a look at the Execution Code of the go () method in the BackgroundJob, as follows:
// Run the following jobBody method in the background. cpp thread mode
BackgroundJob & BackgroundJob: go (){
Boost: thread t (boost: bind (& BackgroundJob: jobBody, this, _ status ));
Return * this;
}
/// Background. cpp. Background object can be only destroyed after jobBody () ran
Void BackgroundJob: jobBody (boost: shared_ptr <JobStatus> status ){
....
Const string threadName = name ();
If (! ThreadName. empty ())
SetThreadName (threadName. c_str ());
Try {
Run (); // here, mongos starts to execute the run method in the sub-class balancer.
}
....
If (status-> deleteSelf)
Delete this;
}
The above code will eventually convert the execution process to the run () method of the balancer class, as follows:
Void Balancer: run (){
/* This is the body of a BackgroundJob so if we throw
Here were basically ending the balancer thread prematurely */
While (! InShutdown ()){
If (! _ Init () {// check whether the balancer is linked to config server and other shard
Log () <"will retry to initialize balancer in one minute" <endl;
Sleepsecs (60 );
Continue;
}
Break;
}
// Construct the link string Information
ConnectionString config = configServer. getConnectionString ();
// Declare a Distributed Lock
DistributedLock balanceLock (config, "balancer ");
While (! InShutdown () {// loop until the program is interrupted or closed
Try {
// Determine whether the chunk balancing function is effective
If (! Grid. shouldBalance ()){
Log (1) <"skipping balancing round because balancing is disabled" <endl;
Sleepsecs (30 );
Continue;
}
& Nbs