Search in sources :

Example 86 with NamespaceName

use of org.apache.pulsar.common.naming.NamespaceName in project incubator-pulsar by apache.

the class SimpleLoadManagerImpl method doNamespaceBundleSplit.

/**
 * Detect and split hot namespace bundles
 */
@Override
public void doNamespaceBundleSplit() throws Exception {
    int maxBundleCount = pulsar.getConfiguration().getLoadBalancerNamespaceMaximumBundles();
    long maxBundleTopics = pulsar.getConfiguration().getLoadBalancerNamespaceBundleMaxTopics();
    long maxBundleSessions = pulsar.getConfiguration().getLoadBalancerNamespaceBundleMaxSessions();
    long maxBundleMsgRate = pulsar.getConfiguration().getLoadBalancerNamespaceBundleMaxMsgRate();
    long maxBundleBandwidth = pulsar.getConfiguration().getLoadBalancerNamespaceBundleMaxBandwidthMbytes() * MBytes;
    log.info("Running namespace bundle split with thresholds: topics {}, sessions {}, msgRate {}, bandwidth {}, maxBundles {}", maxBundleTopics, maxBundleSessions, maxBundleMsgRate, maxBundleBandwidth, maxBundleCount);
    if (this.lastLoadReport == null || this.lastLoadReport.getBundleStats() == null) {
        return;
    }
    Map<String, NamespaceBundleStats> bundleStats = this.lastLoadReport.getBundleStats();
    Set<String> bundlesToBeSplit = new HashSet<>();
    for (Map.Entry<String, NamespaceBundleStats> statsEntry : bundleStats.entrySet()) {
        String bundleName = statsEntry.getKey();
        NamespaceBundleStats stats = statsEntry.getValue();
        long totalSessions = stats.consumerCount + stats.producerCount;
        double totalMsgRate = stats.msgRateIn + stats.msgRateOut;
        double totalBandwidth = stats.msgThroughputIn + stats.msgThroughputOut;
        boolean needSplit = false;
        if (stats.topics > maxBundleTopics || totalSessions > maxBundleSessions || totalMsgRate > maxBundleMsgRate || totalBandwidth > maxBundleBandwidth) {
            if (stats.topics <= 1) {
                log.info("Unable to split hot namespace bundle {} since there is only one topic.", bundleName);
            } else {
                NamespaceName namespaceName = NamespaceName.get(LoadManagerShared.getNamespaceNameFromBundleName(bundleName));
                int numBundles = pulsar.getNamespaceService().getBundleCount(namespaceName);
                if (numBundles >= maxBundleCount) {
                    log.info("Unable to split hot namespace bundle {} since the namespace has too many bundles.", bundleName);
                } else {
                    needSplit = true;
                }
            }
        }
        if (needSplit) {
            if (this.getLoadBalancerAutoBundleSplitEnabled()) {
                log.info("Will split hot namespace bundle {}, topics {}, producers+consumers {}, msgRate in+out {}, bandwidth in+out {}", bundleName, stats.topics, totalSessions, totalMsgRate, totalBandwidth);
                bundlesToBeSplit.add(bundleName);
            } else {
                log.info("DRY RUN - split hot namespace bundle {}, topics {}, producers+consumers {}, msgRate in+out {}, bandwidth in+out {}", bundleName, stats.topics, totalSessions, totalMsgRate, totalBandwidth);
            }
        }
    }
    if (bundlesToBeSplit.size() > 0) {
        for (String bundleName : bundlesToBeSplit) {
            try {
                pulsar.getAdminClient().namespaces().splitNamespaceBundle(LoadManagerShared.getNamespaceNameFromBundleName(bundleName), LoadManagerShared.getBundleRangeFromBundleName(bundleName), pulsar.getConfiguration().isLoadBalancerAutoUnloadSplitBundlesEnabled());
                log.info("Successfully split namespace bundle {}", bundleName);
            } catch (Exception e) {
                log.error("Failed to split namespace bundle {}", bundleName, e);
            }
        }
        this.setLoadReportForceUpdateFlag();
    }
}
Also used : KeeperException(org.apache.zookeeper.KeeperException) IOException(java.io.IOException) PulsarServerException(org.apache.pulsar.broker.PulsarServerException) NamespaceName(org.apache.pulsar.common.naming.NamespaceName) NamespaceBundleStats(org.apache.pulsar.policies.data.loadbalancer.NamespaceBundleStats) Map(java.util.Map) HashMap(java.util.HashMap) TreeMap(java.util.TreeMap) HashSet(java.util.HashSet)

Example 87 with NamespaceName

use of org.apache.pulsar.common.naming.NamespaceName in project incubator-pulsar by apache.

the class ModularLoadManagerImpl method selectBrokerForAssignment.

/**
 * As the leader broker, find a suitable broker for the assignment of the given bundle.
 *
 * @param serviceUnit
 *            ServiceUnitId for the bundle.
 * @return The name of the selected broker, as it appears on ZooKeeper.
 */
@Override
public Optional<String> selectBrokerForAssignment(final ServiceUnitId serviceUnit) {
    // Use brokerCandidateCache as a lock to reduce synchronization.
    synchronized (brokerCandidateCache) {
        final String bundle = serviceUnit.toString();
        if (preallocatedBundleToBroker.containsKey(bundle)) {
            // If the given bundle is already in preallocated, return the selected broker.
            return Optional.of(preallocatedBundleToBroker.get(bundle));
        }
        final BundleData data = loadData.getBundleData().computeIfAbsent(bundle, key -> getBundleDataOrDefault(bundle));
        brokerCandidateCache.clear();
        LoadManagerShared.applyNamespacePolicies(serviceUnit, policies, brokerCandidateCache, getAvailableBrokers(), brokerTopicLoadingPredicate);
        // filter brokers which owns topic higher than threshold
        LoadManagerShared.filterBrokersWithLargeTopicCount(brokerCandidateCache, loadData, conf.getLoadBalancerBrokerMaxTopics());
        // distribute namespaces to domain and brokers according to anti-affinity-group
        LoadManagerShared.filterAntiAffinityGroupOwnedBrokers(pulsar, serviceUnit.toString(), brokerCandidateCache, brokerToNamespaceToBundleRange, brokerToFailureDomainMap);
        // distribute bundles evenly to candidate-brokers
        LoadManagerShared.removeMostServicingBrokersForNamespace(serviceUnit.toString(), brokerCandidateCache, brokerToNamespaceToBundleRange);
        log.info("{} brokers being considered for assignment of {}", brokerCandidateCache.size(), bundle);
        // Use the filter pipeline to finalize broker candidates.
        try {
            for (BrokerFilter filter : filterPipeline) {
                filter.filter(brokerCandidateCache, data, loadData, conf);
            }
        } catch (BrokerFilterException x) {
            // restore the list of brokers to the full set
            LoadManagerShared.applyNamespacePolicies(serviceUnit, policies, brokerCandidateCache, getAvailableBrokers(), brokerTopicLoadingPredicate);
        }
        if (brokerCandidateCache.isEmpty()) {
            // restore the list of brokers to the full set
            LoadManagerShared.applyNamespacePolicies(serviceUnit, policies, brokerCandidateCache, getAvailableBrokers(), brokerTopicLoadingPredicate);
        }
        // Choose a broker among the potentially smaller filtered list, when possible
        Optional<String> broker = placementStrategy.selectBroker(brokerCandidateCache, data, loadData, conf);
        if (log.isDebugEnabled()) {
            log.debug("Selected broker {} from candidate brokers {}", broker, brokerCandidateCache);
        }
        if (!broker.isPresent()) {
            // No brokers available
            return broker;
        }
        final double overloadThreshold = conf.getLoadBalancerBrokerOverloadedThresholdPercentage() / 100.0;
        final double maxUsage = loadData.getBrokerData().get(broker.get()).getLocalData().getMaxResourceUsage();
        if (maxUsage > overloadThreshold) {
            // All brokers that were in the filtered list were overloaded, so check if there is a better broker
            LoadManagerShared.applyNamespacePolicies(serviceUnit, policies, brokerCandidateCache, getAvailableBrokers(), brokerTopicLoadingPredicate);
            broker = placementStrategy.selectBroker(brokerCandidateCache, data, loadData, conf);
        }
        // Add new bundle to preallocated.
        loadData.getBrokerData().get(broker.get()).getPreallocatedBundleData().put(bundle, data);
        preallocatedBundleToBroker.put(bundle, broker.get());
        final String namespaceName = LoadManagerShared.getNamespaceNameFromBundleName(bundle);
        final String bundleRange = LoadManagerShared.getBundleRangeFromBundleName(bundle);
        brokerToNamespaceToBundleRange.get(broker.get()).computeIfAbsent(namespaceName, k -> new HashSet<>()).add(bundleRange);
        return broker;
    }
}
Also used : BrokerFilter(org.apache.pulsar.broker.loadbalance.BrokerFilter) CreateMode(org.apache.zookeeper.CreateMode) DefaultThreadFactory(io.netty.util.concurrent.DefaultThreadFactory) ObjectMapperFactory(org.apache.pulsar.common.util.ObjectMapperFactory) LoggerFactory(org.slf4j.LoggerFactory) LoadSheddingStrategy(org.apache.pulsar.broker.loadbalance.LoadSheddingStrategy) LoadManager(org.apache.pulsar.broker.loadbalance.LoadManager) ModularLoadManagerStrategy(org.apache.pulsar.broker.loadbalance.ModularLoadManagerStrategy) Stat(org.apache.zookeeper.data.Stat) StringUtils(org.apache.commons.lang3.StringUtils) BundleSplitStrategy(org.apache.pulsar.broker.loadbalance.BundleSplitStrategy) SystemResourceUsage(org.apache.pulsar.policies.data.loadbalancer.SystemResourceUsage) Map(java.util.Map) ZooKeeperDataCache(org.apache.pulsar.zookeeper.ZooKeeperDataCache) NamespaceName(org.apache.pulsar.common.naming.NamespaceName) AdminResource.jsonMapper(org.apache.pulsar.broker.admin.AdminResource.jsonMapper) ZooKeeper(org.apache.zookeeper.ZooKeeper) BrokerHostUsage(org.apache.pulsar.broker.loadbalance.BrokerHostUsage) LoadData(org.apache.pulsar.broker.loadbalance.LoadData) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Set(java.util.Set) ZooKeeperChildrenCache(org.apache.pulsar.zookeeper.ZooKeeperChildrenCache) ZooKeeperCacheListener(org.apache.pulsar.zookeeper.ZooKeeperCacheListener) ModularLoadManager(org.apache.pulsar.broker.loadbalance.ModularLoadManager) Executors(java.util.concurrent.Executors) ZkUtils(org.apache.bookkeeper.util.ZkUtils) BrokerData(org.apache.pulsar.broker.BrokerData) NamespaceBundleFactory(org.apache.pulsar.common.naming.NamespaceBundleFactory) List(java.util.List) ServiceUnitId(org.apache.pulsar.common.naming.ServiceUnitId) Optional(java.util.Optional) NamespaceBundleStats(org.apache.pulsar.policies.data.loadbalancer.NamespaceBundleStats) TimeAverageBrokerData(org.apache.pulsar.broker.TimeAverageBrokerData) PulsarWebResource.path(org.apache.pulsar.broker.web.PulsarWebResource.path) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) BundleData(org.apache.pulsar.broker.BundleData) BrokerFilter(org.apache.pulsar.broker.loadbalance.BrokerFilter) HashSet(java.util.HashSet) ScheduledExecutorService(java.util.concurrent.ScheduledExecutorService) BrokerFilterException(org.apache.pulsar.broker.loadbalance.BrokerFilterException) ResourceQuota(org.apache.pulsar.common.policies.data.ResourceQuota) Logger(org.slf4j.Logger) Iterator(java.util.Iterator) KeeperException(org.apache.zookeeper.KeeperException) SystemUtils(org.apache.commons.lang3.SystemUtils) ServiceConfiguration(org.apache.pulsar.broker.ServiceConfiguration) LocalBrokerData(org.apache.pulsar.policies.data.loadbalancer.LocalBrokerData) BrokerTopicLoadingPredicate(org.apache.pulsar.broker.loadbalance.impl.LoadManagerShared.BrokerTopicLoadingPredicate) FailureDomain(org.apache.pulsar.common.policies.data.FailureDomain) IOException(java.io.IOException) PulsarService(org.apache.pulsar.broker.PulsarService) Maps(com.google.common.collect.Maps) TimeUnit(java.util.concurrent.TimeUnit) Policies(org.apache.pulsar.common.policies.data.Policies) POLICIES(org.apache.pulsar.broker.cache.ConfigurationCacheService.POLICIES) TimeAverageMessageData(org.apache.pulsar.broker.TimeAverageMessageData) ZooDefs(org.apache.zookeeper.ZooDefs) NoNodeException(org.apache.zookeeper.KeeperException.NoNodeException) PulsarServerException(org.apache.pulsar.broker.PulsarServerException) Deserializer(org.apache.pulsar.zookeeper.ZooKeeperCache.Deserializer) BundleData(org.apache.pulsar.broker.BundleData) BrokerFilterException(org.apache.pulsar.broker.loadbalance.BrokerFilterException) HashSet(java.util.HashSet)

Example 88 with NamespaceName

use of org.apache.pulsar.common.naming.NamespaceName in project incubator-pulsar by apache.

the class LoadBalancerTestingUtils method makeBundles.

public static NamespaceBundle[] makeBundles(final NamespaceBundleFactory nsFactory, final String property, final String cluster, final String namespace, final int numBundles) {
    final NamespaceBundle[] result = new NamespaceBundle[numBundles];
    final NamespaceName namespaceName = NamespaceName.get(property, cluster, namespace);
    for (int i = 0; i < numBundles - 1; ++i) {
        final long lower = NamespaceBundles.FULL_UPPER_BOUND * i / numBundles;
        final long upper = NamespaceBundles.FULL_UPPER_BOUND * (i + 1) / numBundles;
        result[i] = nsFactory.getBundle(namespaceName, Range.range(lower, BoundType.CLOSED, upper, BoundType.OPEN));
    }
    result[numBundles - 1] = nsFactory.getBundle(namespaceName, Range.range(NamespaceBundles.FULL_UPPER_BOUND * (numBundles - 1) / numBundles, BoundType.CLOSED, NamespaceBundles.FULL_UPPER_BOUND, BoundType.CLOSED));
    return result;
}
Also used : NamespaceBundle(org.apache.pulsar.common.naming.NamespaceBundle) NamespaceName(org.apache.pulsar.common.naming.NamespaceName)

Example 89 with NamespaceName

use of org.apache.pulsar.common.naming.NamespaceName in project incubator-pulsar by apache.

the class NamespaceServiceTest method testSplitMapWithRefreshedStatMap.

@Test
public void testSplitMapWithRefreshedStatMap() throws Exception {
    OwnershipCache MockOwnershipCache = spy(pulsar.getNamespaceService().getOwnershipCache());
    ManagedLedger ledger = mock(ManagedLedger.class);
    when(ledger.getCursors()).thenReturn(Lists.newArrayList());
    doNothing().when(MockOwnershipCache).disableOwnership(any(NamespaceBundle.class));
    Field ownership = NamespaceService.class.getDeclaredField("ownershipCache");
    ownership.setAccessible(true);
    ownership.set(pulsar.getNamespaceService(), MockOwnershipCache);
    NamespaceService namespaceService = pulsar.getNamespaceService();
    NamespaceName nsname = NamespaceName.get("pulsar/global/ns1");
    TopicName topicName = TopicName.get("persistent://pulsar/global/ns1/topic-1");
    NamespaceBundles bundles = namespaceService.getNamespaceBundleFactory().getBundles(nsname);
    NamespaceBundle originalBundle = bundles.findBundle(topicName);
    PersistentTopic topic = new PersistentTopic(topicName.toString(), ledger, pulsar.getBrokerService());
    Method method = pulsar.getBrokerService().getClass().getDeclaredMethod("addTopicToStatsMaps", TopicName.class, Topic.class);
    method.setAccessible(true);
    method.invoke(pulsar.getBrokerService(), topicName, topic);
    String nspace = originalBundle.getNamespaceObject().toString();
    List<Topic> list = this.pulsar.getBrokerService().getAllTopicsFromNamespaceBundle(nspace, originalBundle.toString());
    assertNotNull(list);
    // Split bundle and take ownership of split bundles
    CompletableFuture<Void> result = namespaceService.splitAndOwnBundle(originalBundle, false);
    try {
        result.get();
    } catch (Exception e) {
        // make sure: no failure
        fail("split bundle faild", e);
    }
    // old bundle should be removed from status-map
    list = this.pulsar.getBrokerService().getAllTopicsFromNamespaceBundle(nspace, originalBundle.toString());
    assertTrue(list.isEmpty());
    // status-map should be updated with new split bundles
    NamespaceBundle splitBundle = pulsar.getNamespaceService().getBundle(topicName);
    assertTrue(!CollectionUtils.isEmpty(this.pulsar.getBrokerService().getAllTopicsFromNamespaceBundle(nspace, splitBundle.toString())));
}
Also used : NamespaceBundle(org.apache.pulsar.common.naming.NamespaceBundle) ManagedLedger(org.apache.bookkeeper.mledger.ManagedLedger) NamespaceBundles(org.apache.pulsar.common.naming.NamespaceBundles) AfterMethod(org.testng.annotations.AfterMethod) Method(java.lang.reflect.Method) BeforeMethod(org.testng.annotations.BeforeMethod) TopicName(org.apache.pulsar.common.naming.TopicName) Field(java.lang.reflect.Field) NamespaceName(org.apache.pulsar.common.naming.NamespaceName) PersistentTopic(org.apache.pulsar.broker.service.persistent.PersistentTopic) Topic(org.apache.pulsar.broker.service.Topic) PersistentTopic(org.apache.pulsar.broker.service.persistent.PersistentTopic) Test(org.testng.annotations.Test)

Example 90 with NamespaceName

use of org.apache.pulsar.common.naming.NamespaceName in project incubator-pulsar by apache.

the class OwnershipCacheTest method testGetOwnedServiceUnits.

@Test
public void testGetOwnedServiceUnits() throws Exception {
    OwnershipCache cache = new OwnershipCache(this.pulsar, bundleFactory);
    NamespaceName testNs = NamespaceName.get("pulsar/test/ns-6");
    NamespaceBundle testBundle = bundleFactory.getFullBundle(testNs);
    // case 1: no one owns the namespace
    assertFalse(cache.getOwnerAsync(testBundle).get().isPresent());
    assertTrue(cache.getOwnedBundles().isEmpty());
    // case 2: someone else owns the namespace
    ServiceUnitZkUtils.acquireNameSpace(zkCache.getZooKeeper(), ServiceUnitZkUtils.path(testBundle), new NamespaceEphemeralData("pulsar://otherhost:8881", "pulsar://otherhost:8884", "http://otherhost:8080", "https://otherhost:4443", false));
    assertTrue(cache.getOwnedBundles().isEmpty());
    Thread.sleep(500);
    // try to acquire, which will load the read-only cache
    NamespaceEphemeralData data1 = cache.tryAcquiringOwnership(testBundle).get();
    assertEquals(data1.getNativeUrl(), "pulsar://otherhost:8881");
    assertEquals(data1.getNativeUrlTls(), "pulsar://otherhost:8884");
    assertTrue(!data1.isDisabled());
    assertTrue(cache.getOwnedBundles().isEmpty());
    // case 3: this broker owns the namespace
    // delete the ephemeral node by others
    zkCache.getZooKeeper().delete(ServiceUnitZkUtils.path(testBundle), -1);
    // force to read directly from ZK
    localCache.ownerInfoCache().invalidate(ServiceUnitZkUtils.path(testBundle));
    data1 = cache.tryAcquiringOwnership(testBundle).get();
    assertEquals(data1.getNativeUrl(), selfBrokerUrl);
    assertTrue(!data1.isDisabled());
    assertTrue(cache.getOwnedBundles().size() == 1);
}
Also used : NamespaceBundle(org.apache.pulsar.common.naming.NamespaceBundle) NamespaceName(org.apache.pulsar.common.naming.NamespaceName) Test(org.testng.annotations.Test)

Aggregations

NamespaceName (org.apache.pulsar.common.naming.NamespaceName)99 WebTarget (javax.ws.rs.client.WebTarget)52 PulsarAdminException (org.apache.pulsar.client.admin.PulsarAdminException)52 Test (org.testng.annotations.Test)27 NamespaceBundle (org.apache.pulsar.common.naming.NamespaceBundle)26 List (java.util.List)15 MockedPulsarServiceBaseTest (org.apache.pulsar.broker.auth.MockedPulsarServiceBaseTest)13 RestException (org.apache.pulsar.broker.web.RestException)13 TopicName (org.apache.pulsar.common.naming.TopicName)13 Field (java.lang.reflect.Field)12 URL (java.net.URL)11 NamespaceBundles (org.apache.pulsar.common.naming.NamespaceBundles)11 Policies (org.apache.pulsar.common.policies.data.Policies)10 PulsarServerException (org.apache.pulsar.broker.PulsarServerException)8 BundlesData (org.apache.pulsar.common.policies.data.BundlesData)8 KeeperException (org.apache.zookeeper.KeeperException)8 ArrayList (java.util.ArrayList)7 Map (java.util.Map)7 HashSet (java.util.HashSet)6 CompletableFuture (java.util.concurrent.CompletableFuture)6