blob: 40c3e078657bca0fcf249c568509e319857cfa4d [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 org.apache.ignite.loadtests.client;
import java.io.IOException;
import java.time.Instant;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Random;
import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.internal.client.GridClient;
import org.apache.ignite.internal.client.GridClientConfiguration;
import org.apache.ignite.internal.client.GridClientData;
import org.apache.ignite.internal.client.GridClientDataConfiguration;
import org.apache.ignite.internal.client.GridClientException;
import org.apache.ignite.internal.client.GridClientFactory;
import org.apache.ignite.internal.client.GridClientPartitionAffinity;
import org.apache.ignite.internal.util.IgniteUtils;
import org.apache.ignite.internal.util.typedef.X;
import org.apache.ignite.internal.util.typedef.internal.U;
import org.apache.ignite.testframework.GridFileLock;
import org.apache.ignite.testframework.GridLoadTestUtils;
/**
* Use {@code modules/core/src/test/config/benchmark/spring-cache-client-benchmark-*.xml}
* configurations for servers.
*/
public class ClientCacheBenchmark {
/** Number of keys, used in PUT/GET operations. */
private static final int KEY_COUNT = 1000;
/** Size of arrays used as stored values. */
private static final int VALUE_LENGTH = 1024 * 4;
/** Cached values for store. */
private static final byte[][] values = new byte[KEY_COUNT][];
/** Probability of put operation. */
private static final double WRITE_PROB = 0.2;
/** Random generator. */
private final Random rnd = new Random();
/** Number of submitting threads for current test. */
private final int threadCnt;
/** Number of operations per thread. */
private final int iterationCnt;
/** Test client. */
private GridClient client;
/** Resulting number of iterations per second. */
private double itersPerSec;
/**
* @param threadCnt Number of submitting threads.
* @param iterationCnt Number of operations per thread.
*/
public ClientCacheBenchmark(int threadCnt, int iterationCnt) {
this.threadCnt = threadCnt;
this.iterationCnt = iterationCnt;
initValues();
}
/**
* Initiates the values cache.
*/
private void initValues() {
for (int i = 0; i < KEY_COUNT; i++) {
values[i] = new byte[VALUE_LENGTH];
rnd.nextBytes(values[i]);
}
}
/**
* Performs test,
*
* @param printResults Whether to print results.
* @throws GridClientException If failed.
*/
public void run(boolean printResults) throws GridClientException {
Collection<TestThread> workers = new ArrayList<>(threadCnt);
client = GridClientFactory.start(configuration());
long startTime = System.currentTimeMillis();
for (int i = 0; i < threadCnt; i++) {
TestThread th = new TestThread();
workers.add(th);
th.start();
}
U.joinThreads(workers, null);
if (printResults)
countAndPrintSummary(workers, startTime);
GridClientFactory.stopAll();
}
/**
* @return Resulting iterations per second.
*/
public double getItersPerSec() {
return itersPerSec;
}
/**
* Counts and prints tests summary,
*
* @param workers Collection of test worker threads.
* @param startTime Time when test eas started.
*/
private void countAndPrintSummary(Collection<TestThread> workers, long startTime) {
long total = 0;
int thCnt = workers.size();
for (TestThread t : workers) { total += t.iters; }
double timeSpent = ((double)(System.currentTimeMillis() - startTime)) / 1000;
itersPerSec = total / timeSpent;
System.out.printf("%8s, %12.0f, %12.0f, %12s\n", thCnt, itersPerSec, total / timeSpent / thCnt, total);
}
/**
* @return Test client configuration.
*/
private GridClientConfiguration configuration() {
GridClientConfiguration cfg = new GridClientConfiguration();
cfg.setServers(Collections.singleton("localhost:11211"));
GridClientDataConfiguration cacheCfg = new GridClientDataConfiguration();
cacheCfg.setName("partitioned");
cacheCfg.setAffinity(new GridClientPartitionAffinity());
cfg.setDataConfigurations(Collections.singletonList(cacheCfg));
return cfg;
}
/**
* Test thread.
*/
private class TestThread extends Thread {
/** Thread private random generator. */
private final Random rnd = new Random();
/** Number of iterations to perform. */
private long iters;
/** {@inheritDoc} */
@Override public void run() {
try {
GridClientData data = client.data("partitioned");
for (int i = 0; i < iterationCnt; i++)
performIteration(data);
}
catch (GridClientException e) {
e.printStackTrace();
}
}
/**
* Performs test iteration.
* @param data client data to operate on.
* @throws GridClientException If failed.
*/
private void performIteration(GridClientData data) throws GridClientException {
if (rnd.nextDouble() <= WRITE_PROB)
data.put(rnd.nextInt(KEY_COUNT), values[rnd.nextInt(KEY_COUNT)]);
else
data.get(rnd.nextInt(KEY_COUNT));
iters++;
}
}
/**
* Runs benchmark.
* @param args Command-line arguments.
* @throws GridClientException If failed.
*/
public static void main(String[] args) throws GridClientException, IgniteCheckedException {
GridFileLock fileLock = GridLoadTestUtils.fileLock();
fileLock.lock();
try {
System.out.printf("%8s, %12s, %12s, %12s\n", "Threads", "It./s.", "It./s.*th.", "Iters.");
if (args.length == 0) {
for (int i = 1; i <= 16; i *= 2) {
ClientCacheBenchmark benchmark = new ClientCacheBenchmark(i, 10000);
benchmark.run(false);
System.gc();
}
for (int i = 1; i <= 64; i *= 2) {
ClientCacheBenchmark benchmark = new ClientCacheBenchmark(i, 10000);
benchmark.run(true);
System.gc();
}
}
else {
int nThreads = Integer.parseInt(args[0]);
String outputFileName = (args.length >= 2 ? args[1] : null);
ClientCacheBenchmark benchmark = null;
for (int i = 0; i < 2; i++) {
benchmark = new ClientCacheBenchmark(nThreads, 10000);
benchmark.run(true);
}
if (outputFileName != null) {
X.println("Writing test results to a file: " + outputFileName);
assert benchmark != null;
try {
GridLoadTestUtils.appendLineToFile(
outputFileName,
"%s,%d",
IgniteUtils.LONG_DATE_FMT.format(Instant.now()),
Math.round(benchmark.getItersPerSec()));
}
catch (IOException e) {
X.error("Failed to output to a file", e);
}
}
}
}
finally {
fileLock.close();
}
}
}