/* * Copyright 2013 LinkedIn, Inc * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. */ package voldemort.performance; import java.util.ArrayList; import java.util.HashMap; import voldemort.ServerTestUtils; import voldemort.client.RoutingTier; import voldemort.cluster.Cluster; import voldemort.routing.BaseStoreRoutingPlan; import voldemort.routing.RoutingStrategyType; import voldemort.routing.StoreRoutingPlan; import voldemort.serialization.SerializerDefinition; import voldemort.store.StoreDefinition; import voldemort.store.StoreDefinitionBuilder; import voldemort.store.bdb.BdbStorageConfiguration; import voldemort.tools.PartitionBalance; public class StoreRoutingPlanPerf { Cluster cluster; StoreDefinition storeDefinition; // Construct zone-appropriate 3/2/2 store def. public StoreDefinition getStoreDef(int numZones) { HashMap<Integer, Integer> zoneRep = new HashMap<Integer, Integer>(); for(int zoneId = 0; zoneId < numZones; zoneId++) { zoneRep.put(zoneId, 3); } int repFactor = numZones * 3; StoreDefinition storeDef = new StoreDefinitionBuilder().setName("ZZ322") .setType(BdbStorageConfiguration.TYPE_NAME) .setRoutingPolicy(RoutingTier.CLIENT) .setRoutingStrategyType(RoutingStrategyType.ZONE_STRATEGY) .setKeySerializer(new SerializerDefinition("string")) .setValueSerializer(new SerializerDefinition("string")) .setReplicationFactor(repFactor) .setZoneReplicationFactor(zoneRep) .setRequiredReads(2) .setRequiredWrites(2) .setZoneCountReads(0) .setZoneCountWrites(0) .build(); return storeDef; } public Cluster getCluster(int numZones, int numNodes, int numPartitions) { if (numPartitions % numNodes != 0) { System.err.println("numPartitions does not evenly divide by numNodes: " + numPartitions + " / " + numNodes); System.exit(1); } if (numNodes % numZones != 0) { System.err.println("numNodes does not evenly divide by numZones: " + numNodes + " / " + numZones); System.exit(1); } int[] nodeToZoneMapping = new int[numNodes]; for(int i = 0; i < numNodes; ++i) { nodeToZoneMapping[i] = i % numZones; } int[][] partitionMapping = new int[numNodes][]; for(int i = 0; i < numPartitions; ++i) { int nodeId = i % numNodes; partitionMapping[nodeId] = new int[numPartitions/numNodes]; } for(int i = 0; i < numPartitions; ++i) { int nodeId = i % numNodes; int partitionOffset = i / numNodes; partitionMapping[nodeId][partitionOffset] = i; } int[] dummyPorts = new int[numNodes * 3]; for(int i = 0; i < numNodes; i++) { dummyPorts[i * 3] = 1000; dummyPorts[i * 3 + 1] = 2000; dummyPorts[i * 3 + 2] = 3000; } return ServerTestUtils.getLocalZonedCluster(numNodes, numZones, nodeToZoneMapping, partitionMapping, dummyPorts); } StoreRoutingPlanPerf() { cluster = null; storeDefinition = null; } /** * Repeatedly constructs StoreRoutingPlan objects. * * @param count of constructions to do. * @return ns to complete count constructions */ public long perfStoreRoutingPlan(int count) { long startNs = System.nanoTime(); for(int i = 0; i < count; ++i) { new StoreRoutingPlan(cluster, storeDefinition); } return System.nanoTime() - startNs; } /** * Repeatedly constructs BaseStoreRoutingPlan objects. * * @param count of constructions to do. * @return ns to complete count constructions */ public long perfBaseStoreRoutingPlan(int count) { long startNs = System.nanoTime(); for(int i = 0; i < count; ++i) { new BaseStoreRoutingPlan(cluster, storeDefinition); } return System.nanoTime() - startNs; } /** * Repeatedly constructs PartitionBalanceobjects. * * @param count of constructions to do. * @return ns to complete count constructions */ public long perfPartitionBalance(int count) { ArrayList<StoreDefinition> storeDefs = new ArrayList<StoreDefinition>(); storeDefs.add(storeDefinition); long startNs = System.nanoTime(); for(int i = 0; i < count; ++i) { new PartitionBalance(cluster, storeDefs); } return System.nanoTime() - startNs; } public void perfTest(int numZones, int numNodes, int numPartitions) { cluster = getCluster(numZones, numNodes, numPartitions); // System.out.println(cluster); storeDefinition = getStoreDef(numZones); // System.out.println(storeDefinition); long baseNs = perfBaseStoreRoutingPlan(1000); long storeNs = perfStoreRoutingPlan(1000); long pbNs = perfPartitionBalance(10); System.out.println("Zones (" + numZones + ") / Nodes (" + numNodes + ") / Partitions (" + numPartitions + "):"); System.out.println("BaseRP: " + baseNs + " ns (1000x)"); System.out.println("StoreRP: " + storeNs + " ns (1000x)"); System.out.println("PartitionBalance: " + pbNs + " ns (10x)"); } public static void main(String[] args) throws Exception { StoreRoutingPlanPerf srpp = new StoreRoutingPlanPerf(); srpp.perfTest(2, 10, 100); System.out.println("Ignore the above result. Doing one throw away perf test to prime java foo."); srpp.perfTest(2, 10, 100); srpp.perfTest(2, 10, 500); srpp.perfTest(2, 10, 2500); srpp.perfTest(2, 50, 500); srpp.perfTest(2, 50, 2500); srpp.perfTest(2, 250, 2500); srpp.perfTest(5, 50, 500); srpp.perfTest(5, 50, 2500); srpp.perfTest(5, 250, 2500); } }