|
|
|
@ -15,7 +15,9 @@ |
|
|
|
*/ |
|
|
|
package org.thingsboard.server.queue.discovery; |
|
|
|
|
|
|
|
import com.datastax.driver.core.utils.UUIDs; |
|
|
|
import com.datastax.oss.driver.api.core.uuid.Uuids; |
|
|
|
import lombok.SneakyThrows; |
|
|
|
import lombok.extern.slf4j.Slf4j; |
|
|
|
import org.junit.Assert; |
|
|
|
import org.junit.Before; |
|
|
|
@ -30,12 +32,15 @@ import org.thingsboard.server.common.msg.queue.ServiceType; |
|
|
|
import org.thingsboard.server.common.msg.queue.TopicPartitionInfo; |
|
|
|
import org.thingsboard.server.gen.transport.TransportProtos; |
|
|
|
|
|
|
|
import java.text.SimpleDateFormat; |
|
|
|
import java.util.ArrayList; |
|
|
|
import java.util.Collections; |
|
|
|
import java.util.Comparator; |
|
|
|
import java.util.HashMap; |
|
|
|
import java.util.List; |
|
|
|
import java.util.Map; |
|
|
|
import java.util.Random; |
|
|
|
import java.util.concurrent.TimeUnit; |
|
|
|
import java.util.stream.Collectors; |
|
|
|
|
|
|
|
import static org.mockito.Mockito.mock; |
|
|
|
@ -107,13 +112,15 @@ public class HashPartitionServiceTest { |
|
|
|
map.put(partition, map.getOrDefault(partition, 0) + 1); |
|
|
|
} |
|
|
|
|
|
|
|
printDispersion(start, map, ITERATIONS); |
|
|
|
checkDispersion(start, map, ITERATIONS, 1.0); |
|
|
|
} |
|
|
|
|
|
|
|
@SneakyThrows |
|
|
|
@Test |
|
|
|
public void testDispersionOnResolveByPartitionIdx() { |
|
|
|
int serverCount = 10; |
|
|
|
int queueCount = 10000; |
|
|
|
int serverCount = 5; |
|
|
|
int tenantCount = 1000; |
|
|
|
int queueCount = 3; |
|
|
|
int partitionCount = 3; |
|
|
|
|
|
|
|
List<TransportProtos.ServiceInfo> services = new ArrayList<>(); |
|
|
|
@ -126,28 +133,35 @@ public class HashPartitionServiceTest { |
|
|
|
Map<String, Integer> map = new HashMap<>(); |
|
|
|
services.forEach(s -> map.put(s.getServiceId(), 0)); |
|
|
|
|
|
|
|
for (int queueIndex = 0; queueIndex < queueCount; queueIndex++) { |
|
|
|
for (int partition = 0; partition < partitionCount; partition++) { |
|
|
|
TopicPartitionInfo tpi = new TopicPartitionInfo("tb_rule_engine.queue_" + queueIndex, TenantId.SYS_TENANT_ID, partition, false); |
|
|
|
TransportProtos.ServiceInfo serviceInfo = clusterRoutingService.resolveByPartitionIdx(services, tpi); |
|
|
|
String serviceId = serviceInfo.getServiceId(); |
|
|
|
map.put(serviceId, map.get(serviceId) + 1); |
|
|
|
Random random = new Random(); |
|
|
|
long ts = new SimpleDateFormat("dd-MM-yyyy").parse("06-12-2016").getTime() - TimeUnit.DAYS.toMillis(tenantCount); |
|
|
|
for (int tenantIndex = 0; tenantIndex < tenantCount; tenantIndex++) { |
|
|
|
TenantId tenantId = new TenantId(UUIDs.startOf(ts)); |
|
|
|
ts += TimeUnit.DAYS.toMillis(1) + random.nextInt(1000); |
|
|
|
for (int queueIndex = 0; queueIndex < queueCount; queueIndex++) { |
|
|
|
QueueKey queueKey = new QueueKey(ServiceType.TB_RULE_ENGINE, "queue" + queueIndex, tenantId); |
|
|
|
for (int partition = 0; partition < partitionCount; partition++) { |
|
|
|
TransportProtos.ServiceInfo serviceInfo = clusterRoutingService.resolveByPartitionIdx(services, queueKey, partition); |
|
|
|
String serviceId = serviceInfo.getServiceId(); |
|
|
|
map.put(serviceId, map.get(serviceId) + 1); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
printDispersion(start, map, queueCount * partitionCount); |
|
|
|
checkDispersion(start, map, tenantCount * queueCount * partitionCount, 10.0); |
|
|
|
} |
|
|
|
|
|
|
|
private <T> void printDispersion(long start, Map<T, Integer> map, int iterations) { |
|
|
|
private <T> void checkDispersion(long start, Map<T, Integer> map, int iterations, double maxDiffPercent) { |
|
|
|
List<Map.Entry<T, Integer>> data = map.entrySet().stream().sorted(Comparator.comparingInt(Map.Entry::getValue)).collect(Collectors.toList()); |
|
|
|
long end = System.currentTimeMillis(); |
|
|
|
double diff = (data.get(data.size() - 1).getValue() - data.get(0).getValue()); |
|
|
|
double diffPercent = (diff / iterations) * 100.0; |
|
|
|
double ideal = ((double) iterations) / map.size(); |
|
|
|
double diff = Math.max(data.get(data.size() - 1).getValue() - ideal, ideal - data.get(0).getValue()); |
|
|
|
double diffPercent = (diff / ideal) * 100.0; |
|
|
|
System.out.println("Time: " + (end - start) + " Diff: " + diff + "(" + String.format("%f", diffPercent) + "%)"); |
|
|
|
Assert.assertTrue(diffPercent < 0.5); |
|
|
|
for (Map.Entry<T, Integer> entry : data) { |
|
|
|
System.out.println(entry.getKey() + ": " + entry.getValue()); |
|
|
|
} |
|
|
|
Assert.assertTrue(diffPercent < maxDiffPercent); |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|