2017-07-25 19:10:31 +08:00
|
|
|
/*
|
|
|
|
|
* Copyright 2017 HugeGraph Authors
|
|
|
|
|
*
|
|
|
|
|
* 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
|
2017-08-16 16:13:20 +08:00
|
|
|
* License for the specific language governing permissions and limitations
|
|
|
|
|
* under the License.
|
2017-07-25 19:10:31 +08:00
|
|
|
*/
|
2017-06-13 13:47:15 +08:00
|
|
|
package com.baidu.hugegraph.example;
|
|
|
|
|
|
|
|
|
|
import java.util.ArrayList;
|
|
|
|
|
import java.util.LinkedList;
|
|
|
|
|
import java.util.List;
|
|
|
|
|
import java.util.Random;
|
|
|
|
|
|
2017-06-23 11:30:43 +08:00
|
|
|
import org.apache.commons.lang3.tuple.Pair;
|
2017-06-13 13:47:15 +08:00
|
|
|
import org.apache.tinkerpop.gremlin.structure.Edge;
|
|
|
|
|
import org.apache.tinkerpop.gremlin.structure.T;
|
2017-06-22 20:02:16 +08:00
|
|
|
import org.apache.tinkerpop.gremlin.structure.Transaction;
|
2017-06-13 13:47:15 +08:00
|
|
|
import org.apache.tinkerpop.gremlin.structure.Vertex;
|
|
|
|
|
import org.slf4j.Logger;
|
|
|
|
|
import org.slf4j.LoggerFactory;
|
|
|
|
|
|
|
|
|
|
import com.baidu.hugegraph.HugeGraph;
|
2017-06-22 20:02:16 +08:00
|
|
|
import com.baidu.hugegraph.backend.cache.Cache;
|
2017-07-20 22:20:33 +08:00
|
|
|
import com.baidu.hugegraph.backend.cache.CacheManager;
|
2017-06-22 20:02:16 +08:00
|
|
|
import com.baidu.hugegraph.backend.id.Id;
|
2017-07-31 21:26:38 +08:00
|
|
|
import com.baidu.hugegraph.schema.EdgeLabel;
|
2017-06-13 13:47:15 +08:00
|
|
|
import com.baidu.hugegraph.schema.SchemaManager;
|
2017-08-04 19:48:57 +08:00
|
|
|
import com.baidu.hugegraph.schema.VertexLabel;
|
2017-06-22 20:02:16 +08:00
|
|
|
import com.baidu.hugegraph.structure.HugeVertex;
|
2017-06-13 13:47:15 +08:00
|
|
|
|
|
|
|
|
public class PerfExample1 {
|
|
|
|
|
|
|
|
|
|
public static final int PERSON_NUM = 70;
|
|
|
|
|
public static final int SOFTWARE_NUM = 30;
|
|
|
|
|
public static final int EDGE_NUM = 1000;
|
|
|
|
|
|
|
|
|
|
private static final Logger logger = LoggerFactory.getLogger(PerfExample1.class);
|
|
|
|
|
|
|
|
|
|
public static void main(String[] args) throws InterruptedException {
|
|
|
|
|
if (args.length < 3) {
|
|
|
|
|
System.out.println("Usage: times threadno");
|
2017-06-13 14:24:24 +08:00
|
|
|
return;
|
2017-06-13 13:47:15 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int times = Integer.parseInt(args[1]);
|
|
|
|
|
int threadno = Integer.parseInt(args[2]);;
|
|
|
|
|
|
|
|
|
|
// NOTE: this test with HugeGraph is for local, change it into
|
|
|
|
|
// client if test with restful server from remote
|
|
|
|
|
HugeGraph hugegraph = ExampleUtil.loadGraph();
|
|
|
|
|
GraphManager graph = new GraphManager(hugegraph);
|
|
|
|
|
|
|
|
|
|
initSchema(hugegraph.schema());
|
|
|
|
|
testInsertPerf(graph, times, threadno);
|
|
|
|
|
|
2017-06-13 14:24:24 +08:00
|
|
|
hugegraph.close();
|
2017-06-13 13:47:15 +08:00
|
|
|
System.exit(0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void testInsertPerf(GraphManager graph,
|
|
|
|
|
int times, int threadno) throws InterruptedException {
|
2017-06-23 11:30:43 +08:00
|
|
|
List<Pair<Long, Long>> rates = new LinkedList<>();
|
2017-06-13 13:47:15 +08:00
|
|
|
|
|
|
|
|
List<Thread> threads = new LinkedList<>();
|
|
|
|
|
for (int i = 0; i < threadno; i++) {
|
|
|
|
|
Thread t = new Thread(() -> {
|
2017-06-23 11:30:43 +08:00
|
|
|
graph.tx().open();
|
|
|
|
|
Pair<Long, Long> rate = testInsertPerf(graph, times);
|
2017-07-19 17:38:46 +08:00
|
|
|
graph.tx().close();
|
2017-06-23 11:30:43 +08:00
|
|
|
|
2017-06-13 13:47:15 +08:00
|
|
|
rates.add(rate);
|
|
|
|
|
});
|
|
|
|
|
t.start();
|
|
|
|
|
threads.add(t);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (Thread t : threads) {
|
|
|
|
|
t.join();
|
|
|
|
|
}
|
|
|
|
|
|
2017-06-23 11:30:43 +08:00
|
|
|
// total edges
|
|
|
|
|
long edges = rates.stream().mapToLong(i -> i.getLeft()).sum();
|
|
|
|
|
// total cost (average time of all threads) (ms)
|
|
|
|
|
long cost = (long) rates.stream().mapToLong(i -> i.getRight())
|
2017-07-19 17:38:46 +08:00
|
|
|
.average().getAsDouble();
|
2017-06-23 11:30:43 +08:00
|
|
|
logger.info("Rate with threads: {} edges/s", edges * 1000 / cost);
|
2017-06-13 13:47:15 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void initSchema(SchemaManager schema) {
|
2017-07-31 21:26:38 +08:00
|
|
|
schema.propertyKey("name").asText().create();
|
|
|
|
|
schema.propertyKey("age").asInt().create();
|
|
|
|
|
schema.propertyKey("lang").asText().create();
|
|
|
|
|
schema.propertyKey("date").asText().create();
|
|
|
|
|
schema.propertyKey("price").asInt().create();
|
2017-06-13 13:47:15 +08:00
|
|
|
|
2017-07-31 21:26:38 +08:00
|
|
|
VertexLabel person = schema.vertexLabel("person")
|
2017-06-13 13:47:15 +08:00
|
|
|
.properties("name", "age")
|
|
|
|
|
.primaryKeys("name")
|
|
|
|
|
.ifNotExist()
|
|
|
|
|
.create();
|
|
|
|
|
|
2017-07-31 21:26:38 +08:00
|
|
|
VertexLabel software = schema.vertexLabel("software")
|
2017-06-13 13:47:15 +08:00
|
|
|
.properties("name", "lang", "price")
|
|
|
|
|
.primaryKeys("name")
|
|
|
|
|
.ifNotExist()
|
|
|
|
|
.create();
|
|
|
|
|
|
2017-07-31 21:26:38 +08:00
|
|
|
// schema.indexLabel("personByName")
|
2017-06-13 13:47:15 +08:00
|
|
|
// .on(person).by("name")
|
|
|
|
|
// .secondary()
|
|
|
|
|
// .ifNotExist()
|
|
|
|
|
// .create();
|
|
|
|
|
//
|
2017-07-31 21:26:38 +08:00
|
|
|
// schema.indexLabel("softwareByPrice")
|
2017-06-13 13:47:15 +08:00
|
|
|
// .on(software).by("price")
|
|
|
|
|
// .search()
|
|
|
|
|
// .ifNotExist()
|
|
|
|
|
// .create();
|
|
|
|
|
|
2017-07-31 21:26:38 +08:00
|
|
|
EdgeLabel knows = schema.edgeLabel("knows")
|
|
|
|
|
.sourceLabel("person").targetLabel("person")
|
2017-06-13 13:47:15 +08:00
|
|
|
.properties("date")
|
|
|
|
|
.ifNotExist()
|
|
|
|
|
.create();
|
|
|
|
|
|
2017-07-31 21:26:38 +08:00
|
|
|
EdgeLabel created = schema.edgeLabel("created")
|
|
|
|
|
.sourceLabel("person").targetLabel("software")
|
2017-06-13 13:47:15 +08:00
|
|
|
.properties("date")
|
|
|
|
|
.ifNotExist()
|
|
|
|
|
.create();
|
|
|
|
|
}
|
|
|
|
|
|
2017-07-19 17:38:46 +08:00
|
|
|
public static Pair<Long, Long> testInsertPerf(GraphManager graph,
|
|
|
|
|
int times) {
|
2017-06-13 13:47:15 +08:00
|
|
|
long total = EDGE_NUM * times;
|
|
|
|
|
long startTime = System.currentTimeMillis();
|
|
|
|
|
|
|
|
|
|
List<Object> personVertexIds = new ArrayList<>();
|
|
|
|
|
List<Object> softwareVertexIds = new ArrayList<>();
|
|
|
|
|
Random random = new Random();
|
|
|
|
|
|
|
|
|
|
long startTime0, endTime0 = 0;
|
|
|
|
|
while (times > 0) {
|
|
|
|
|
startTime0 = System.currentTimeMillis();
|
|
|
|
|
int personAge = 0;
|
|
|
|
|
String personName = "";
|
|
|
|
|
logger.debug("==============random person vertex===============");
|
|
|
|
|
for (int i = 0; i < PERSON_NUM; i++) {
|
|
|
|
|
random = new Random();
|
|
|
|
|
personAge = random.nextInt(70);
|
|
|
|
|
personName = "P" + random.nextInt(10000);
|
|
|
|
|
Vertex vetex = graph.addVertex(T.label, "person",
|
2017-07-19 17:38:46 +08:00
|
|
|
"name", personName, "age", personAge);
|
2017-06-13 13:47:15 +08:00
|
|
|
personVertexIds.add(vetex.id());
|
2017-07-19 17:38:46 +08:00
|
|
|
logger.debug("Add vertex: {}", vetex);
|
2017-06-13 13:47:15 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int softwarePrice = 0;
|
|
|
|
|
String softwareName = "";
|
|
|
|
|
String softwareLang = "java";
|
|
|
|
|
logger.debug("==============random software vertex============");
|
|
|
|
|
for (int i = 0; i < SOFTWARE_NUM; i++) {
|
|
|
|
|
random = new Random();
|
|
|
|
|
softwarePrice = random.nextInt(10000) + 1;
|
|
|
|
|
softwareName = "S" + random.nextInt(10000);
|
|
|
|
|
Vertex vetex = graph.addVertex(T.label, "software",
|
2017-07-19 17:38:46 +08:00
|
|
|
"name", softwareName, "lang", "java",
|
|
|
|
|
"price", softwarePrice);
|
2017-06-13 13:47:15 +08:00
|
|
|
softwareVertexIds.add(vetex.id());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Random 1000 Edge
|
|
|
|
|
logger.debug("====================add Edges=================");
|
|
|
|
|
for (int i = 0; i < EDGE_NUM / 2; i++) {
|
|
|
|
|
random = new Random();
|
|
|
|
|
|
|
|
|
|
// Add edge: person --knows-> person
|
|
|
|
|
Object p1 = personVertexIds.get(random.nextInt(PERSON_NUM));
|
|
|
|
|
Object p2 = personVertexIds.get(random.nextInt(PERSON_NUM));
|
|
|
|
|
Edge edge1 = graph.getVertex(p1).addEdge("knows",
|
2017-07-19 17:38:46 +08:00
|
|
|
graph.getVertex(p2));
|
2017-06-13 13:47:15 +08:00
|
|
|
|
|
|
|
|
// Add edge: person --created-> software
|
|
|
|
|
Object p3 = personVertexIds.get(random.nextInt(PERSON_NUM));
|
|
|
|
|
Object s1 = softwareVertexIds.get(random.nextInt(SOFTWARE_NUM));
|
|
|
|
|
Edge edge2 = graph.getVertex(p3).addEdge("created",
|
2017-07-19 17:38:46 +08:00
|
|
|
graph.getVertex(s1));
|
2017-06-13 13:47:15 +08:00
|
|
|
}
|
|
|
|
|
|
2017-07-19 17:38:46 +08:00
|
|
|
graph.tx().commit();
|
2017-06-13 13:47:15 +08:00
|
|
|
personVertexIds.clear();
|
|
|
|
|
softwareVertexIds.clear();
|
|
|
|
|
times--;
|
|
|
|
|
endTime0 = System.currentTimeMillis();
|
|
|
|
|
logger.debug("Adding edges during time: {} ms",
|
2017-07-19 17:38:46 +08:00
|
|
|
endTime0 - startTime0);
|
2017-06-13 13:47:15 +08:00
|
|
|
}
|
|
|
|
|
long endTime = System.currentTimeMillis();
|
|
|
|
|
|
|
|
|
|
long cost = endTime - startTime;
|
|
|
|
|
long rate = total * 1000 / cost;
|
|
|
|
|
logger.info("All tests cost time: {} ms, the rate is: {} edges/s",
|
2017-07-19 17:38:46 +08:00
|
|
|
cost, rate);
|
2017-06-23 11:30:43 +08:00
|
|
|
return Pair.of(total, cost);
|
2017-06-13 13:47:15 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static class GraphManager {
|
|
|
|
|
private HugeGraph hugegraph;
|
2017-07-20 22:20:33 +08:00
|
|
|
private Cache cache = CacheManager.instance().cache("perf-test");
|
2017-06-13 13:47:15 +08:00
|
|
|
|
|
|
|
|
public GraphManager(HugeGraph hugegraph) {
|
|
|
|
|
this.hugegraph = hugegraph;
|
|
|
|
|
}
|
|
|
|
|
|
2017-06-22 20:02:16 +08:00
|
|
|
public Transaction tx() {
|
|
|
|
|
return this.hugegraph.tx();
|
|
|
|
|
}
|
|
|
|
|
|
2017-06-13 13:47:15 +08:00
|
|
|
public Vertex addVertex(Object... keyValues) {
|
2017-07-26 11:26:41 +08:00
|
|
|
HugeVertex v = (HugeVertex) this.hugegraph.addVertex(keyValues);
|
|
|
|
|
this.cache.update(v.id(), v.resetTx());
|
2017-06-23 17:30:07 +08:00
|
|
|
return v;
|
2017-06-13 13:47:15 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public Vertex getVertex(Object id) {
|
2017-07-26 11:26:41 +08:00
|
|
|
return ((Vertex) this.cache.getOrFetch((Id) id, k -> {
|
2017-06-22 20:02:16 +08:00
|
|
|
return this.hugegraph.vertices(k).next();
|
2017-07-26 11:26:41 +08:00
|
|
|
}));
|
2017-06-13 13:47:15 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|