Search in sources :

Example 1 with TimeAverageMessageData

use of org.apache.pulsar.broker.TimeAverageMessageData in project incubator-pulsar by apache.

the class ModularLoadManagerImpl method getBundleDataOrDefault.

// Attempt to local the data for the given bundle in ZooKeeper.
// If it cannot be found, return the default bundle data.
private BundleData getBundleDataOrDefault(final String bundle) {
    BundleData bundleData = null;
    try {
        final String bundleZPath = getBundleDataZooKeeperPath(bundle);
        final String quotaZPath = String.format("%s/%s", RESOURCE_QUOTA_ZPATH, bundle);
        if (zkClient.exists(bundleZPath, null) != null) {
            bundleData = readJson(zkClient.getData(bundleZPath, null, null), BundleData.class);
        } else if (zkClient.exists(quotaZPath, null) != null) {
            final ResourceQuota quota = readJson(zkClient.getData(quotaZPath, null, null), ResourceQuota.class);
            bundleData = new BundleData(NUM_SHORT_SAMPLES, NUM_LONG_SAMPLES);
            // Initialize from existing resource quotas if new API ZNodes do not exist.
            final TimeAverageMessageData shortTermData = bundleData.getShortTermData();
            final TimeAverageMessageData longTermData = bundleData.getLongTermData();
            shortTermData.setMsgRateIn(quota.getMsgRateIn());
            shortTermData.setMsgRateOut(quota.getMsgRateOut());
            shortTermData.setMsgThroughputIn(quota.getBandwidthIn());
            shortTermData.setMsgThroughputOut(quota.getBandwidthOut());
            longTermData.setMsgRateIn(quota.getMsgRateIn());
            longTermData.setMsgRateOut(quota.getMsgRateOut());
            longTermData.setMsgThroughputIn(quota.getBandwidthIn());
            longTermData.setMsgThroughputOut(quota.getBandwidthOut());
            // Assume ample history.
            shortTermData.setNumSamples(NUM_SHORT_SAMPLES);
            longTermData.setNumSamples(NUM_LONG_SAMPLES);
        }
    } catch (Exception e) {
        log.warn("Error when trying to find bundle {} on zookeeper: {}", bundle, e);
    }
    if (bundleData == null) {
        bundleData = new BundleData(NUM_SHORT_SAMPLES, NUM_LONG_SAMPLES, defaultStats);
    }
    return bundleData;
}
Also used : ResourceQuota(org.apache.pulsar.common.policies.data.ResourceQuota) TimeAverageMessageData(org.apache.pulsar.broker.TimeAverageMessageData) BundleData(org.apache.pulsar.broker.BundleData) BrokerFilterException(org.apache.pulsar.broker.loadbalance.BrokerFilterException) KeeperException(org.apache.zookeeper.KeeperException) IOException(java.io.IOException) NoNodeException(org.apache.zookeeper.KeeperException.NoNodeException) PulsarServerException(org.apache.pulsar.broker.PulsarServerException)

Example 2 with TimeAverageMessageData

use of org.apache.pulsar.broker.TimeAverageMessageData in project incubator-pulsar by apache.

the class OverloadShedder method findBundlesForUnloading.

/**
 * Attempt to shed one bundle off every broker which is overloaded.
 *
 * @param loadData
 *            The load data to used to make the unloading decision.
 * @param conf
 *            The service configuration.
 * @return A map from bundles to unload to the brokers on which they are loaded.
 */
public Map<String, String> findBundlesForUnloading(final LoadData loadData, final ServiceConfiguration conf) {
    selectedBundlesCache.clear();
    final double overloadThreshold = conf.getLoadBalancerBrokerOverloadedThresholdPercentage() / 100.0;
    final Map<String, Long> recentlyUnloadedBundles = loadData.getRecentlyUnloadedBundles();
    for (final Map.Entry<String, BrokerData> entry : loadData.getBrokerData().entrySet()) {
        final String broker = entry.getKey();
        final BrokerData brokerData = entry.getValue();
        final LocalBrokerData localData = brokerData.getLocalData();
        final double maxUsage = localData.getMaxResourceUsage();
        if (maxUsage >= overloadThreshold) {
            log.info("Attempting to shed load on {}, which has max resource usage {}%", broker, maxUsage);
            double maxMessageRate = Double.NEGATIVE_INFINITY;
            String mostTaxingBundle = null;
            if (localData.getBundles().size() > 1) {
                for (final String bundle : localData.getBundles()) {
                    final BundleData bundleData = loadData.getBundleData().get(bundle);
                    if (bundleData == null) {
                        continue;
                    }
                    // Consider short-term message rate to address system resource burden
                    final TimeAverageMessageData shortTermData = bundleData.getShortTermData();
                    final double messageRate = shortTermData.getMsgRateIn() + shortTermData.getMsgRateOut();
                    // The burden of checking the timestamp is for the load manager, not the strategy.
                    if (messageRate > maxMessageRate && !recentlyUnloadedBundles.containsKey(bundle)) {
                        maxMessageRate = messageRate;
                        mostTaxingBundle = bundle;
                    }
                }
                if (mostTaxingBundle != null) {
                    selectedBundlesCache.put(broker, mostTaxingBundle);
                } else {
                    log.warn("Load shedding could not be performed on broker {} because all bundles assigned to it " + "have recently been unloaded");
                }
            } else if (localData.getBundles().size() == 1) {
                log.warn("HIGH USAGE WARNING : Sole namespace bundle {} is overloading broker {}. " + "No Load Shedding will be done on this broker", localData.getBundles().iterator().next(), broker);
            } else {
                log.warn("Broker {} is overloaded despite having no bundles", broker);
            }
        }
    }
    return selectedBundlesCache;
}
Also used : LocalBrokerData(org.apache.pulsar.policies.data.loadbalancer.LocalBrokerData) BrokerData(org.apache.pulsar.broker.BrokerData) LocalBrokerData(org.apache.pulsar.policies.data.loadbalancer.LocalBrokerData) TimeAverageMessageData(org.apache.pulsar.broker.TimeAverageMessageData) Map(java.util.Map) HashMap(java.util.HashMap) BundleData(org.apache.pulsar.broker.BundleData)

Example 3 with TimeAverageMessageData

use of org.apache.pulsar.broker.TimeAverageMessageData in project incubator-pulsar by apache.

the class LeastLongTermMessageRate method getScore.

// Form a score for a broker using its preallocated bundle data and time average data.
// This is done by summing all preallocated long-term message rates and adding them to the broker's overall
// long-term message rate, which is itself the sum of the long-term message rate of every allocated bundle.
// Any broker at (or above) the overload threshold will have a score of POSITIVE_INFINITY.
private static double getScore(final BrokerData brokerData, final ServiceConfiguration conf) {
    final double overloadThreshold = conf.getLoadBalancerBrokerOverloadedThresholdPercentage() / 100.0;
    final double maxUsage = brokerData.getLocalData().getMaxResourceUsage();
    if (maxUsage > overloadThreshold) {
        log.warn("Broker {} is overloaded: max usage={}", brokerData.getLocalData().getWebServiceUrl(), maxUsage);
        return Double.POSITIVE_INFINITY;
    }
    double totalMessageRate = 0;
    for (BundleData bundleData : brokerData.getPreallocatedBundleData().values()) {
        final TimeAverageMessageData longTermData = bundleData.getLongTermData();
        totalMessageRate += longTermData.getMsgRateIn() + longTermData.getMsgRateOut();
    }
    // calculate estimated score
    final TimeAverageBrokerData timeAverageData = brokerData.getTimeAverageData();
    final double timeAverageLongTermMessageRate = timeAverageData.getLongTermMsgRateIn() + timeAverageData.getLongTermMsgRateOut();
    final double totalMessageRateEstimate = totalMessageRate + timeAverageLongTermMessageRate;
    if (log.isDebugEnabled()) {
        log.debug("Broker {} has long term message rate {}", brokerData.getLocalData().getWebServiceUrl(), totalMessageRateEstimate);
    }
    return totalMessageRateEstimate;
}
Also used : TimeAverageMessageData(org.apache.pulsar.broker.TimeAverageMessageData) BundleData(org.apache.pulsar.broker.BundleData) TimeAverageBrokerData(org.apache.pulsar.broker.TimeAverageBrokerData)

Example 4 with TimeAverageMessageData

use of org.apache.pulsar.broker.TimeAverageMessageData in project incubator-pulsar by apache.

the class ModularLoadManagerImplTest method testEvenBundleDistribution.

// Test that bundles belonging to the same namespace are distributed evenly among brokers.
// Test disabled since it's depending on CPU usage in the machine
@Test(enabled = false)
public void testEvenBundleDistribution() throws Exception {
    final NamespaceBundle[] bundles = LoadBalancerTestingUtils.makeBundles(nsFactory, "test", "test", "test", 16);
    int numAssignedToPrimary = 0;
    int numAssignedToSecondary = 0;
    final BundleData bundleData = new BundleData(10, 1000);
    final TimeAverageMessageData longTermMessageData = new TimeAverageMessageData(1000);
    longTermMessageData.setMsgRateIn(1000);
    bundleData.setLongTermData(longTermMessageData);
    final String firstBundleDataPath = String.format("%s/%s", ModularLoadManagerImpl.BUNDLE_DATA_ZPATH, bundles[0]);
    // Write long message rate for first bundle to ensure that even bundle distribution is not a coincidence of
    // balancing by message rate. If we were balancing by message rate, one of the brokers should only have this
    // one bundle.
    ZkUtils.createFullPathOptimistic(pulsar1.getZkClient(), firstBundleDataPath, bundleData.getJsonBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
    for (final NamespaceBundle bundle : bundles) {
        if (primaryLoadManager.selectBrokerForAssignment(bundle).equals(primaryHost)) {
            ++numAssignedToPrimary;
        } else {
            ++numAssignedToSecondary;
        }
        if ((numAssignedToPrimary + numAssignedToSecondary) % 2 == 0) {
            // On even number of assignments, assert that an equal number of bundles have been assigned between
            // them.
            assertEquals(numAssignedToPrimary, numAssignedToSecondary);
        }
    }
}
Also used : NamespaceBundle(org.apache.pulsar.common.naming.NamespaceBundle) TimeAverageMessageData(org.apache.pulsar.broker.TimeAverageMessageData) BundleData(org.apache.pulsar.broker.BundleData) Test(org.testng.annotations.Test)

Example 5 with TimeAverageMessageData

use of org.apache.pulsar.broker.TimeAverageMessageData in project incubator-pulsar by apache.

the class ModularLoadManagerImplTest method testMaxTopicDistributionToBroker.

/**
 * It verifies that once broker owns max-number of topics: load-manager doesn't allocates new bundles to that broker
 * unless all the brokers are in same state.
 *
 * <pre>
 * 1. Create a bundle whose bundle-resource-quota will contain max-topics
 * 2. Load-manager assigns broker to this bundle so, assigned broker is overloaded with max-topics
 * 3. For any new further bundles: broker assigns different brokers.
 * </pre>
 *
 * @throws Exception
 */
@Test
public void testMaxTopicDistributionToBroker() throws Exception {
    final int totalBundles = 50;
    final NamespaceBundle[] bundles = LoadBalancerTestingUtils.makeBundles(nsFactory, "test", "test", "test", totalBundles);
    final BundleData bundleData = new BundleData(10, 1000);
    // it sets max topics under this bundle so, owner of this broker reaches max-topic threshold
    bundleData.setTopics(pulsar1.getConfiguration().getLoadBalancerBrokerMaxTopics() + 10);
    final TimeAverageMessageData longTermMessageData = new TimeAverageMessageData(1000);
    longTermMessageData.setMsgRateIn(1000);
    bundleData.setLongTermData(longTermMessageData);
    final String firstBundleDataPath = String.format("%s/%s", ModularLoadManagerImpl.BUNDLE_DATA_ZPATH, bundles[0]);
    ZkUtils.createFullPathOptimistic(pulsar1.getZkClient(), firstBundleDataPath, bundleData.getJsonBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
    String maxTopicOwnedBroker = primaryLoadManager.selectBrokerForAssignment(bundles[0]).get();
    for (int i = 1; i < totalBundles; i++) {
        assertNotEquals(primaryLoadManager.selectBrokerForAssignment(bundles[i]), maxTopicOwnedBroker);
    }
}
Also used : NamespaceBundle(org.apache.pulsar.common.naming.NamespaceBundle) TimeAverageMessageData(org.apache.pulsar.broker.TimeAverageMessageData) BundleData(org.apache.pulsar.broker.BundleData) Test(org.testng.annotations.Test)

Aggregations

TimeAverageMessageData (org.apache.pulsar.broker.TimeAverageMessageData)6 BundleData (org.apache.pulsar.broker.BundleData)5 Map (java.util.Map)2 NamespaceBundle (org.apache.pulsar.common.naming.NamespaceBundle)2 LocalBrokerData (org.apache.pulsar.policies.data.loadbalancer.LocalBrokerData)2 Test (org.testng.annotations.Test)2 IOException (java.io.IOException)1 HashMap (java.util.HashMap)1 BrokerData (org.apache.pulsar.broker.BrokerData)1 PulsarServerException (org.apache.pulsar.broker.PulsarServerException)1 ServiceConfiguration (org.apache.pulsar.broker.ServiceConfiguration)1 TimeAverageBrokerData (org.apache.pulsar.broker.TimeAverageBrokerData)1 BrokerFilterException (org.apache.pulsar.broker.loadbalance.BrokerFilterException)1 ResourceQuota (org.apache.pulsar.common.policies.data.ResourceQuota)1 NamespaceBundleStats (org.apache.pulsar.policies.data.loadbalancer.NamespaceBundleStats)1 KeeperException (org.apache.zookeeper.KeeperException)1 NoNodeException (org.apache.zookeeper.KeeperException.NoNodeException)1