def test_nodes(self, active_nodes, new_domain):
        # Go over all hosts
        for node in active_nodes:
            # Get actual CPU measurements
            curr_cpu_demand = np.percentile(node.get_readings(), 95)
            
            # Memory demand is calculated by summing up all VM reservations
            curr_mem_demand = 0

            # Add up the demands of all domains running on the host              
            for old_domain in node.domains.values():
                # Domain size specification 
                spec = old_domain.domain_configuration.get_domain_spec()
                
                # Sum up mem load 
                curr_mem_demand += spec.total_memory()
            
            # Calculate metrics
            new_domain_spec = conf_domainsize.get_domain_spec(new_domain.size)
            mem_delta = conf_nodes.NODE_MEM - curr_mem_demand - new_domain_spec.total_memory()
            
            # Calculate estiated CPU demand if VM is almost
            vm_cpu_demand = conf_nodes.to_node_load(95, new_domain.size)
            cpu_delta = conf_nodes.UTIL - curr_cpu_demand - vm_cpu_demand
            
            # If metric is positive, the node can host the domain
            if cpu_delta >= 0 and mem_delta >= 0: 
                return node.name 
예제 #2
0
def __build_modified_profiles(mix):
    for handle in mix.handles:
        print 'processing modified profile %s ...' % (handle.name)
        
        # Load TS
        ts_name = wmeta.times_name(handle, wmeta.MUTATION_PNORM, mix)

        # Modify CPU normal profile     
        profile = profile_modifier.process_trace(tc.connection(), ts_name,
                                                            handle.modifier, handle.additive,
                                                            handle.scale, handle.shift)
        
        # Attach profile to handle
        handle.profile_frequency, handle.profile = profile
        
    # Store profiles
    for handle in mix.handles:
        profile = np.array(handle.profile)
        profile_frequency = handle.profile_frequency
        
        for size in xrange(conf_domainsize.count_domain_sizes()):
            size = conf_domainsize.get_domain_spec(size).max_user_demand()
            user_profile = (profile / 100.0) * size.users
            profile_frequency = profile_frequency / (wmeta.CYCLE_TIME / schedule_builder.EXPERIMENT_DURATION)
            user_profile = np.array(user_profile)
            user_profile += 5
            if not DRY_RUN:
                print 'storing modified profile %s ...' % (handle.name)
                __write_profile(wmeta.times_name(handle, wmeta.MUTATION_PUSER, mix), user_profile,
                                profile_frequency)
 def test_nodes(self, new_domain, node_list):
     host_choice = []
     for node in node_list:
         # Aggregate load for the complete host 
         cpu_load = 0
         mem_load = 0
           
         # Calculate the node utilization by accumulating all domain loads
         for dom in node.domains.values():
             spec = dom.domain_configuration.get_domain_spec()
             cpu_load += spec.total_cpu_cores()
             mem_load += spec.total_memory()
         
         # Calculate metric
         spec = conf_domainsize.get_domain_spec(new_domain.size)
         cpu_delta = conf_nodes.NODE_CPU_CORES - (cpu_load + spec.total_cpu_cores())
         mem_delta = conf_nodes.NODE_MEM - (mem_load + spec.total_memory())
         metric = cpu_delta * mem_delta
         
         # Server is not able to handle the domain
         if cpu_delta < 0 or mem_delta < 0:
             continue
         
         # Add metric to the choice list
         host_choice.append((node.name, metric))
           
     # Check if we found at least one host
     if not host_choice:
         return None
       
     # Sort host choice list
     host_choice = self.sort(host_choice, lambda x: x[1])
     
     # Pkc hte one with the lowest metric (best fit)
     return host_choice[0][0] 
예제 #4
0
def __store_profile_yarns(mix, handle, normalizing_value, profile, profile_frequency):
    # 1) RAW profile (e.g. for plotting)
    raw_profile = np.array(profile)
    if not DRY_RUN:
        __write_profile(wmeta.times_name(handle, wmeta.MUTATION_PRAW, mix), raw_profile, profile_frequency)
    
    # 2) NORMALIZED profile (normalized with the set maximum, see above) (e.g. to feed into SSAPv)
    maxval = float(normalizing_value[handle.htype.id])
    profile /= maxval
    norm_profile = np.array(profile)
    norm_profile[norm_profile > 1] = 1
    norm_profile *= 100  # Times does not support float values
    if not DRY_RUN:
        __write_profile(wmeta.times_name(handle, wmeta.MUTATION_PNORM, mix), norm_profile, profile_frequency)
    
    # 3) Store USER profiles (-> e.g. for Rain workload driver)
    
    for size in xrange(conf_domainsize.count_domain_sizes()):
        size = conf_domainsize.get_domain_spec(size).max_user_demand()
        user_profile = profile * size.users
        user_profile = np.array(user_profile)
        user_profile += 5
        user_profile_frequency = profile_frequency / (wmeta.CYCLE_TIME / schedule_builder.EXPERIMENT_DURATION)
        user_profile_name = wmeta.times_name(handle, wmeta.MUTATION_PUSER, mix, size)
        print 'FREQ - USER YARN: %s @ %f' % (user_profile_name, user_profile_frequency)
        if not DRY_RUN:
            __write_profile(user_profile_name, user_profile, user_profile_frequency)
    def test_nodes(self, new_domain, nodelist):
        norms = []
        for node in nodelist: 
            # Aggregate load for the complete host 
            mem_load = 0
              
            for dom in node.domains.values():
                spec = dom.domain_configuration.get_domain_spec()
                mem_load += spec.total_memory()
            
            # Get actual CPU measurements
            curr_cpu_demand = np.percentile(node.get_readings(), 95)
            resd_cpu = conf_nodes.UTIL - curr_cpu_demand
            
            # Calculate residual vector
            resd_mem = conf_nodes.NODE_MEM - mem_load
            
            # VM resource demand
            spec = conf_domainsize.get_domain_spec(new_domain.size)

            # Calculate estiated CPU demand if VM is almost
            domain_cpu_demand = conf_nodes.to_node_load(95, new_domain.size)
            domain_mem_demand = spec.total_memory()
            
            # Calculate the norm
            norm = 1 * math.pow(domain_cpu_demand - resd_cpu, 2) + 1 * math.pow(domain_mem_demand - resd_mem, 2)

            # Check if this host is able to handle the new domain
            cpu_delta = resd_cpu - domain_cpu_demand
            mem_delta = resd_mem - domain_mem_demand
            if cpu_delta >= 0 and mem_delta >= 0:
                norms.append((node, norm, curr_cpu_demand, mem_load))
            else:
                print 'failed for node %s - status: %i mem %i cpu' % (node.name, mem_delta, cpu_delta)
            
        # Find the node with the lowest norm that is able to host the domain
        norms.sort(key=lambda x: x[1])
        spec = conf_domainsize.get_domain_spec(new_domain.size)
        for norm in norms: 
            # Node found 
            return norm[0].name
 def __check_capacity(self, host, domain):
     # Calculate total demand of all active domains running on selected node
     cpu_demand = 0
     mem_demand = 0
             
     for active_domain in host.domains.values():
         active_domain_configuration = active_domain.domain_configuration
         active_domain_spec = domainsize.get_domain_spec(active_domain_configuration.size)
         
         cpu_demand += active_domain_spec.total_cpu_cores()
         mem_demand += active_domain_spec.total_memory()
         
     # Domain specification of the new domain to place
     domain_spec = domainsize.get_domain_spec(domain.size)
         
     # Calculate residual capacity
     cpu_demand = nodes.NODE_CPU_CORES - domain_spec.total_cpu_cores() - cpu_demand
     mem_demand = nodes.NODE_MEM - domain_spec.total_memory() - mem_demand
     
     # Get new node if current one is overloaded
     return cpu_demand >= 0 and mem_demand >= 0
    def placement(self, domain):
        # Get list of inactive nodes
        inactive_nodes = self.__get_inactive_nodes()
        
        # Set initial active node
        if self.active_node is None:
            self.active_node = inactive_nodes.pop()

        # Domain specification of the new domain to place
        domain_spec = domainsize.get_domain_spec(domain.size)
        
        # Calculate total demand of all active domains running on selected node
        cpu_demand = 0
        mem_demand = 0
                
        for active_domain in self.active_node.domains.values():
            active_domain_configuration = active_domain.domain_configuration
            active_domain_spec = domainsize.get_domain_spec(active_domain_configuration.size)
            
            cpu_demand += active_domain_spec.total_cpu_cores()
            mem_demand += active_domain_spec.total_memory()
            
        # Calculate residual capacity
        cpu_demand = nodes.NODE_CPU_CORES - domain_spec.total_cpu_cores() - cpu_demand
        mem_demand = nodes.NODE_MEM - domain_spec.total_memory() - mem_demand
        
        # Get new node if current one is overloaded
        if cpu_demand < 0 or mem_demand < 0:
            try:
                self.active_node = inactive_nodes.pop()
            except:
                print 'inactive nodes length: %i' % len(inactive_nodes)
                self.model.dump()
                print 'PROBLEM IN SCHEDULE ID: %i' %conf_schedule.SCHEDULE_ID 
                raise ValueError('FATAL error: No more free nodes available %i - sc %i' % (len(inactive_nodes), conf_schedule.SCHEDULE_ID))
 
        
        # Return selected node
        return self.active_node.name
    def test_nodes(self, new_domain, nodelist):
        results = []
        for node in nodelist: 
            # Aggregate load for the complete host 
            mem_load = 0
              
            for dom in node.domains.values():
                spec = dom.domain_configuration.get_domain_spec() 
                mem_load += spec.total_memory()
            
            # Get actual CPU measurements
            curr_cpu_demand = np.percentile(node.get_readings(), 95)
            resd_cpu = conf_nodes.UTIL - curr_cpu_demand
                
            # Calculate residual vector
            resd_mem = conf_nodes.NODE_MEM - mem_load
            
            # VM resource demand
            spec = conf_domainsize.get_domain_spec(new_domain.size)
            
            # Calculate estiated CPU demand if VM is almost
            domain_cpu_demand = conf_nodes.to_node_load(95, new_domain.size)
            domain_mem_demand = spec.total_memory()
            
            # Calculate the dot product
            w_cpu = w_mem = 1
            abs_res = math.sqrt(math.pow(resd_cpu, 2) + math.pow(resd_mem, 2))
            abs_vm = math.sqrt(math.pow(domain_cpu_demand, 2) + math.pow(domain_mem_demand, 2))
            dot_product = w_cpu * resd_cpu * domain_cpu_demand + w_mem * resd_mem * domain_mem_demand
            cosine = dot_product / (abs_res * abs_vm)
             
            # Check if this host is able to handle the new domain
            cpu_delta = resd_cpu - domain_cpu_demand
            mem_delta = resd_mem - domain_mem_demand
            if cpu_delta >= 0 and mem_delta >= 0:
                results.append((node, dot_product, cosine))
            else:
                print 'failed for node %s - status: %i mem %i cpu' % (node.name, mem_delta, cpu_delta)
            

        if results:
            # Get the node with the best (greatest) dot product
            results.sort(key=lambda x: x[1])
            results.reverse()
            best_dot_product = results[0][0]
                        
            # Get the node with the best (smallest) cosine
            results.sort(key=lambda x: x[2])
            best_cosine = results[0][0]
            
            return (best_dot_product.name, best_cosine.name)
    def test_nodes(self, new_domain, nodelist):
        results = []
        for node in nodelist: 
            # Aggregate load for the complete host 
            cpu_load = 0
            mem_load = 0
              
            for dom in node.domains.values():
                spec = dom.domain_configuration.get_domain_spec() 
                cpu_load += spec.total_cpu_cores()
                mem_load += spec.total_memory()
            
            # VM resource demand
            spec = conf_domainsize.get_domain_spec(new_domain.size)
                
            # Calculate residual vector
            resd_cpu = conf_nodes.NODE_CPU_CORES - cpu_load
            resd_mem = conf_nodes.NODE_MEM - mem_load
            
            # Calculate the dot product
            w_cpu = w_mem = 1
            abs_res = math.sqrt(math.pow(resd_cpu, 2) + math.pow(resd_mem, 2))
            abs_vm = math.sqrt(math.pow(spec.total_cpu_cores(), 2) + math.pow(spec.total_memory(), 2))
            dot_product = w_cpu * resd_cpu * spec.total_cpu_cores() + w_mem * resd_mem * spec.total_memory()
            cosine = dot_product / (abs_res * abs_vm)
             
            # Check if this host is able to handle the new domain
            cpu_delta = resd_cpu - spec.total_cpu_cores()
            mem_delta = resd_mem - spec.total_memory()
            if cpu_delta >= 0 and mem_delta >= 0:
                results.append((node, dot_product, cosine))
            else:
                print 'failed for node %s - status: %i mem %i cpu' % (node.name, mem_delta, cpu_delta)
            

        if results:
            # Get the node with the best (greatest) dot product
            results.sort(key=lambda x: x[1])
            results.reverse()
            best_dot_product = results[0][0]
                        
            # Get the node with the best (smallest) cosine
            results.sort(key=lambda x: x[2])
            best_cosine = results[0][0]
            
            return (best_dot_product.name, best_cosine.name)
    def placement(self, domain):
        # Get all hosts
        hosts = self.model.get_hosts(model.types.NODE)
        
        # Find interval for new domain
        domain_spec = domainsize.get_domain_spec(domain.size)
        for interval in self.intervals:
            if interval.fits(domain_spec):
                break 
        
        if interval == None:
            raise ValueError("Could not find a suitable interval for domain")
        
        # Find all active hosts for the given interval and unused hosts
        interval_hosts = []
        unused_hosts = []
        for host in hosts: 
            if host.domains:
                try:
                    if host.harmonic_interval == interval.index:
                        interval_hosts.append(host)
                except:
                    unused_hosts.append(host)
                    pass
            else:
                unused_hosts.append(host)

        # Selected target node        
        selected = None       
         
        # Check if one of the interval hosts has enough free resources to handle the new domain
        for host in interval_hosts:
            if self.__check_capacity(host, domain):
                selected = host
                break
            
        # Open a new host
        if selected is None:
            selected = unused_hosts.pop()
            
            # Set harmonic interval index            
            selected.harmonic_interval = interval.index

        # Return selected node
        return selected.name
예제 #11
0
def __calculate_reservation_based_lower_bounds(capacity_cpu, capacity_mem, events):
    # Stack is used to keep track of active VMs
    active_stack = []
     
    # Demand duration list
    demand_duration_list = []
     
    # Go through all events and calculate lower bound values
    last_event_offset = 0
    for event in events:
        # Update active VM stack
        if event.is_start:
            active_stack.append(event.entry)
        else:
            active_stack.remove(event.entry)
            
        
        # Calculate total infrastructure demand
        demand_cpu_cores = 0
        demand_mem = 0
        for entry in active_stack: 
            size = conf_domainsize.get_domain_spec(entry.domain_size)
            demand_cpu_cores += size.total_cpu_cores()
            demand_mem += size.total_memory()

        # Calculate server demands          
        server_demand_cpu = math.ceil(demand_cpu_cores / capacity_cpu)
        server_demand_mem = math.ceil(demand_mem / capacity_mem)

        # Take bigger server demand (mem or cpu)
        server_demand = max(server_demand_cpu, server_demand_mem)
        
        # Update delta event duration calculation
        event_duration= event.offset - last_event_offset
        last_event_offset = event.offset
        
        # Add server demand to list 
        demand_duration_list.append((server_demand, event_duration))
        
    # Calculate overall lower bound on server demand over all event slots 
    lb_res_total = max([e[0] for e in demand_duration_list])
    lb_res_avg = sum([e[0] * e[1] for e in demand_duration_list]) / sum([e[1] for e in demand_duration_list])
    return lb_res_total, lb_res_avg
 def test_nodes(self, new_domain, node_list):
     host_choice = []
     for node in node_list:
         # Get actual CPU measurements
         curr_cpu_demand = np.percentile(node.get_readings(), 95)
         
         # Memory demand is calculated by summing up all VM reservations
         mem_load = 0
           
         # Calculate the node utilization by accumulating all domain loads
         for dom in node.domains.values():
             spec = dom.domain_configuration.get_domain_spec()
             mem_load += spec.total_memory()
         
         # Calculate metric
         spec = conf_domainsize.get_domain_spec(new_domain.size)
         mem_delta = conf_nodes.NODE_MEM - (mem_load + spec.total_memory())
         
         
         # Calculate estiated CPU demand if VM is almost
         vm_cpu_demand = conf_nodes.to_node_load(95, new_domain.size)
         cpu_delta = conf_nodes.UTIL - curr_cpu_demand - vm_cpu_demand
         
         # Calculate fit metric
         metric = cpu_delta * mem_delta
         
         # Server is not able to handle the domain
         if cpu_delta < 0 or mem_delta < 0:
             continue
         
         # Add metric to the choice list
         host_choice.append((node.name, metric))
           
     # Check if we found at least one host
     if not host_choice:
         return None
       
     # Sort host choice list
     host_choice = self.sort(host_choice, lambda x: x[1])
     
     # Pkc hte one with the lowest metric (best fit)
     return host_choice[0][0] 
    def test_nodes(self, active_nodes, new_domain):
        # Go over all hosts
        for node in active_nodes:
            # Aggregate resource load for this host
            curr_cpu_demand = 0
            curr_mem_demand = 0

            # Add up the demands of all domains running on the host              
            for old_domain in node.domains.values():
                # Domain size specification 
                spec = old_domain.domain_configuration.get_domain_spec()
                
                # Sum up cpu and mem load 
                curr_cpu_demand += spec.total_cpu_cores()
                curr_mem_demand += spec.total_memory()
            
            # Calculate metric
            new_domain_spec = conf_domainsize.get_domain_spec(new_domain.size)
            cpu_delta = conf_nodes.NODE_CPU_CORES - curr_cpu_demand - new_domain_spec.total_cpu_cores()
            mem_delta = conf_nodes.NODE_MEM - curr_mem_demand - new_domain_spec.total_memory()
            
            # If metric is positive, the node can host the domain
            if cpu_delta >= 0 and mem_delta >= 0: 
                return node.name 
예제 #14
0
def __calculate_demand_based_lower_bounds(capacity_cpu, capacity_mem, events):
    # Stack is used to keep track of active VMs
    active_stack = []
     
    # Demand duration list
    demand_duration_list = []
     
    # Go through all events and calculate lower bound values
    last_event_offset = 0
    
    # Go through all events and calculate lower bound values
    for event in events:
        # Update active VM stack
        if event.is_start:
            active_stack.append(event.entry)
        else:
            active_stack.remove(event.entry)
            
        # Calculate total infrastructure demand
        sum_cpu = 0
        sum_mem = 0
        for entry in active_stack:
            # calculate current offset
            delta_time = event.offset - entry.offset 
            delta_index = delta_time / entry.freq
            
            # Include 10 minutes of load
            delta_index_past = max(delta_index - 10, 0)
            
            # Measurements
            loads = entry.ts[delta_index_past:delta_index]
            
            # Get minimum load
            if len(loads) < 2:
                load = 0; 
            else:
                load = min(*loads)
                
            size = conf_domainsize.get_domain_spec(entry.domain_size)
            sum_cpu += conf_nodes.to_node_load(load, entry.domain_size)
            sum_mem += size.total_memory()
           
        # Calculate server demands 
        lb_cpu = math.ceil(sum_cpu / float(conf_nodes.UTIL))
        lb_mem = math.ceil(sum_mem / float(capacity_mem))
        
        # Take bigger server demand
        lb = max(lb_cpu, lb_mem)
        
        # Update delta event duration calculation
        duration = event.offset - last_event_offset
        last_event_offset = event.offset
        
        # Add server demand to list
        demand_duration_list.append((lb, duration))
        
    # Calculate overall lower bound on server demand over all event slots
    lb_dem_total = max([e[0] for e in demand_duration_list])
    lb_dem_avg = sum([e[0] * e[1] for e in demand_duration_list]) / sum([e[1] for e in demand_duration_list])
    
    return lb_dem_total, lb_dem_avg
예제 #15
0
 def get_domain_spec(self):
     return conf_domainsize.get_domain_spec(self.size)
예제 #16
0
def to_node_load(domain_load, domain_size):
    domain_cores = domainsize.get_domain_spec(domain_size).phy_cpu_cores()
    return float(domain_load * domain_cores) / float(NODE_CPU_CORES)