Search in sources :

Example 11 with ResourceQuota

use of com.yahoo.pulsar.common.policies.data.ResourceQuota in project pulsar by yahoo.

the class SimpleLoadManagerImpl method writeResourceQuotasToZooKeeper.

@Override
public void writeResourceQuotasToZooKeeper() throws Exception {
    log.info("Writing namespace bundle resource quotas to ZooKeeper as leader broker");
    // write the load factors
    setDynamicConfigurationToZK(LOADBALANCER_DYNAMIC_SETTING_LOAD_FACTOR_CPU_ZPATH, new HashMap<String, String>() {

        {
            put(SETTING_NAME_LOAD_FACTOR_CPU, Double.toString(realtimeCpuLoadFactor));
        }
    });
    setDynamicConfigurationToZK(LOADBALANCER_DYNAMIC_SETTING_LOAD_FACTOR_MEM_ZPATH, new HashMap<String, String>() {

        {
            put(SETTING_NAME_LOAD_FACTOR_MEM, Double.toString(realtimeMemoryLoadFactor));
        }
    });
    // write default quota
    ResourceQuota defaultQuota = pulsar.getLocalZkCacheService().getResourceQuotaCache().getDefaultQuota();
    this.compareAndWriteQuota(null, defaultQuota, this.realtimeAvgResourceQuota);
    // write each bundle's quota
    Map<String, ResourceQuota> quotas = this.realtimeResourceQuotas.get();
    for (Map.Entry<String, ResourceQuota> entry : quotas.entrySet()) {
        String bundle = entry.getKey();
        ResourceQuota oldQuota = pulsar.getLocalZkCacheService().getResourceQuotaCache().getQuota(bundle);
        this.compareAndWriteQuota(bundle, oldQuota, entry.getValue());
    }
}
Also used : ResourceQuota(com.yahoo.pulsar.common.policies.data.ResourceQuota) Map(java.util.Map) HashMap(java.util.HashMap) TreeMap(java.util.TreeMap)

Example 12 with ResourceQuota

use of com.yahoo.pulsar.common.policies.data.ResourceQuota in project pulsar by yahoo.

the class SimpleLoadManagerImplTest method testPrimary.

@Test(enabled = true)
public void testPrimary() throws Exception {
    LoadManager loadManager = new SimpleLoadManagerImpl(pulsar1);
    PulsarResourceDescription rd = new PulsarResourceDescription();
    rd.put("memory", new ResourceUsage(1024, 4096));
    rd.put("cpu", new ResourceUsage(10, 100));
    rd.put("bandwidthIn", new ResourceUsage(250 * 1024, 1024 * 1024));
    rd.put("bandwidthOut", new ResourceUsage(550 * 1024, 1024 * 1024));
    ResourceUnit ru1 = new SimpleResourceUnit("http://" + pulsar1.getAdvertisedAddress() + ":" + pulsar1.getConfiguration().getWebServicePort(), rd);
    Set<ResourceUnit> rus = new HashSet<ResourceUnit>();
    rus.add(ru1);
    LoadRanker lr = new ResourceAvailabilityRanker();
    // inject the load report and rankings
    Map<ResourceUnit, com.yahoo.pulsar.common.policies.data.loadbalancer.LoadReport> loadReports = new HashMap<>();
    com.yahoo.pulsar.common.policies.data.loadbalancer.LoadReport loadReport = new com.yahoo.pulsar.common.policies.data.loadbalancer.LoadReport();
    loadReport.setSystemResourceUsage(new SystemResourceUsage());
    loadReports.put(ru1, loadReport);
    setObjectField(SimpleLoadManagerImpl.class, loadManager, "currentLoadReports", loadReports);
    ResourceUnitRanking ranking = new ResourceUnitRanking(loadReport.getSystemResourceUsage(), new HashSet<String>(), new ResourceQuota(), new HashSet<String>(), new ResourceQuota());
    Map<ResourceUnit, ResourceUnitRanking> rankings = new HashMap<>();
    rankings.put(ru1, ranking);
    setObjectField(SimpleLoadManagerImpl.class, loadManager, "resourceUnitRankings", rankings);
    AtomicReference<Map<Long, Set<ResourceUnit>>> sortedRankingsInstance = new AtomicReference<>(Maps.newTreeMap());
    sortedRankingsInstance.get().put(lr.getRank(rd), rus);
    setObjectField(SimpleLoadManagerImpl.class, loadManager, "sortedRankings", sortedRankingsInstance);
    ResourceUnit found = ((SimpleLoadManagerImpl) loadManager).getLeastLoaded(new NamespaceName("pulsar/use/primary-ns.10"));
    // broker is not active so found should be null
    assertNotEquals(found, null, "did not find a broker when expected one to be found");
}
Also used : HashMap(java.util.HashMap) NamespaceName(com.yahoo.pulsar.common.naming.NamespaceName) ResourceQuota(com.yahoo.pulsar.common.policies.data.ResourceQuota) ResourceUnitRanking(com.yahoo.pulsar.common.policies.data.loadbalancer.ResourceUnitRanking) HashSet(java.util.HashSet) SystemResourceUsage(com.yahoo.pulsar.common.policies.data.loadbalancer.SystemResourceUsage) ResourceUsage(com.yahoo.pulsar.common.policies.data.loadbalancer.ResourceUsage) SystemResourceUsage(com.yahoo.pulsar.common.policies.data.loadbalancer.SystemResourceUsage) AtomicReference(java.util.concurrent.atomic.AtomicReference) Map(java.util.Map) HashMap(java.util.HashMap) Test(org.testng.annotations.Test)

Example 13 with ResourceQuota

use of com.yahoo.pulsar.common.policies.data.ResourceQuota in project pulsar by yahoo.

the class ResourceQuotaTest method testResourceQuotaDefault.

@Test
public void testResourceQuotaDefault() {
    ResourceQuota quota = new ResourceQuota();
    Assert.assertEquals(quota.getMsgRateIn(), 0.0);
    Assert.assertEquals(quota.getMsgRateOut(), 0.0);
    Assert.assertEquals(quota.getBandwidthIn(), 0.0);
    Assert.assertEquals(quota.getBandwidthOut(), 0.0);
    Assert.assertEquals(quota.getMemory(), 0.0);
    Assert.assertEquals(quota.getDynamic(), true);
    Assert.assertFalse(quota.isValid());
    quota.setMsgRateIn(10);
    quota.setMsgRateOut(20);
    quota.setBandwidthIn(10000);
    quota.setBandwidthOut(20000);
    quota.setMemory(100);
    quota.setDynamic(false);
    Assert.assertEquals(quota.getMsgRateIn(), 10.0);
    Assert.assertEquals(quota.getMsgRateOut(), 20.0);
    Assert.assertEquals(quota.getBandwidthIn(), 10000.0);
    Assert.assertEquals(quota.getBandwidthOut(), 20000.0);
    Assert.assertEquals(quota.getMemory(), 100.0);
    Assert.assertEquals(quota.getDynamic(), false);
}
Also used : ResourceQuota(com.yahoo.pulsar.common.policies.data.ResourceQuota) Test(org.testng.annotations.Test)

Example 14 with ResourceQuota

use of com.yahoo.pulsar.common.policies.data.ResourceQuota in project pulsar by yahoo.

the class SimpleLoadManagerImpl method getTotalAllocatedQuota.

/**
     * Get the sum of allocated resource for the list of namespace bundles
     */
private ResourceQuota getTotalAllocatedQuota(Set<String> bundles) {
    ResourceQuota totalQuota = new ResourceQuota();
    for (String bundle : bundles) {
        ResourceQuota quota = this.getResourceQuota(bundle);
        totalQuota.add(quota);
    }
    return totalQuota;
}
Also used : ResourceQuota(com.yahoo.pulsar.common.policies.data.ResourceQuota)

Example 15 with ResourceQuota

use of com.yahoo.pulsar.common.policies.data.ResourceQuota in project pulsar by yahoo.

the class SimpleLoadManagerImpl method findBrokerForPlacement.

/**
     * Assign owner for specified ServiceUnit from the given candidates, following the the principles: 1) Optimum
     * distribution: fill up one broker till its load reaches optimum level (defined by underload threshold) before pull
     * another idle broker in; 2) Even distribution: once all brokers' load are above optimum level, maintain all
     * brokers to have even load; 3) Set the underload threshold to small value (like 1) for pure even distribution, and
     * high value (like 80) for pure optimum distribution;
     *
     * Strategy to select broker: 1) The first choice is the least loaded broker which is underload but not idle; 2) The
     * second choice is idle broker (if there is any); 3) Othewise simply select the least loaded broker if it is NOT
     * overloaded; 4) If all brokers are overloaded, select the broker with maximum available capacity (considering
     * brokers could have different hardware configuration, this usually means to select the broker with more hardware
     * resource);
     *
     * Broker's load level: 1) Load ranking (triggered by LoadReport update) estimate the load level according to the
     * resourse usage and namespace bundles already loaded by each broker; 2) When leader broker decide the owner for a
     * new namespace bundle, it may take time for the real owner to actually load the bundle and refresh LoadReport,
     * leader broker will store the bundle in a list called preAllocatedBundles, and the quota of all
     * preAllocatedBundles in preAllocatedQuotas, and re-estimate the broker's load level by putting the
     * preAllocatedQuota into calculation; 3) Everything (preAllocatedBundles and preAllocatedQuotas) will get reset in
     * load ranking.
     */
private ResourceUnit findBrokerForPlacement(Multimap<Long, ResourceUnit> candidates, ServiceUnitId serviceUnit) {
    long underloadThreshold = this.getLoadBalancerBrokerUnderloadedThresholdPercentage();
    long overloadThreshold = this.getLoadBalancerBrokerOverloadedThresholdPercentage();
    ResourceQuota defaultQuota = pulsar.getLocalZkCacheService().getResourceQuotaCache().getDefaultQuota();
    double minLoadPercentage = 101.0;
    long maxAvailability = -1;
    ResourceUnit idleRU = null;
    ResourceUnit maxAvailableRU = null;
    ResourceUnit randomRU = null;
    ResourceUnit selectedRU = null;
    ResourceUnitRanking selectedRanking = null;
    String serviceUnitId = serviceUnit.toString();
    synchronized (resourceUnitRankings) {
        long randomBrokerIndex = (candidates.size() > 0) ? (this.brokerRotationCursor % candidates.size()) : 0;
        // find the least loaded & not-idle broker
        for (Map.Entry<Long, ResourceUnit> candidateOwner : candidates.entries()) {
            ResourceUnit candidate = candidateOwner.getValue();
            randomBrokerIndex--;
            // skip broker which is not ranked. this should never happen except in unit test
            if (!resourceUnitRankings.containsKey(candidate)) {
                continue;
            }
            // check if this ServiceUnit is already pre-allocated
            String resourceUnitId = candidate.getResourceId();
            ResourceUnitRanking ranking = resourceUnitRankings.get(candidate);
            if (ranking.isServiceUnitPreAllocated(serviceUnitId)) {
                return candidate;
            }
            // check if this ServiceUnit is already loaded
            if (ranking.isServiceUnitLoaded(serviceUnitId)) {
                ranking.removeLoadedServiceUnit(serviceUnitId, this.getResourceQuota(serviceUnitId));
            }
            // record a random broker
            if (randomBrokerIndex < 0 && randomRU == null) {
                randomRU = candidate;
            }
            // check the available capacity
            double loadPercentage = ranking.getEstimatedLoadPercentage();
            double availablePercentage = Math.max(0, (100 - loadPercentage) / 100);
            long availability = (long) (ranking.estimateMaxCapacity(defaultQuota) * availablePercentage);
            if (availability > maxAvailability) {
                maxAvailability = availability;
                maxAvailableRU = candidate;
            }
            // check the load percentage
            if (ranking.isIdle()) {
                if (idleRU == null) {
                    idleRU = candidate;
                }
            } else {
                if (selectedRU == null) {
                    selectedRU = candidate;
                    selectedRanking = ranking;
                    minLoadPercentage = loadPercentage;
                } else {
                    if (ranking.compareTo(selectedRanking) < 0) {
                        minLoadPercentage = loadPercentage;
                        selectedRU = candidate;
                        selectedRanking = ranking;
                    }
                }
            }
        }
        if ((minLoadPercentage > underloadThreshold && idleRU != null) || selectedRU == null) {
            // assigned to idle broker is the least loaded broker already have optimum load (which means NOT
            // underloaded), or all brokers are idle
            selectedRU = idleRU;
        } else if (minLoadPercentage >= 100.0 && randomRU != null) {
            // all brokers are full, assign to a random one
            selectedRU = randomRU;
        } else if (minLoadPercentage > overloadThreshold) {
            // assign to the broker with maximum available capacity if all brokers are overloaded
            selectedRU = maxAvailableRU;
        }
        // re-calculate load level for selected broker
        if (selectedRU != null) {
            this.brokerRotationCursor = (this.brokerRotationCursor + 1) % 1000000;
            ResourceUnitRanking ranking = resourceUnitRankings.get(selectedRU);
            String loadPercentageDesc = ranking.getEstimatedLoadPercentageString();
            log.info("Assign {} to {} with ({}).", serviceUnitId, selectedRU.getResourceId(), loadPercentageDesc);
            if (!ranking.isServiceUnitPreAllocated(serviceUnitId)) {
                ResourceQuota quota = this.getResourceQuota(serviceUnitId);
                ranking.addPreAllocatedServiceUnit(serviceUnitId, quota);
            }
        }
    }
    return selectedRU;
}
Also used : ResourceUnit(com.yahoo.pulsar.broker.loadbalance.ResourceUnit) ResourceQuota(com.yahoo.pulsar.common.policies.data.ResourceQuota) ResourceUnitRanking(com.yahoo.pulsar.common.policies.data.loadbalancer.ResourceUnitRanking) Map(java.util.Map) HashMap(java.util.HashMap) TreeMap(java.util.TreeMap)

Aggregations

ResourceQuota (com.yahoo.pulsar.common.policies.data.ResourceQuota)19 Test (org.testng.annotations.Test)9 HashMap (java.util.HashMap)7 Map (java.util.Map)7 TreeMap (java.util.TreeMap)6 ResourceUnit (com.yahoo.pulsar.broker.loadbalance.ResourceUnit)3 LoadReport (com.yahoo.pulsar.common.policies.data.loadbalancer.LoadReport)3 ResourceUnitRanking (com.yahoo.pulsar.common.policies.data.loadbalancer.ResourceUnitRanking)3 SystemResourceUsage (com.yahoo.pulsar.common.policies.data.loadbalancer.SystemResourceUsage)3 ResourceQuotaCache (com.yahoo.pulsar.broker.cache.ResourceQuotaCache)2 NamespaceName (com.yahoo.pulsar.common.naming.NamespaceName)2 NamespaceBundleStats (com.yahoo.pulsar.common.policies.data.loadbalancer.NamespaceBundleStats)2 ResourceUsage (com.yahoo.pulsar.common.policies.data.loadbalancer.ResourceUsage)2 HashSet (java.util.HashSet)2 AtomicReference (java.util.concurrent.atomic.AtomicReference)2 PulsarServerException (com.yahoo.pulsar.broker.PulsarServerException)1 MockedPulsarServiceBaseTest (com.yahoo.pulsar.broker.auth.MockedPulsarServiceBaseTest)1 SimpleResourceUnit (com.yahoo.pulsar.broker.loadbalance.impl.SimpleResourceUnit)1 RestException (com.yahoo.pulsar.broker.web.RestException)1 PulsarAdmin (com.yahoo.pulsar.client.admin.PulsarAdmin)1