/** * Obtain the UUID of some relatively underutilized data service. * * <p>FIXME The LBS should interpret the excludedServiceUUID as the source service UUID and then * provide a list of those services having an LBS computed service score which is significantly * lower than the score for this service. Changing this will break some unit tests (for the LBS * behavior). */ private UUID getMoveTarget( final UUID sourceServiceUUID, final ILoadBalancerService loadBalancerService) { try { // request under utilized data service UUIDs (RMI). final UUID[] uuids = loadBalancerService.getUnderUtilizedDataServices( // 0, // minCount - no lower bound. 1, // maxCount - no upper bound. sourceServiceUUID // exclude this data service. ); if (uuids != null && uuids.length > 0) { // Found a move target. return uuids[0]; } // No move target. return null; } catch (TimeoutException t) { log.warn(t.getMessage()); return null; } catch (InterruptedException t) { log.warn(t.getMessage()); return null; } catch (Throwable t) { log.error("Could not obtain target service UUIDs: ", t); return null; } }
/** * Figure out if this data service is considered to be highly utilized, in which case the DS * should shed some index partitions. * * <p>Note: We consult the load balancer service on this since it is able to put the load of this * service into perspective by also considering the load on the other services in the federation. * * @param loadBalancerService The load balancer. */ protected boolean shouldMove(final ILoadBalancerService loadBalancerService) { if (loadBalancerService == null) throw new IllegalArgumentException(); // inquire if this service is highly utilized. final boolean highlyUtilizedService; try { final UUID serviceUUID = resourceManager.getDataServiceUUID(); highlyUtilizedService = loadBalancerService.isHighlyUtilizedDataService(serviceUUID); } catch (Exception ex) { log.warn("Could not determine if this data service is highly utilized"); return false; } if (!highlyUtilizedService) { if (log.isInfoEnabled()) log.info("Service is not highly utilized."); return false; } /* * At this point we know that the LBS considers this host and service to * be highly utilized (relative to the other hosts and services). If * there is evidence of resource exhaustion for critical resources (CPU, * RAM, or DIKS) then we will MOVE index partitions in order to shed * some load. Otherwise, we will SPLIT hot index partitions in order to * increase the potential concurrency of the workload for this service. * * Note: CPU is the only fungable resource since things will just slow * down if a host has 100% CPU while it can die if it runs out of DISK * or RAM (including if it begins to swap heavily). * * @todo config options for these triggers. */ final ResourceScores resourceScores = resourceManager.getResourceScores(); final boolean shouldMove = // // heavy CPU utilization. (resourceScores.percentCPUTime >= resourceManager.movePercentCpuTimeThreshold) || // swapping heavily. (resourceScores.majorPageFaultsPerSec > 20) || // running out of disk (data dir). (resourceScores.dataDirBytesFree < Bytes.gigabyte * 5) || // running out of disk (tmp dir). (resourceScores.dataDirBytesFree < Bytes.gigabyte * .5); return shouldMove; // if (shouldMove) { // // return chooseMoves(loadBalancerService); // // } // return chooseHotSplits(); }