use of com.yahoo.pulsar.broker.loadbalance.impl.SimpleResourceUnit in project pulsar by yahoo.
the class BrokerServiceLookupTest method testMultipleBrokerLookup.
/**
* UsecaseL Multiple Broker => Lookup Redirection test
*
* 1. Broker1 is a leader
* 2. Lookup request reaches to Broker2 which redirects to leader (Broker1) with authoritative = false
* 3. Leader (Broker1) finds out least loaded broker as Broker2 and redirects request to Broker2 with authoritative = true
* 4. Broker2 receives final request to own a bundle with authoritative = true and client connects to Broker2
*
* @throws Exception
*/
@Test
public void testMultipleBrokerLookup() throws Exception {
log.info("-- Starting {} test --", methodName);
/**** start broker-2 ****/
ServiceConfiguration conf2 = new ServiceConfiguration();
conf2.setBrokerServicePort(PortManager.nextFreePort());
conf2.setBrokerServicePortTls(PortManager.nextFreePort());
conf2.setWebServicePort(PortManager.nextFreePort());
conf2.setWebServicePortTls(PortManager.nextFreePort());
conf2.setAdvertisedAddress("localhost");
conf2.setClusterName(conf.getClusterName());
PulsarService pulsar2 = startBroker(conf2);
pulsar.getLoadManager().writeLoadReportOnZookeeper();
pulsar2.getLoadManager().writeLoadReportOnZookeeper();
LoadManager loadManager1 = spy(pulsar.getLoadManager());
LoadManager loadManager2 = spy(pulsar2.getLoadManager());
Field loadManagerField = NamespaceService.class.getDeclaredField("loadManager");
loadManagerField.setAccessible(true);
// mock: redirect request to leader [2]
doReturn(true).when(loadManager2).isCentralized();
loadManagerField.set(pulsar2.getNamespaceService(), loadManager2);
// mock: return Broker2 as a Least-loaded broker when leader receies request [3]
doReturn(true).when(loadManager1).isCentralized();
SimpleResourceUnit resourceUnit = new SimpleResourceUnit(pulsar2.getWebServiceAddress(), null);
doReturn(resourceUnit).when(loadManager1).getLeastLoaded(any(ServiceUnitId.class));
loadManagerField.set(pulsar.getNamespaceService(), loadManager1);
/**** started broker-2 ****/
URI brokerServiceUrl = new URI("pulsar://localhost:" + conf2.getBrokerServicePort());
PulsarClient pulsarClient2 = PulsarClient.create(brokerServiceUrl.toString(), new ClientConfiguration());
// load namespace-bundle by calling Broker2
Consumer consumer = pulsarClient2.subscribe("persistent://my-property/use/my-ns/my-topic1", "my-subscriber-name", new ConsumerConfiguration());
Producer producer = pulsarClient.createProducer("persistent://my-property/use/my-ns/my-topic1", new ProducerConfiguration());
for (int i = 0; i < 10; i++) {
String message = "my-message-" + i;
producer.send(message.getBytes());
}
Message msg = null;
Set<String> messageSet = Sets.newHashSet();
for (int i = 0; i < 10; i++) {
msg = consumer.receive(5, TimeUnit.SECONDS);
String receivedMessage = new String(msg.getData());
log.debug("Received message: [{}]", receivedMessage);
String expectedMessage = "my-message-" + i;
testMessageOrderAndDuplicates(messageSet, receivedMessage, expectedMessage);
}
// Acknowledge the consumption of all messages at once
consumer.acknowledgeCumulative(msg);
consumer.close();
producer.close();
pulsarClient2.close();
pulsar2.close();
loadManager1 = null;
loadManager2 = null;
}
use of com.yahoo.pulsar.broker.loadbalance.impl.SimpleResourceUnit in project pulsar by yahoo.
the class LoadBalancerTest method testLoadBalanceDistributionAmongUnequallyLoaded.
@Test(enabled = false)
void testLoadBalanceDistributionAmongUnequallyLoaded() throws Exception {
long memoryMB = 4096;
long cpuPercent = 25;
long bInMbps = 256;
long bOutMbps = 256;
long threads = 25;
LoadManager loadManager = new SimpleLoadManagerImpl(pulsarServices[0]);
ZooKeeperCache mockCache = mock(ZooKeeperCache.class);
Set<String> activeBrokers = Sets.newHashSet("prod1-broker1.messaging.use.example.com:8080", "prod1-broker2.messaging.use.example.com:8080", "prod1-broker3.messaging.use.example.com:8080");
when(mockCache.getChildren(SimpleLoadManagerImpl.LOADBALANCE_BROKERS_ROOT)).thenReturn(activeBrokers);
when(mockCache.getChildren(SimpleLoadManagerImpl.LOADBALANCE_BROKERS_ROOT)).thenReturn(activeBrokers);
Field zkCacheField = PulsarService.class.getDeclaredField("localZkCache");
zkCacheField.setAccessible(true);
zkCacheField.set(pulsarServices[0], mockCache);
int totalAvailabilityWeight = 0;
TreeMap<Long, Set<ResourceUnit>> sortedRankingsInstance = new TreeMap<Long, Set<ResourceUnit>>();
for (int i = 1; i <= 3; i++) {
PulsarResourceDescription rd = createResourceDescription(memoryMB * i, cpuPercent * i, bInMbps * i, bOutMbps * 2, threads * i);
ResourceUnit ru1 = new SimpleResourceUnit(String.format("http://prod1-broker%d.messaging.use.example.com:8080", i), rd);
LoadRanker ranker = new ResourceAvailabilityRanker();
long rank = ranker.getRank(rd);
if (sortedRankingsInstance.containsKey(rank)) {
// get the object set and put the rd in it
sortedRankingsInstance.get(rank).add(ru1);
} else {
Set<ResourceUnit> rus = new HashSet<ResourceUnit>();
rus.add(ru1);
sortedRankingsInstance.put(rank, rus);
}
totalAvailabilityWeight += rank;
}
Field sortedRankings = SimpleLoadManagerImpl.class.getDeclaredField("sortedRankings");
sortedRankings.setAccessible(true);
AtomicReference<TreeMap<Long, Set<ResourceUnit>>> ar = new AtomicReference<TreeMap<Long, Set<ResourceUnit>>>();
ar.set(sortedRankingsInstance);
sortedRankings.set(loadManager, ar);
int totalNamespaces = 1000;
Map<String, Integer> namespaceOwner = new HashMap<String, Integer>();
for (int i = 0; i < totalNamespaces; i++) {
ResourceUnit found = loadManager.getLeastLoaded(DestinationName.get("persistent://pulsar/use/primary-ns/topic-" + i));
if (namespaceOwner.containsKey(found.getResourceId())) {
namespaceOwner.put(found.getResourceId(), namespaceOwner.get(found.getResourceId()) + 1);
} else {
namespaceOwner.put(found.getResourceId(), 0);
}
}
for (Map.Entry<Long, Set<ResourceUnit>> entry : sortedRankingsInstance.entrySet()) {
int selectionProbability = (int) (((double) entry.getKey() / totalAvailabilityWeight) * 100);
int idealExpectedOwned = selectionProbability * (int) ((double) totalNamespaces / 100);
int expectedOwnedLowerBound = idealExpectedOwned - idealExpectedOwned / 10;
int expectedOwnedUpperBound = idealExpectedOwned + idealExpectedOwned / 10;
for (ResourceUnit ru : entry.getValue()) {
assertTrue(namespaceOwner.containsKey(ru.getResourceId()));
int ownedNamespaces = namespaceOwner.get(ru.getResourceId());
assertTrue(ownedNamespaces > expectedOwnedLowerBound || ownedNamespaces < expectedOwnedUpperBound);
}
}
}
use of com.yahoo.pulsar.broker.loadbalance.impl.SimpleResourceUnit in project pulsar by yahoo.
the class LoadBalancerTest method testLoadbalanceDistributionAmongEquallyLoaded.
/*
* Simple Test, creates three Resource Units (brokers) with equal load and expects that out of 1005 namespaces it
* should be divided fairly equally with about 10% of variation
*
*/
@Test(enabled = false)
public void testLoadbalanceDistributionAmongEquallyLoaded() throws Exception {
LoadManager loadManager = new SimpleLoadManagerImpl(pulsarServices[0]);
ZooKeeperCache mockCache = mock(ZooKeeperCache.class);
Set<String> activeBrokers = Sets.newHashSet("prod1-broker1.messaging.use.example.com:8080", "prod1-broker2.messaging.use.example.com:8080", "prod1-broker3.messaging.use.example.com:8080");
when(mockCache.getChildren(SimpleLoadManagerImpl.LOADBALANCE_BROKERS_ROOT)).thenReturn(activeBrokers);
when(mockCache.getChildren(SimpleLoadManagerImpl.LOADBALANCE_BROKERS_ROOT)).thenReturn(activeBrokers);
Field zkCacheField = PulsarService.class.getDeclaredField("localZkCache");
zkCacheField.setAccessible(true);
zkCacheField.set(pulsarServices[0], mockCache);
long memoryMB = 4096;
long cpuPercent = 45;
long bInMbps = 350;
long bOutMbps = 180;
long threads = 10;
// TODO move to its own test
PulsarResourceDescription rd = createResourceDescription(memoryMB, cpuPercent, bInMbps, bOutMbps, threads);
Set<ResourceUnit> rus = new HashSet<ResourceUnit>();
for (String broker : activeBrokers) {
ResourceUnit ru = new SimpleResourceUnit(broker, rd);
rus.add(ru);
}
TreeMap<Long, Set<ResourceUnit>> sortedRankingsInstance = new TreeMap<Long, Set<ResourceUnit>>();
LoadRanker ranker = new ResourceAvailabilityRanker();
sortedRankingsInstance.put(ranker.getRank(rd), rus);
Field sortedRankings = SimpleLoadManagerImpl.class.getDeclaredField("sortedRankings");
sortedRankings.setAccessible(true);
AtomicReference<TreeMap<Long, Set<ResourceUnit>>> ar = new AtomicReference<TreeMap<Long, Set<ResourceUnit>>>();
ar.set(sortedRankingsInstance);
sortedRankings.set(loadManager, ar);
}
use of com.yahoo.pulsar.broker.loadbalance.impl.SimpleResourceUnit in project pulsar by yahoo.
the class LoadBalancerTest method testGetLeastLoadedBasic.
@Test(enabled = false)
public void testGetLeastLoadedBasic() throws Exception {
LocalZooKeeperCache mockCache = mock(LocalZooKeeperCache.class);
Set<String> activeBrokers = Sets.newHashSet("prod1-broker1.messaging.use.example.com:8080", "prod1-broker2.messaging.use.example.com:8080", "prod1-broker3.messaging.use.example.com:8080");
when(mockCache.getChildren(SimpleLoadManagerImpl.LOADBALANCE_BROKERS_ROOT)).thenReturn(activeBrokers);
Field zkCacheField = PulsarService.class.getDeclaredField("localZkCache");
zkCacheField.setAccessible(true);
LocalZooKeeperCache originalLZK1 = (LocalZooKeeperCache) zkCacheField.get(pulsarServices[0]);
LocalZooKeeperCache originalLZK2 = (LocalZooKeeperCache) zkCacheField.get(pulsarServices[1]);
zkCacheField.set(pulsarServices[0], mockCache);
zkCacheField.set(pulsarServices[1], mockCache);
LoadManager loadManager = new SimpleLoadManagerImpl(pulsarServices[0]);
// TODO move to its own test
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://prod1-broker1.messaging.use.example.com:8080", rd);
Set<ResourceUnit> rus = new HashSet<ResourceUnit>();
rus.add(ru1);
LoadRanker lr = new ResourceAvailabilityRanker();
AtomicReference<Map<Long, Set<ResourceUnit>>> sortedRankingsInstance = new AtomicReference<>(Maps.newTreeMap());
sortedRankingsInstance.get().put(lr.getRank(rd), rus);
Field sortedRankings = SimpleLoadManagerImpl.class.getDeclaredField("sortedRankings");
sortedRankings.setAccessible(true);
sortedRankings.set(loadManager, sortedRankingsInstance);
ResourceUnit found = ((SimpleLoadManagerImpl) loadManager).getLeastLoaded(new NamespaceName("pulsar/use/primary-ns.10"));
assertEquals("http://prod1-broker1.messaging.use.example.com:8080", found.getResourceId());
zkCacheField.set(pulsarServices[0], originalLZK1);
zkCacheField.set(pulsarServices[1], originalLZK2);
}
use of com.yahoo.pulsar.broker.loadbalance.impl.SimpleResourceUnit in project pulsar by yahoo.
the class BrokerServiceLookupTest method testWebserviceServiceTls.
/**
* 1. Start broker1 and broker2 with tls enable
* 2. Hit HTTPS lookup url at broker2 which redirects to HTTPS broker1
*
* @throws Exception
*/
@Test
public void testWebserviceServiceTls() throws Exception {
log.info("-- Starting {} test --", methodName);
final String TLS_SERVER_CERT_FILE_PATH = "./src/test/resources/certificate/server.crt";
final String TLS_SERVER_KEY_FILE_PATH = "./src/test/resources/certificate/server.key";
final String TLS_CLIENT_CERT_FILE_PATH = "./src/test/resources/certificate/client.crt";
final String TLS_CLIENT_KEY_FILE_PATH = "./src/test/resources/certificate/client.key";
/**** start broker-2 ****/
ServiceConfiguration conf2 = new ServiceConfiguration();
conf2.setBrokerServicePort(PortManager.nextFreePort());
conf2.setBrokerServicePortTls(PortManager.nextFreePort());
conf2.setWebServicePort(PortManager.nextFreePort());
conf2.setWebServicePortTls(PortManager.nextFreePort());
conf2.setAdvertisedAddress("localhost");
conf2.setTlsAllowInsecureConnection(true);
conf2.setTlsEnabled(true);
conf2.setTlsCertificateFilePath(TLS_SERVER_CERT_FILE_PATH);
conf2.setTlsKeyFilePath(TLS_SERVER_KEY_FILE_PATH);
conf2.setClusterName(conf.getClusterName());
PulsarService pulsar2 = startBroker(conf2);
// restart broker1 with tls enabled
conf.setTlsAllowInsecureConnection(true);
conf.setTlsEnabled(true);
conf.setTlsCertificateFilePath(TLS_SERVER_CERT_FILE_PATH);
conf.setTlsKeyFilePath(TLS_SERVER_KEY_FILE_PATH);
stopBroker();
startBroker();
pulsar.getLoadManager().writeLoadReportOnZookeeper();
pulsar2.getLoadManager().writeLoadReportOnZookeeper();
LoadManager loadManager1 = spy(pulsar.getLoadManager());
LoadManager loadManager2 = spy(pulsar2.getLoadManager());
Field loadManagerField = NamespaceService.class.getDeclaredField("loadManager");
loadManagerField.setAccessible(true);
// mock: redirect request to leader [2]
doReturn(true).when(loadManager2).isCentralized();
loadManagerField.set(pulsar2.getNamespaceService(), loadManager2);
// mock: return Broker2 as a Least-loaded broker when leader receies
// request [3]
doReturn(true).when(loadManager1).isCentralized();
SimpleResourceUnit resourceUnit = new SimpleResourceUnit(pulsar2.getWebServiceAddress(), null);
doReturn(resourceUnit).when(loadManager1).getLeastLoaded(any(ServiceUnitId.class));
loadManagerField.set(pulsar.getNamespaceService(), loadManager1);
/**** started broker-2 ****/
URI brokerServiceUrl = new URI("pulsar://localhost:" + conf2.getBrokerServicePort());
PulsarClient pulsarClient2 = PulsarClient.create(brokerServiceUrl.toString(), new ClientConfiguration());
final String lookupResourceUrl = "/lookup/v2/destination/persistent/my-property/use/my-ns/my-topic1";
// set client cert_key file
KeyManager[] keyManagers = null;
Certificate[] tlsCert = SecurityUtility.loadCertificatesFromPemFile(TLS_CLIENT_CERT_FILE_PATH);
PrivateKey tlsKey = SecurityUtility.loadPrivateKeyFromPemFile(TLS_CLIENT_KEY_FILE_PATH);
KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
ks.load(null, null);
ks.setKeyEntry("private", tlsKey, "".toCharArray(), tlsCert);
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(ks, "".toCharArray());
keyManagers = kmf.getKeyManagers();
TrustManager[] trustManagers = InsecureTrustManagerFactory.INSTANCE.getTrustManagers();
SSLContext sslCtx = SSLContext.getInstance("TLS");
sslCtx.init(keyManagers, trustManagers, new SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sslCtx.getSocketFactory());
// hit broker2 url
URLConnection con = new URL(pulsar2.getWebServiceAddressTls() + lookupResourceUrl).openConnection();
log.info("orignal url: {}", con.getURL());
con.connect();
log.info("connected url: {} ", con.getURL());
// assert connect-url: broker2-https
Assert.assertEquals(con.getURL().getPort(), conf2.getWebServicePortTls());
InputStream is = con.getInputStream();
// assert redirect-url: broker1-https only
log.info("redirected url: {}", con.getURL());
Assert.assertEquals(con.getURL().getPort(), conf.getWebServicePortTls());
is.close();
pulsarClient2.close();
pulsar2.close();
loadManager1 = null;
loadManager2 = null;
}
Aggregations