Madan Jampani
Committed by Gerrit Code Review

Test application to measure partitioned raft database performance.

Change-Id: I6a1e773d71feb4867b959ec33841b8026dda32f5
1 +<?xml version="1.0" encoding="UTF-8"?>
2 +<!--
3 + ~ Copyright 2015 Open Networking Laboratory
4 + ~
5 + ~ Licensed under the Apache License, Version 2.0 (the "License");
6 + ~ you may not use this file except in compliance with the License.
7 + ~ You may obtain a copy of the License at
8 + ~
9 + ~ http://www.apache.org/licenses/LICENSE-2.0
10 + ~
11 + ~ Unless required by applicable law or agreed to in writing, software
12 + ~ distributed under the License is distributed on an "AS IS" BASIS,
13 + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 + ~ See the License for the specific language governing permissions and
15 + ~ limitations under the License.
16 + -->
17 +<app name="org.onosproject.databaseperf" origin="ON.Lab" version="1.1.0"
18 + features="onos-app-database-perf">
19 + <description>Partitioned database performance measurement application</description>
20 +</app>
1 +<?xml version="1.0" encoding="UTF-8"?>
2 +<!--
3 + ~ Copyright 2015 Open Networking Laboratory
4 + ~
5 + ~ Licensed under the Apache License, Version 2.0 (the "License");
6 + ~ you may not use this file except in compliance with the License.
7 + ~ You may obtain a copy of the License at
8 + ~
9 + ~ http://www.apache.org/licenses/LICENSE-2.0
10 + ~
11 + ~ Unless required by applicable law or agreed to in writing, software
12 + ~ distributed under the License is distributed on an "AS IS" BASIS,
13 + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 + ~ See the License for the specific language governing permissions and
15 + ~ limitations under the License.
16 + -->
17 +<assembly
18 + xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
19 + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
20 + xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
21 + <formats>
22 + <format>zip</format>
23 + </formats>
24 + <id>onos</id>
25 + <includeBaseDirectory>false</includeBaseDirectory>
26 + <files>
27 + <file>
28 + <source>src/assembly/app.xml</source>
29 + <destName>app.xml</destName>
30 + </file>
31 + <file>
32 + <source>target/${project.artifactId}-${project.version}.jar</source>
33 + <destName>m2/org/onosproject/${project.artifactId}/${project.version}/${project.artifactId}-${project.version}.jar</destName>
34 + </file>
35 + </files>
36 +</assembly>
1 +/*
2 + * Copyright 2015 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +package org.onosproject.databaseperf;
17 +
18 +import static org.apache.felix.scr.annotations.ReferenceCardinality.MANDATORY_UNARY;
19 +import static org.onlab.util.Tools.delay;
20 +import static org.onlab.util.Tools.groupedThreads;
21 +import static org.slf4j.LoggerFactory.getLogger;
22 +
23 +import java.util.Timer;
24 +import java.util.TimerTask;
25 +import java.util.UUID;
26 +import java.util.concurrent.ExecutorService;
27 +import java.util.concurrent.Executors;
28 +import java.util.concurrent.TimeUnit;
29 +import java.util.concurrent.atomic.AtomicInteger;
30 +import java.util.stream.IntStream;
31 +
32 +import org.apache.commons.lang.math.RandomUtils;
33 +import org.apache.felix.scr.annotations.Activate;
34 +import org.apache.felix.scr.annotations.Component;
35 +import org.apache.felix.scr.annotations.Deactivate;
36 +import org.apache.felix.scr.annotations.Reference;
37 +import org.onlab.util.KryoNamespace;
38 +import org.onosproject.cluster.ClusterService;
39 +import org.onosproject.cluster.ControllerNode;
40 +import org.onosproject.core.ApplicationId;
41 +import org.onosproject.core.CoreService;
42 +import org.onosproject.store.service.ConsistentMap;
43 +import org.onosproject.store.service.Serializer;
44 +import org.onosproject.store.service.StorageService;
45 +import org.slf4j.Logger;
46 +
47 +/**
48 + * Application to measure partitioned database performance.
49 + */
50 +@Component(immediate = true)
51 +public class DatabasePerfInstaller {
52 +
53 + private final Logger log = getLogger(getClass());
54 +
55 + @Reference(cardinality = MANDATORY_UNARY)
56 + protected CoreService coreService;
57 +
58 + @Reference(cardinality = MANDATORY_UNARY)
59 + protected ClusterService clusterService;
60 +
61 + @Reference(cardinality = MANDATORY_UNARY)
62 + protected StorageService storageService;
63 +
64 + private boolean stopped;
65 +
66 + private ApplicationId appId;
67 +
68 + private static final long REPORT_PERIOD = 5000L; //ms
69 + private Timer reportTimer;
70 +
71 + private AtomicInteger successCount = new AtomicInteger(0);
72 + private AtomicInteger failureCount = new AtomicInteger(0);
73 +
74 + private ConsistentMap<String, String> cmap;
75 +
76 + private ControllerNode localNode;
77 +
78 + private long reportStartTime = System.currentTimeMillis();
79 +
80 + private static final int NUM_TASK_THREADS = 2;
81 + private ExecutorService taskExecutor;
82 +
83 + private static final Serializer SERIALIZER = new Serializer() {
84 +
85 + KryoNamespace kryo = new KryoNamespace.Builder().build();
86 +
87 + @Override
88 + public <T> byte[] encode(T object) {
89 + return kryo.serialize(object);
90 + }
91 +
92 + @Override
93 + public <T> T decode(byte[] bytes) {
94 + return kryo.deserialize(bytes);
95 + }
96 +
97 + };
98 +
99 + @Activate
100 + public void activate() {
101 + localNode = clusterService.getLocalNode();
102 + String nodeId = localNode.ip().toString();
103 + appId = coreService.registerApplication("org.onosproject.nettyperf."
104 + + nodeId);
105 +
106 + cmap = storageService.createConsistentMap("onos-app-database-perf-test-map", SERIALIZER);
107 + taskExecutor = Executors.newFixedThreadPool(NUM_TASK_THREADS, groupedThreads("onos/database-perf", "worker"));
108 + log.info("Started with Application ID {}", appId.id());
109 + start();
110 + }
111 +
112 + @Deactivate
113 + public void deactivate() {
114 + stop();
115 + log.info("Stopped");
116 + }
117 +
118 + public void start() {
119 + long delay = System.currentTimeMillis() % REPORT_PERIOD;
120 + reportTimer = new Timer("onos-netty-perf-reporter");
121 + reportTimer.scheduleAtFixedRate(new TimerTask() {
122 + @Override
123 + public void run() {
124 + report();
125 + }
126 + }, delay, REPORT_PERIOD);
127 +
128 + stopped = false;
129 + IntStream.range(0, NUM_TASK_THREADS).forEach(i -> {
130 + taskExecutor.submit(() -> {
131 + delay(2000); // take a breath to start
132 + while (!stopped) {
133 + performDBOperation();
134 + delay(2); // take a breather
135 + }
136 + });
137 + });
138 + }
139 +
140 + private void performDBOperation() {
141 + String key = String.format("test%d", RandomUtils.nextInt(1000));
142 + try {
143 + if (RandomUtils.nextBoolean()) {
144 + cmap.put(key, UUID.randomUUID().toString());
145 + } else {
146 + cmap.get(key);
147 + }
148 + successCount.incrementAndGet();
149 + } catch (Exception e) {
150 + failureCount.incrementAndGet();
151 + }
152 + }
153 +
154 + private void report() {
155 + long delta = System.currentTimeMillis() - reportStartTime;
156 + if (delta > 0) {
157 + int rate = (int) Math.round(((successCount.get() * 1000.0) / delta));
158 + log.info("Passed: {}, Failed: {}, Rate: {}",
159 + successCount.getAndSet(0), failureCount.getAndSet(0), rate);
160 + reportStartTime = System.currentTimeMillis();
161 + }
162 + }
163 +
164 + public void stop() {
165 + reportTimer.cancel();
166 + reportTimer = null;
167 + stopped = true;
168 + try {
169 + taskExecutor.awaitTermination(5, TimeUnit.SECONDS);
170 + } catch (InterruptedException e) {
171 + log.warn("Failed to stop worker.");
172 + }
173 + }
174 +}
1 +/*
2 + * Copyright 2015 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +
17 +/**
18 + * Performance test application that induces steady load on the partitioned database.
19 + */
20 +package org.onosproject.databaseperf;
...@@ -264,6 +264,12 @@ ...@@ -264,6 +264,12 @@
264 <bundle>mvn:org.onosproject/onos-app-intent-perf/@ONOS-VERSION</bundle> 264 <bundle>mvn:org.onosproject/onos-app-intent-perf/@ONOS-VERSION</bundle>
265 </feature> 265 </feature>
266 266
267 + <feature name="onos-app-database-perf" version="@FEATURE-VERSION"
268 + description="ONOS partitioned database perf application">
269 + <feature>onos-api</feature>
270 + <bundle>mvn:org.onosproject/onos-app-database-perf/@ONOS-VERSION</bundle>
271 + </feature>
272 +
267 <feature name="onos-app-election" version="@FEATURE-VERSION" 273 <feature name="onos-app-election" version="@FEATURE-VERSION"
268 description="ONOS app leadership election test"> 274 description="ONOS app leadership election test">
269 <feature>onos-api</feature> 275 <feature>onos-api</feature>
......