def balance(self): ############################################ ## HOTSPOT DETECTOR ######################## ############################################ k = 20 self.check_hostpost(k) ############################################ ## MIGRATION MANAGER ####################### ############################################ # Calculate volumes of each node nodes = [] domains = [] for node in self.model.get_hosts(): volume = 1.0 / max(0.001, float(100.0 - node.percentile_load(PERCENTILE, k)) / 100.0) node.volume = volume node.volume_size = volume / 8.0 # 8 GByte if node.type == types.NODE: nodes.append(node) elif node.type == types.DOMAIN: domains.append(node) # Sort nodes to their volume in DECREASING order # Multiplication with a big value to shift post comma digits to the front (integer) nodes.sort(lambda a, b: int((b.volume - a.volume) * 100000)) ############################################ ## MIGRATION TRIGGER ####################### ############################################ time_now = self.pump.sim_time() sleep_time = 60 for node in nodes: node.dump() try: # Overload situation if node.overloaded: print 'Overload...' self.migration_trigger(True, nodes, node, k, sleep_time, time_now) except StopIteration: pass # Balance system print 'Imbalance...' # self.check_imbalance(time_now, sleep_time, k) try: # Underload situation if node.underloaded: print 'Underload...' self.migration_trigger(False, nodes, node, k, sleep_time, time_now) except StopIteration: pass
def balance(self): ############################################ ## HOTSPOT DETECTOR ######################## ############################################ for node in self.model.get_hosts(types.NODE): # Check past readings readings = node.get_readings() # m out of the k last measurements are used to detect overloads k = K_VALUE overload = 0 underload = 0 for reading in readings[-k:]: if reading > THRESHOLD_OVERLOAD: overload += 1 if reading < THRESHOLD_UNDERLOAD: underload += 1 m = M_VALUE overload = (overload >= m) underload = (underload >= m) if overload: print 'Overload in %s - %s' % (node.name, readings[-k:]) # Update overload node.overloaded = overload node.underloaded = underload ############################################ ## MIGRATION MANAGER ####################### ############################################ # Calculate volumes of each node nodes = [] domains = [] for node in self.model.get_hosts(): volume = 1.0 / max(0.001, float(100.0 - node.percentile_load(PERCENTILE, k)) / 100.0) node.volume = volume node.volume_size = volume / 8.0 # 8 GByte if node.type == types.NODE: nodes.append(node) elif node.type == types.DOMAIN: domains.append(node) # Sort nodes to their volume in DECREASING order # Multiplication with a big value to shift post comma digits to the front (integer) nodes.sort(lambda a, b: int((b.volume - a.volume) * 100000)) ############################################ ## MIGRATION TRIGGER ####################### ############################################ time_now = self.pump.sim_time() sleep_time = 60 for node in nodes: node.dump() try: # Overload situation if node.overloaded: # Source node to migrate from source = node # Sort domains by their VSR value in decreasing order node_domains = [] node_domains.extend(node.domains.values()) node_domains.sort(lambda a, b: int(b.volume_size - a.volume_size)) # Try to migrate all domains by decreasing VSR value for domain in node_domains: # Try all targets for the migration (reversed - starting at the BOTTOM) for target in reversed(range(nodes.index(node) + 1, len(nodes))): target = nodes[target] if len(target.domains) == 0: # print 'skip %s - %s' % (target.name, target.domains) continue domain_cpu_factor = target.cpu_cores / domain.cpu_cores test = True test &= (target.percentile_load(PERCENTILE, k) + domain.percentile_load(PERCENTILE, k) / domain_cpu_factor) < THRESHOLD_OVERLOAD # Overload threshold test &= len(target.domains) < 6 test &= (time_now - target.blocked) > sleep_time test &= (time_now - source.blocked) > sleep_time if test: print 'Overload migration: %s from %s to %s' % (domain.name, source.name, target.name) self.migrate(domain, source, target) raise StopIteration() for target in reversed(range(nodes.index(node) + 1, len(nodes))): target = nodes[target] domain_cpu_factor = target.cpu_cores / domain.cpu_cores test = True test &= (target.percentile_load(PERCENTILE, k) + domain.percentile_load(PERCENTILE, k) / domain_cpu_factor) < THRESHOLD_OVERLOAD # Overload threshold test &= len(target.domains) < 6 test &= (time_now - target.blocked) > sleep_time test &= (time_now - source.blocked) > sleep_time if test: print 'Overload migration (Empty): %s from %s to %s' % (domain.name, source.name, target.name) self.migrate(domain, source, target) raise StopIteration() except StopIteration: pass try: # Underload situation if node.underloaded: # Source node to migrate from source = node # Sort domains by their VSR value in decreasing order node_domains = [] node_domains.extend(node.domains.values()) node_domains.sort(lambda a, b: int(b.volume_size - a.volume_size)) # Try to migrate all domains by decreasing VSR value for domain in node_domains: # Try all targets for the migration for target in range(nodes.index(node) - 1): target = nodes[target] if len(target.domains) == 0: continue domain_cpu_factor = target.cpu_cores / domain.cpu_cores test = True test &= (target.percentile_load(PERCENTILE, k) + domain.percentile_load(PERCENTILE, k) / domain_cpu_factor) < THRESHOLD_OVERLOAD # Overload threshold test &= len(target.domains) < 6 test &= (time_now - target.blocked) > sleep_time test &= (time_now - source.blocked) > sleep_time if test: print 'Underload migration: %s from %s to %s' % (domain.name, source.name, target.name) self.migrate(domain, source, target) raise StopIteration() for target in range(nodes.index(node) - 1): target = nodes[target] domain_cpu_factor = target.cpu_cores / domain.cpu_cores test = True test &= (target.percentile_load(PERCENTILE, k) + domain.percentile_load(PERCENTILE, k) / domain_cpu_factor) < THRESHOLD_OVERLOAD # Overload threshold test &= len(target.domains) < 6 test &= (time_now - target.blocked) > sleep_time test &= (time_now - source.blocked) > sleep_time if test: print 'Underload migration (Empty): %s from %s to %s' % (domain.name, source.name, target.name) self.migrate(domain, source, target) raise StopIteration() except StopIteration: pass