Search in sources :

Example 1 with LeaderBroker

use of org.apache.pulsar.broker.loadbalance.LeaderBroker in project pulsar by apache.

the class NamespaceService method searchForCandidateBroker.

private void searchForCandidateBroker(NamespaceBundle bundle, CompletableFuture<Optional<LookupResult>> lookupFuture, LookupOptions options) {
    if (null == pulsar.getLeaderElectionService()) {
        LOG.warn("The leader election has not yet been completed! NamespaceBundle[{}]", bundle);
        lookupFuture.completeExceptionally(new IllegalStateException("The leader election has not yet been completed!"));
        return;
    }
    String candidateBroker = null;
    LeaderElectionService les = pulsar.getLeaderElectionService();
    if (les == null) {
        // The leader election service was not initialized yet. This can happen because the broker service is
        // initialized first and it might start receiving lookup requests before the leader election service is
        // fully initialized.
        LOG.warn("Leader election service isn't initialized yet. " + "Returning empty result to lookup. NamespaceBundle[{}]", bundle);
        lookupFuture.complete(Optional.empty());
        return;
    }
    boolean authoritativeRedirect = les.isLeader();
    try {
        // check if this is Heartbeat or SLAMonitor namespace
        candidateBroker = checkHeartbeatNamespace(bundle);
        if (candidateBroker == null) {
            candidateBroker = checkHeartbeatNamespaceV2(bundle);
        }
        if (candidateBroker == null) {
            String broker = getSLAMonitorBrokerName(bundle);
            // checking if the broker is up and running
            if (broker != null && isBrokerActive(broker)) {
                candidateBroker = broker;
            }
        }
        if (candidateBroker == null) {
            Optional<LeaderBroker> currentLeader = pulsar.getLeaderElectionService().getCurrentLeader();
            if (options.isAuthoritative()) {
                // leader broker already assigned the current broker as owner
                candidateBroker = pulsar.getSafeWebServiceAddress();
            } else {
                LoadManager loadManager = this.loadManager.get();
                boolean makeLoadManagerDecisionOnThisBroker = !loadManager.isCentralized() || les.isLeader();
                if (!makeLoadManagerDecisionOnThisBroker) {
                    // If leader is not active, fallback to pick the least loaded from current broker loadmanager
                    boolean leaderBrokerActive = currentLeader.isPresent() && isBrokerActive(currentLeader.get().getServiceUrl());
                    if (!leaderBrokerActive) {
                        makeLoadManagerDecisionOnThisBroker = true;
                        if (!currentLeader.isPresent()) {
                            LOG.warn("The information about the current leader broker wasn't available. " + "Handling load manager decisions in a decentralized way. " + "NamespaceBundle[{}]", bundle);
                        } else {
                            LOG.warn("The current leader broker {} isn't active. " + "Handling load manager decisions in a decentralized way. " + "NamespaceBundle[{}]", currentLeader.get(), bundle);
                        }
                    }
                }
                if (makeLoadManagerDecisionOnThisBroker) {
                    Optional<String> availableBroker = getLeastLoadedFromLoadManager(bundle);
                    if (!availableBroker.isPresent()) {
                        LOG.warn("Load manager didn't return any available broker. " + "Returning empty result to lookup. NamespaceBundle[{}]", bundle);
                        lookupFuture.complete(Optional.empty());
                        return;
                    }
                    candidateBroker = availableBroker.get();
                    authoritativeRedirect = true;
                } else {
                    // forward to leader broker to make assignment
                    candidateBroker = currentLeader.get().getServiceUrl();
                }
            }
        }
    } catch (Exception e) {
        LOG.warn("Error when searching for candidate broker to acquire {}: {}", bundle, e.getMessage(), e);
        lookupFuture.completeExceptionally(e);
        return;
    }
    try {
        checkNotNull(candidateBroker);
        if (candidateBroker.equals(pulsar.getSafeWebServiceAddress())) {
            // Load manager decided that the local broker should try to become the owner
            ownershipCache.tryAcquiringOwnership(bundle).thenAccept(ownerInfo -> {
                if (ownerInfo.isDisabled()) {
                    if (LOG.isDebugEnabled()) {
                        LOG.debug("Namespace bundle {} is currently being unloaded", bundle);
                    }
                    lookupFuture.completeExceptionally(new IllegalStateException(String.format("Namespace bundle %s is currently being unloaded", bundle)));
                } else {
                    if (options.isLoadTopicsInBundle()) {
                        // Schedule the task to pre-load topics
                        pulsar.loadNamespaceTopics(bundle);
                    }
                    // find the target
                    if (options.hasAdvertisedListenerName()) {
                        AdvertisedListener listener = ownerInfo.getAdvertisedListeners().get(options.getAdvertisedListenerName());
                        if (listener == null) {
                            lookupFuture.completeExceptionally(new PulsarServerException("the broker do not have " + options.getAdvertisedListenerName() + " listener"));
                            return;
                        } else {
                            URI url = listener.getBrokerServiceUrl();
                            URI urlTls = listener.getBrokerServiceUrlTls();
                            lookupFuture.complete(Optional.of(new LookupResult(ownerInfo, url == null ? null : url.toString(), urlTls == null ? null : urlTls.toString())));
                            return;
                        }
                    } else {
                        lookupFuture.complete(Optional.of(new LookupResult(ownerInfo)));
                        return;
                    }
                }
            }).exceptionally(exception -> {
                LOG.warn("Failed to acquire ownership for namespace bundle {}: {}", bundle, exception);
                lookupFuture.completeExceptionally(new PulsarServerException("Failed to acquire ownership for namespace bundle " + bundle, exception));
                return null;
            });
        } else {
            if (LOG.isDebugEnabled()) {
                LOG.debug("Redirecting to broker {} to acquire ownership of bundle {}", candidateBroker, bundle);
            }
            // Now setting the redirect url
            createLookupResult(candidateBroker, authoritativeRedirect, options.getAdvertisedListenerName()).thenAccept(lookupResult -> lookupFuture.complete(Optional.of(lookupResult))).exceptionally(ex -> {
                lookupFuture.completeExceptionally(ex);
                return null;
            });
        }
    } catch (Exception e) {
        LOG.warn("Error in trying to acquire namespace bundle ownership for {}: {}", bundle, e.getMessage(), e);
        lookupFuture.completeExceptionally(e);
    }
}
Also used : ServiceUnitNotReadyException(org.apache.pulsar.broker.service.BrokerServiceException.ServiceUnitNotReadyException) ClusterDataImpl(org.apache.pulsar.common.policies.data.ClusterDataImpl) Topic(org.apache.pulsar.broker.service.Topic) PulsarClientImpl(org.apache.pulsar.client.impl.PulsarClientImpl) URL(java.net.URL) LoggerFactory(org.slf4j.LoggerFactory) LoadManager(org.apache.pulsar.broker.loadbalance.LoadManager) StringUtils(org.apache.commons.lang3.StringUtils) NamespaceBundleSplitAlgorithm(org.apache.pulsar.common.naming.NamespaceBundleSplitAlgorithm) NamespaceBundles(org.apache.pulsar.common.naming.NamespaceBundles) NamespaceIsolationPolicies(org.apache.pulsar.common.policies.impl.NamespaceIsolationPolicies) Preconditions.checkArgument(com.google.common.base.Preconditions.checkArgument) Matcher(java.util.regex.Matcher) MetadataCache(org.apache.pulsar.metadata.api.MetadataCache) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) NamespaceOwnershipStatus(org.apache.pulsar.common.policies.data.NamespaceOwnershipStatus) Map(java.util.Map) ListUtils(org.apache.commons.collections4.ListUtils) NamespaceName(org.apache.pulsar.common.naming.NamespaceName) URI(java.net.URI) PulsarClientException(org.apache.pulsar.client.api.PulsarClientException) AdvertisedListener(org.apache.pulsar.policies.data.loadbalancer.AdvertisedListener) MetadataStoreException(org.apache.pulsar.metadata.api.MetadataStoreException) NamespaceIsolationPolicy(org.apache.pulsar.common.policies.NamespaceIsolationPolicy) Set(java.util.Set) LocalPolicies(org.apache.pulsar.common.policies.data.LocalPolicies) Collectors(java.util.stream.Collectors) String.format(java.lang.String.format) Mode(org.apache.pulsar.common.api.proto.CommandGetTopicsOfNamespace.Mode) NamespaceBundleFactory(org.apache.pulsar.common.naming.NamespaceBundleFactory) List(java.util.List) ServiceUnitId(org.apache.pulsar.common.naming.ServiceUnitId) FutureUtil(org.apache.pulsar.common.util.FutureUtil) StringUtils.isNotBlank(org.apache.commons.lang3.StringUtils.isNotBlank) ConcurrentOpenHashMap(org.apache.pulsar.common.util.collections.ConcurrentOpenHashMap) ClientBuilderImpl(org.apache.pulsar.client.impl.ClientBuilderImpl) ClientConfigurationData(org.apache.pulsar.client.impl.conf.ClientConfigurationData) ClientBuilder(org.apache.pulsar.client.api.ClientBuilder) Optional(java.util.Optional) Pattern(java.util.regex.Pattern) LeaderBroker(org.apache.pulsar.broker.loadbalance.LeaderBroker) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) TopicName(org.apache.pulsar.common.naming.TopicName) Hashing(com.google.common.hash.Hashing) HashMap(java.util.HashMap) CompletableFuture(java.util.concurrent.CompletableFuture) ResourceUnit(org.apache.pulsar.broker.loadbalance.ResourceUnit) PulsarAdmin(org.apache.pulsar.client.admin.PulsarAdmin) Counter(io.prometheus.client.Counter) AtomicReference(java.util.concurrent.atomic.AtomicReference) CollectionUtils(org.apache.commons.collections4.CollectionUtils) Lists(com.google.common.collect.Lists) BundleSplitOption(org.apache.pulsar.common.naming.BundleSplitOption) PulsarClient(org.apache.pulsar.client.api.PulsarClient) NamespaceBundle(org.apache.pulsar.common.naming.NamespaceBundle) TopicDomain(org.apache.pulsar.common.naming.TopicDomain) LeaderElectionService(org.apache.pulsar.broker.loadbalance.LeaderElectionService) Summary(org.apache.pulsar.broker.stats.prometheus.metrics.Summary) Logger(org.slf4j.Logger) PulsarWebResource(org.apache.pulsar.broker.web.PulsarWebResource) ServiceConfiguration(org.apache.pulsar.broker.ServiceConfiguration) LocalBrokerData(org.apache.pulsar.policies.data.loadbalancer.LocalBrokerData) Preconditions.checkNotNull(com.google.common.base.Preconditions.checkNotNull) LookupData(org.apache.pulsar.common.lookup.data.LookupData) PulsarService(org.apache.pulsar.broker.PulsarService) TimeUnit(java.util.concurrent.TimeUnit) LookupResult(org.apache.pulsar.broker.lookup.LookupResult) PulsarServerException(org.apache.pulsar.broker.PulsarServerException) NonPersistentTopic(org.apache.pulsar.broker.service.nonpersistent.NonPersistentTopic) Collections(java.util.Collections) SECONDS(java.util.concurrent.TimeUnit.SECONDS) BrokerAssignment(org.apache.pulsar.common.policies.data.BrokerAssignment) PulsarServerException(org.apache.pulsar.broker.PulsarServerException) LoadManager(org.apache.pulsar.broker.loadbalance.LoadManager) AdvertisedListener(org.apache.pulsar.policies.data.loadbalancer.AdvertisedListener) URI(java.net.URI) ServiceUnitNotReadyException(org.apache.pulsar.broker.service.BrokerServiceException.ServiceUnitNotReadyException) PulsarClientException(org.apache.pulsar.client.api.PulsarClientException) MetadataStoreException(org.apache.pulsar.metadata.api.MetadataStoreException) PulsarServerException(org.apache.pulsar.broker.PulsarServerException) LookupResult(org.apache.pulsar.broker.lookup.LookupResult) LeaderElectionService(org.apache.pulsar.broker.loadbalance.LeaderElectionService) LeaderBroker(org.apache.pulsar.broker.loadbalance.LeaderBroker)

Example 2 with LeaderBroker

use of org.apache.pulsar.broker.loadbalance.LeaderBroker in project pulsar by yahoo.

the class AdminApiTest method brokers.

@Test
public void brokers() throws Exception {
    List<String> list = admin.brokers().getActiveBrokers("test");
    Assert.assertNotNull(list);
    Assert.assertEquals(list.size(), 1);
    List<String> list2 = otheradmin.brokers().getActiveBrokers("test");
    Assert.assertNotNull(list2);
    Assert.assertEquals(list2.size(), 1);
    BrokerInfo leaderBroker = admin.brokers().getLeaderBroker();
    Assert.assertEquals(leaderBroker.getServiceUrl(), pulsar.getLeaderElectionService().getCurrentLeader().map(LeaderBroker::getServiceUrl).get());
    Map<String, NamespaceOwnershipStatus> nsMap = admin.brokers().getOwnedNamespaces("test", list.get(0));
    // since sla-monitor ns is not created nsMap.size() == 1 (for HeartBeat Namespace)
    Assert.assertEquals(nsMap.size(), 2);
    for (String ns : nsMap.keySet()) {
        NamespaceOwnershipStatus nsStatus = nsMap.get(ns);
        if (ns.equals(NamespaceService.getHeartbeatNamespace(pulsar.getAdvertisedAddress(), pulsar.getConfiguration()) + "/0x00000000_0xffffffff")) {
            assertEquals(nsStatus.broker_assignment, BrokerAssignment.shared);
            assertFalse(nsStatus.is_controlled);
            assertTrue(nsStatus.is_active);
        }
    }
    String[] parts = list.get(0).split(":");
    Assert.assertEquals(parts.length, 2);
    Map<String, NamespaceOwnershipStatus> nsMap2 = adminTls.brokers().getOwnedNamespaces("test", String.format("%s:%d", parts[0], pulsar.getListenPortHTTPS().get()));
    Assert.assertEquals(nsMap2.size(), 2);
    admin.namespaces().deleteNamespace("prop-xyz/ns1");
    admin.clusters().deleteCluster("test");
    assertEquals(admin.clusters().getClusters(), Lists.newArrayList());
}
Also used : NamespaceOwnershipStatus(org.apache.pulsar.common.policies.data.NamespaceOwnershipStatus) LeaderBroker(org.apache.pulsar.broker.loadbalance.LeaderBroker) BrokerInfo(org.apache.pulsar.common.policies.data.BrokerInfo) Test(org.testng.annotations.Test) MockedPulsarServiceBaseTest(org.apache.pulsar.broker.auth.MockedPulsarServiceBaseTest)

Example 3 with LeaderBroker

use of org.apache.pulsar.broker.loadbalance.LeaderBroker in project pulsar by yahoo.

the class AdminTest method brokers.

@Test
@SuppressWarnings("unchecked")
public void brokers() throws Exception {
    asyncRequests(ctx -> clusters.createCluster(ctx, "use", ClusterDataImpl.builder().serviceUrl("http://broker.messaging.use.example.com").serviceUrlTls("https://broker.messaging.use.example.com:4443").build()));
    URI requestUri = new URI("http://broker.messaging.use.example.com:8080/admin/brokers/use");
    UriInfo mockUri = mock(UriInfo.class);
    doReturn(requestUri).when(mockUri).getRequestUri();
    Field uriField = PulsarWebResource.class.getDeclaredField("uri");
    uriField.setAccessible(true);
    uriField.set(brokers, mockUri);
    Object res = asyncRequests(ctx -> brokers.getActiveBrokers(ctx, "use"));
    assertTrue(res instanceof Set);
    Set<String> activeBrokers = (Set<String>) res;
    assertEquals(activeBrokers.size(), 1);
    assertEquals(activeBrokers, Sets.newHashSet(pulsar.getAdvertisedAddress() + ":" + pulsar.getListenPortHTTP().get()));
    Object leaderBrokerRes = asyncRequests(ctx -> brokers.getLeaderBroker(ctx));
    assertTrue(leaderBrokerRes instanceof BrokerInfo);
    BrokerInfo leaderBroker = (BrokerInfo) leaderBrokerRes;
    assertEquals(leaderBroker.getServiceUrl(), pulsar.getLeaderElectionService().getCurrentLeader().map(LeaderBroker::getServiceUrl).get());
}
Also used : Field(java.lang.reflect.Field) Set(java.util.Set) LeaderBroker(org.apache.pulsar.broker.loadbalance.LeaderBroker) URI(java.net.URI) UriInfo(javax.ws.rs.core.UriInfo) BrokerInfo(org.apache.pulsar.common.policies.data.BrokerInfo) Test(org.testng.annotations.Test) MockedPulsarServiceBaseTest(org.apache.pulsar.broker.auth.MockedPulsarServiceBaseTest)

Example 4 with LeaderBroker

use of org.apache.pulsar.broker.loadbalance.LeaderBroker in project pulsar by yahoo.

the class AdminApiMultiBrokersTest method testGetLeaderBroker.

@Test(timeOut = 30 * 1000)
public void testGetLeaderBroker() throws ExecutionException, InterruptedException, PulsarAdminException {
    List<PulsarService> allBrokers = getAllBrokers();
    Optional<LeaderBroker> leaderBroker = allBrokers.get(0).getLeaderElectionService().readCurrentLeader().get();
    assertTrue(leaderBroker.isPresent());
    log.info("Leader broker is {}", leaderBroker);
    for (PulsarAdmin admin : getAllAdmins()) {
        String serviceUrl = admin.brokers().getLeaderBroker().getServiceUrl();
        log.info("Pulsar admin get leader broker is {}", serviceUrl);
        assertEquals(leaderBroker.get().getServiceUrl(), serviceUrl);
    }
}
Also used : PulsarService(org.apache.pulsar.broker.PulsarService) PulsarAdmin(org.apache.pulsar.client.admin.PulsarAdmin) LeaderBroker(org.apache.pulsar.broker.loadbalance.LeaderBroker) MultiBrokerBaseTest(org.apache.pulsar.broker.MultiBrokerBaseTest) Test(org.testng.annotations.Test)

Example 5 with LeaderBroker

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

the class AdminApiTest method brokers.

@Test
public void brokers() throws Exception {
    List<String> list = admin.brokers().getActiveBrokers("test");
    Assert.assertNotNull(list);
    Assert.assertEquals(list.size(), 1);
    List<String> list2 = otheradmin.brokers().getActiveBrokers("test");
    Assert.assertNotNull(list2);
    Assert.assertEquals(list2.size(), 1);
    BrokerInfo leaderBroker = admin.brokers().getLeaderBroker();
    Assert.assertEquals(leaderBroker.getServiceUrl(), pulsar.getLeaderElectionService().getCurrentLeader().map(LeaderBroker::getServiceUrl).get());
    Map<String, NamespaceOwnershipStatus> nsMap = admin.brokers().getOwnedNamespaces("test", list.get(0));
    // since sla-monitor ns is not created nsMap.size() == 1 (for HeartBeat Namespace)
    Assert.assertEquals(nsMap.size(), 2);
    for (String ns : nsMap.keySet()) {
        NamespaceOwnershipStatus nsStatus = nsMap.get(ns);
        if (ns.equals(NamespaceService.getHeartbeatNamespace(pulsar.getAdvertisedAddress(), pulsar.getConfiguration()) + "/0x00000000_0xffffffff")) {
            assertEquals(nsStatus.broker_assignment, BrokerAssignment.shared);
            assertFalse(nsStatus.is_controlled);
            assertTrue(nsStatus.is_active);
        }
    }
    String[] parts = list.get(0).split(":");
    Assert.assertEquals(parts.length, 2);
    Map<String, NamespaceOwnershipStatus> nsMap2 = adminTls.brokers().getOwnedNamespaces("test", String.format("%s:%d", parts[0], pulsar.getListenPortHTTPS().get()));
    Assert.assertEquals(nsMap2.size(), 2);
    admin.namespaces().deleteNamespace("prop-xyz/ns1");
    admin.clusters().deleteCluster("test");
    assertEquals(admin.clusters().getClusters(), Lists.newArrayList());
}
Also used : NamespaceOwnershipStatus(org.apache.pulsar.common.policies.data.NamespaceOwnershipStatus) LeaderBroker(org.apache.pulsar.broker.loadbalance.LeaderBroker) BrokerInfo(org.apache.pulsar.common.policies.data.BrokerInfo) Test(org.testng.annotations.Test) MockedPulsarServiceBaseTest(org.apache.pulsar.broker.auth.MockedPulsarServiceBaseTest)

Aggregations

LeaderBroker (org.apache.pulsar.broker.loadbalance.LeaderBroker)12 Test (org.testng.annotations.Test)9 URI (java.net.URI)6 Set (java.util.Set)6 PulsarService (org.apache.pulsar.broker.PulsarService)6 MockedPulsarServiceBaseTest (org.apache.pulsar.broker.auth.MockedPulsarServiceBaseTest)6 PulsarAdmin (org.apache.pulsar.client.admin.PulsarAdmin)6 NamespaceOwnershipStatus (org.apache.pulsar.common.policies.data.NamespaceOwnershipStatus)6 BrokerInfo (org.apache.pulsar.common.policies.data.BrokerInfo)4 Preconditions.checkArgument (com.google.common.base.Preconditions.checkArgument)3 Preconditions.checkNotNull (com.google.common.base.Preconditions.checkNotNull)3 Lists (com.google.common.collect.Lists)3 Hashing (com.google.common.hash.Hashing)3 Counter (io.prometheus.client.Counter)3 String.format (java.lang.String.format)3 URL (java.net.URL)3 Collections (java.util.Collections)3 List (java.util.List)3 Map (java.util.Map)3 Optional (java.util.Optional)3