/** * LOAD BALANCING */ private void LoadBalancing() { if (fail) { return; } if (!ImMaster) { return; } HashSet <string> alreadyMigrated = new HashSet <string>(); foreach (DataServerFile file in dataServers.FileWeights) { string localFilename = file.LocalFilename; string filename = fileTable.FilenameByLocalFilename(localFilename); Weight fileWeight = file.Weight; string oldDataServerId = file.DataServerId; Weight oldDataServerWeight = dataServers.Weight(oldDataServerId); Weight avgWeight = dataServers.AvgWeight; // if the file has no reads or writes if (Weight.Empty(fileWeight)) { continue; } // if data server is already balanced if (Weight.BelowThreshold(oldDataServerWeight, avgWeight, Helper.LOAD_BALANCING_THRESHOLD)) { continue; } foreach (var entry in dataServers.Weights) { string newDataServerId = entry.Key; Weight newDataServerWeight = entry.Value; // BLACK LIST SKIP CASES // skips if its the old dataServer if (newDataServerId == oldDataServerId) { continue; } // migrates just one file per data server if (alreadyMigrated.Contains(newDataServerId)) { continue; } // if file already is in dataserver if (fileTable.FileInDataServer(filename, newDataServerId)) { continue; } // if data server is known to be down if (dataServers.Failed(newDataServerId)) { continue; } // if the data server is already overweight if (Weight.AboveThreshold(newDataServerWeight, avgWeight, Helper.LOAD_BALANCING_THRESHOLD)) { continue; } // if placing the new file would put that server above threshold if (Weight.AboveThreshold(fileWeight + newDataServerWeight, avgWeight, Helper.LOAD_BALANCING_THRESHOLD)) { continue; } // if it isnt free if (!fileTable.Free(filename)) { continue; } // LOCK fileTable.Lock(filename); // reads from old, writes to new string newLocalFilename = LocalFilename(filename, newDataServerId); string oldLocalFilename = fileTable.LocalFilenameByFilename(filename, oldDataServerId); // if swap was false migration failed bool swaped = SwapDataServers(oldDataServerId, newDataServerId, oldLocalFilename, newLocalFilename, fileWeight); if (swaped) { Console.WriteLine("MIGRATE " + filename + " TO " + newDataServerId); // log operation int sequence = clock++; log.LogOperation(sequence, "MigrateFileOnMetadata", filename, oldDataServerId, newDataServerId, oldLocalFilename, newLocalFilename, sequence); // swap files on data server register dataServers.AddFile(newDataServerId, newLocalFilename); dataServers.RemoveFile(oldDataServerId, oldLocalFilename); // swaps data servers on file table fileTable.RemoveDataServer(filename, oldDataServerId); fileTable.AddDataServer(filename, newDataServerId, dataServers.Location(newDataServerId), newLocalFilename); // migrate to metadatas MigrateFileOnMetadatas(filename, oldDataServerId, newDataServerId, oldLocalFilename, newLocalFilename, sequence); // adds file weight to data server weight and removes from previous dataServers.AddWeight(newDataServerId, fileWeight); dataServers.RemoveWeight(oldDataServerId, fileWeight); // adds to data servers already migrated alreadyMigrated.Add(newDataServerId); } // UNLOCK fileTable.Unlock(filename); // if migration occured breaks this data server loop file if (swaped) { break; } } } }