Search in sources :

Example 1 with BrokerData

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

the class ModularLoadManagerImpl method updateBundleData.

// As the leader broker, use the local broker data saved on ZooKeeper to update the bundle stats so that better load
// management decisions may be made.
private void updateBundleData() {
    final Map<String, BundleData> bundleData = loadData.getBundleData();
    // Iterate over the broker data.
    for (Map.Entry<String, BrokerData> brokerEntry : loadData.getBrokerData().entrySet()) {
        final String broker = brokerEntry.getKey();
        final BrokerData brokerData = brokerEntry.getValue();
        final Map<String, NamespaceBundleStats> statsMap = brokerData.getLocalData().getLastStats();
        // broker to update the bundle data.
        for (Map.Entry<String, NamespaceBundleStats> entry : statsMap.entrySet()) {
            final String bundle = entry.getKey();
            final NamespaceBundleStats stats = entry.getValue();
            if (bundleData.containsKey(bundle)) {
                // If we recognize the bundle, add these stats as a new
                // sample.
                bundleData.get(bundle).update(stats);
            } else {
                // Otherwise, attempt to find the bundle data on ZooKeeper.
                // If it cannot be found, use the latest stats as the first
                // sample.
                BundleData currentBundleData = getBundleDataOrDefault(bundle);
                currentBundleData.update(stats);
                bundleData.put(bundle, currentBundleData);
            }
        }
        // Remove all loaded bundles from the preallocated maps.
        final Map<String, BundleData> preallocatedBundleData = brokerData.getPreallocatedBundleData();
        synchronized (preallocatedBundleData) {
            for (String preallocatedBundleName : brokerData.getPreallocatedBundleData().keySet()) {
                if (brokerData.getLocalData().getBundles().contains(preallocatedBundleName)) {
                    final Iterator<Map.Entry<String, BundleData>> preallocatedIterator = preallocatedBundleData.entrySet().iterator();
                    while (preallocatedIterator.hasNext()) {
                        final String bundle = preallocatedIterator.next().getKey();
                        if (bundleData.containsKey(bundle)) {
                            preallocatedIterator.remove();
                            preallocatedBundleToBroker.remove(bundle);
                        }
                    }
                }
                // This is needed too in case a broker which was assigned a bundle dies and comes back up.
                if (preallocatedBundleToBroker.containsKey(preallocatedBundleName)) {
                    preallocatedBundleToBroker.remove(preallocatedBundleName);
                }
            }
        }
        // Using the newest data, update the aggregated time-average data for the current broker.
        brokerData.getTimeAverageData().reset(statsMap.keySet(), bundleData, defaultStats);
        final Map<String, Set<String>> namespaceToBundleRange = brokerToNamespaceToBundleRange.computeIfAbsent(broker, k -> new HashMap<>());
        synchronized (namespaceToBundleRange) {
            namespaceToBundleRange.clear();
            LoadManagerShared.fillNamespaceToBundlesMap(statsMap.keySet(), namespaceToBundleRange);
            LoadManagerShared.fillNamespaceToBundlesMap(preallocatedBundleData.keySet(), namespaceToBundleRange);
        }
    }
}
Also used : Set(java.util.Set) HashSet(java.util.HashSet) BrokerData(org.apache.pulsar.broker.BrokerData) TimeAverageBrokerData(org.apache.pulsar.broker.TimeAverageBrokerData) LocalBrokerData(org.apache.pulsar.policies.data.loadbalancer.LocalBrokerData) BundleData(org.apache.pulsar.broker.BundleData) NamespaceBundleStats(org.apache.pulsar.policies.data.loadbalancer.NamespaceBundleStats) Map(java.util.Map) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap)

Example 2 with BrokerData

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

the class ModularLoadManagerImpl method updateAllBrokerData.

// As the leader broker, update the broker data map in loadData by querying ZooKeeper for the broker data put there
// by each broker via updateLocalBrokerData.
private void updateAllBrokerData() {
    final Set<String> activeBrokers = getAvailableBrokers();
    final Map<String, BrokerData> brokerDataMap = loadData.getBrokerData();
    for (String broker : activeBrokers) {
        try {
            String key = String.format("%s/%s", LoadManager.LOADBALANCE_BROKERS_ROOT, broker);
            final LocalBrokerData localData = brokerDataCache.get(key).orElseThrow(KeeperException.NoNodeException::new);
            if (brokerDataMap.containsKey(broker)) {
                // Replace previous local broker data.
                brokerDataMap.get(broker).setLocalData(localData);
            } else {
                // Initialize BrokerData object for previously unseen
                // brokers.
                brokerDataMap.put(broker, new BrokerData(localData));
            }
        } catch (NoNodeException ne) {
            // it only happens if we update-brokerData before availableBrokerCache refreshed with latest data and
            // broker's delete-znode watch-event hasn't updated availableBrokerCache
            brokerDataMap.remove(broker);
            log.warn("[{}] broker load-report znode not present", broker, ne);
        } catch (Exception e) {
            log.warn("Error reading broker data from cache for broker - [{}], [{}]", broker, e.getMessage());
        }
    }
    // Remove obsolete brokers.
    for (final String broker : brokerDataMap.keySet()) {
        if (!activeBrokers.contains(broker)) {
            brokerDataMap.remove(broker);
        }
    }
}
Also used : LocalBrokerData(org.apache.pulsar.policies.data.loadbalancer.LocalBrokerData) NoNodeException(org.apache.zookeeper.KeeperException.NoNodeException) BrokerData(org.apache.pulsar.broker.BrokerData) TimeAverageBrokerData(org.apache.pulsar.broker.TimeAverageBrokerData) LocalBrokerData(org.apache.pulsar.policies.data.loadbalancer.LocalBrokerData) 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 3 with BrokerData

use of org.apache.pulsar.broker.BrokerData 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 4 with BrokerData

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

the class BrokerVersionFilter method filter.

/**
 * From the given set of available broker candidates, filter those using the version numbers.
 *
 * @param brokers
 *            The currently available brokers that have not already been filtered.
 * @param bundleToAssign
 *            The data for the bundle to assign.
 * @param loadData
 *            The load data from the leader broker.
 * @param conf
 *            The service configuration.
 */
public void filter(Set<String> brokers, BundleData bundleToAssign, LoadData loadData, ServiceConfiguration conf) throws BrokerFilterBadVersionException {
    if (!conf.isPreferLaterVersions()) {
        return;
    }
    com.github.zafarkhaja.semver.Version latestVersion = null;
    try {
        latestVersion = getLatestVersionNumber(brokers, loadData);
        LOG.info("Latest broker version found was [{}]", latestVersion);
    } catch (Exception x) {
        LOG.warn("Disabling PreferLaterVersions feature; reason: " + x.getMessage());
        throw new BrokerFilterBadVersionException("Cannot determine newest broker version: " + x.getMessage());
    }
    int numBrokersLatestVersion = 0;
    int numBrokersOlderVersion = 0;
    Iterator<String> brokerIterator = brokers.iterator();
    while (brokerIterator.hasNext()) {
        String broker = brokerIterator.next();
        BrokerData data = loadData.getBrokerData().get(broker);
        String brokerVersion = data.getLocalData().getBrokerVersionString();
        com.github.zafarkhaja.semver.Version brokerVersionVersion = Version.valueOf(brokerVersion);
        if (brokerVersionVersion.equals(latestVersion)) {
            LOG.debug("Broker [{}] is running the latest version ([{}])", broker, brokerVersion);
            ++numBrokersLatestVersion;
        } else {
            LOG.info("Broker [{}] is running an older version ([{}]); latest version is [{}]", broker, brokerVersion, latestVersion);
            ++numBrokersOlderVersion;
            brokerIterator.remove();
        }
    }
    if (numBrokersOlderVersion == 0) {
        LOG.info("All {} brokers are running the latest version [{}]", numBrokersLatestVersion, latestVersion);
    }
}
Also used : Version(com.github.zafarkhaja.semver.Version) BrokerFilterBadVersionException(org.apache.pulsar.broker.loadbalance.BrokerFilterBadVersionException) BrokerData(org.apache.pulsar.broker.BrokerData) BrokerFilterBadVersionException(org.apache.pulsar.broker.loadbalance.BrokerFilterBadVersionException) ManagedLedgerException(org.apache.bookkeeper.mledger.ManagedLedgerException)

Example 5 with BrokerData

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

the class LeastLongTermMessageRate method selectBroker.

/**
 * Find a suitable broker to assign the given bundle to.
 *
 * @param candidates
 *            The candidates for which the bundle may be assigned.
 * @param bundleToAssign
 *            The data for the bundle to assign.
 * @param loadData
 *            The load data from the leader broker.
 * @param conf
 *            The service configuration.
 * @return The name of the selected broker as it appears on ZooKeeper.
 */
@Override
public Optional<String> selectBroker(final Set<String> candidates, final BundleData bundleToAssign, final LoadData loadData, final ServiceConfiguration conf) {
    bestBrokers.clear();
    double minScore = Double.POSITIVE_INFINITY;
    // select one of them at the end.
    for (String broker : candidates) {
        final BrokerData brokerData = loadData.getBrokerData().get(broker);
        final double score = getScore(brokerData, conf);
        if (score == Double.POSITIVE_INFINITY) {
            final LocalBrokerData localData = brokerData.getLocalData();
            log.warn("Broker {} is overloaded: CPU: {}%, MEMORY: {}%, DIRECT MEMORY: {}%, BANDWIDTH IN: {}%, " + "BANDWIDTH OUT: {}%", broker, localData.getCpu().percentUsage(), localData.getMemory().percentUsage(), localData.getDirectMemory().percentUsage(), localData.getBandwidthIn().percentUsage(), localData.getBandwidthOut().percentUsage());
        }
        if (score < minScore) {
            // Clear best brokers since this score beats the other brokers.
            bestBrokers.clear();
            bestBrokers.add(broker);
            minScore = score;
        } else if (score == minScore) {
            // Add this broker to best brokers since it ties with the best score.
            bestBrokers.add(broker);
        }
    }
    if (bestBrokers.isEmpty()) {
        // All brokers are overloaded.
        // Assign randomly in this case.
        bestBrokers.addAll(candidates);
    }
    if (bestBrokers.isEmpty()) {
        // If still, it means there are no available brokers at this point
        return Optional.empty();
    }
    return Optional.of(bestBrokers.get(ThreadLocalRandom.current().nextInt(bestBrokers.size())));
}
Also used : LocalBrokerData(org.apache.pulsar.policies.data.loadbalancer.LocalBrokerData) LocalBrokerData(org.apache.pulsar.policies.data.loadbalancer.LocalBrokerData) TimeAverageBrokerData(org.apache.pulsar.broker.TimeAverageBrokerData) BrokerData(org.apache.pulsar.broker.BrokerData)

Aggregations

BrokerData (org.apache.pulsar.broker.BrokerData)11 LocalBrokerData (org.apache.pulsar.policies.data.loadbalancer.LocalBrokerData)9 TimeAverageBrokerData (org.apache.pulsar.broker.TimeAverageBrokerData)6 BundleData (org.apache.pulsar.broker.BundleData)4 HashMap (java.util.HashMap)3 Map (java.util.Map)3 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)3 ResourceUsage (org.apache.pulsar.policies.data.loadbalancer.ResourceUsage)3 Version (com.github.zafarkhaja.semver.Version)2 IOException (java.io.IOException)2 ManagedLedgerException (org.apache.bookkeeper.mledger.ManagedLedgerException)2 PulsarServerException (org.apache.pulsar.broker.PulsarServerException)2 BrokerFilterBadVersionException (org.apache.pulsar.broker.loadbalance.BrokerFilterBadVersionException)2 BrokerFilterException (org.apache.pulsar.broker.loadbalance.BrokerFilterException)2 NamespaceBundleStats (org.apache.pulsar.policies.data.loadbalancer.NamespaceBundleStats)2 KeeperException (org.apache.zookeeper.KeeperException)2 NoNodeException (org.apache.zookeeper.KeeperException.NoNodeException)2 Test (org.testng.annotations.Test)2 HashSet (java.util.HashSet)1 Set (java.util.Set)1