diff --git a/hugegraph-api/src/main/java/com/baidu/hugegraph/api/metrics/MetricsAPI.java b/hugegraph-api/src/main/java/com/baidu/hugegraph/api/metrics/MetricsAPI.java index f6710c0aba..7b8e052a9e 100644 --- a/hugegraph-api/src/main/java/com/baidu/hugegraph/api/metrics/MetricsAPI.java +++ b/hugegraph-api/src/main/java/com/baidu/hugegraph/api/metrics/MetricsAPI.java @@ -30,18 +30,30 @@ import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.Produces; +import javax.ws.rs.core.Context; + +import org.slf4j.Logger; import com.baidu.hugegraph.api.API; +import com.baidu.hugegraph.backend.store.BackendMetrics; +import com.baidu.hugegraph.backend.tx.GraphTransaction; +import com.baidu.hugegraph.core.GraphManager; +import com.baidu.hugegraph.exception.NotSupportException; import com.baidu.hugegraph.metric.ServerReporter; import com.baidu.hugegraph.metric.SystemMetrics; +import com.baidu.hugegraph.util.InsertionOrderUtil; import com.baidu.hugegraph.util.JsonUtil; +import com.baidu.hugegraph.util.Log; import com.codahale.metrics.Metric; +import com.codahale.metrics.annotation.Timed; import com.codahale.metrics.json.MetricsModule; @Singleton @Path("metrics") public class MetricsAPI extends API { + private static final Logger LOG = Log.logger(MetricsAPI.class); + private SystemMetrics systemMetrics; static { @@ -53,6 +65,7 @@ public MetricsAPI() { } @GET + @Timed @Path("system") @Produces(APPLICATION_JSON_WITH_CHARSET) @RolesAllowed("admin") @@ -61,6 +74,29 @@ public String system() { } @GET + @Timed + @Path("backend") + @Produces(APPLICATION_JSON_WITH_CHARSET) + @RolesAllowed("admin") + public String backend(@Context GraphManager manager) { + Map> results = InsertionOrderUtil.newMap(); + for (String graph : manager.graphs()) { + GraphTransaction tx = manager.graph(graph).graphTransaction(); + Map metrics = InsertionOrderUtil.newMap(); + metrics.put(BackendMetrics.BACKEND, tx.store().provider().type()); + try { + metrics.putAll(tx.metadata(null, "metrics")); + } catch (NotSupportException e) { + metrics.put(BackendMetrics.EXCEPTION, e.toString()); + LOG.debug("Failed to get backend metrics", e); + } + results.put(graph, metrics); + } + return JsonUtil.toJson(results); + } + + @GET + @Timed @Produces(APPLICATION_JSON_WITH_CHARSET) @RolesAllowed("admin") public String all() { @@ -75,6 +111,7 @@ public String all() { } @GET + @Timed @Path("gauges") @Produces(APPLICATION_JSON_WITH_CHARSET) @RolesAllowed("admin") @@ -84,6 +121,7 @@ public String gauges() { } @GET + @Timed @Path("counters") @Produces(APPLICATION_JSON_WITH_CHARSET) @RolesAllowed("admin") @@ -93,6 +131,7 @@ public String counters() { } @GET + @Timed @Path("histograms") @Produces(APPLICATION_JSON_WITH_CHARSET) @RolesAllowed("admin") @@ -102,6 +141,7 @@ public String histograms() { } @GET + @Timed @Path("meters") @Produces(APPLICATION_JSON_WITH_CHARSET) @RolesAllowed("admin") @@ -111,10 +151,11 @@ public String meters() { } @GET - @Path("times") + @Timed + @Path("timers") @Produces(APPLICATION_JSON_WITH_CHARSET) @RolesAllowed("admin") - public String times() { + public String timers() { ServerReporter reporter = ServerReporter.instance(); return JsonUtil.toJson(reporter.timers()); } diff --git a/hugegraph-cassandra/src/main/java/com/baidu/hugegraph/backend/store/cassandra/CassandraMetrics.java b/hugegraph-cassandra/src/main/java/com/baidu/hugegraph/backend/store/cassandra/CassandraMetrics.java new file mode 100644 index 0000000000..1781d0213e --- /dev/null +++ b/hugegraph-cassandra/src/main/java/com/baidu/hugegraph/backend/store/cassandra/CassandraMetrics.java @@ -0,0 +1,73 @@ +/* + * 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 + * License for the specific language governing permissions and limitations + * under the License. + */ + +package com.baidu.hugegraph.backend.store.cassandra; + +import java.lang.management.MemoryUsage; +import java.util.Map; + +import org.apache.cassandra.tools.NodeProbe; + +import com.baidu.hugegraph.backend.store.BackendMetrics; +import com.baidu.hugegraph.config.HugeConfig; +import com.baidu.hugegraph.util.Bytes; +import com.baidu.hugegraph.util.InsertionOrderUtil; +import com.datastax.driver.core.Cluster; +import com.datastax.driver.core.Host; + +public class CassandraMetrics implements BackendMetrics { + + private final Cluster cluster; + private final int port; + private final String username; + private final String password; + + public CassandraMetrics(Cluster cluster, HugeConfig conf) { + this.cluster = cluster; + this.port = conf.get(CassandraOptions.CASSANDRA_JMX_PORT); + this.username = conf.get(CassandraOptions.CASSANDRA_USERNAME); + this.password = conf.get(CassandraOptions.CASSANDRA_PASSWORD); + } + + @Override + public Map getMetrics() { + Map results = InsertionOrderUtil.newMap(); + for (Host host : this.cluster.getMetadata().getAllHosts()) { + String address = host.getAddress().getHostAddress(); + results.put(address, this.getMetricsByHost(address)); + } + return results; + } + + private Map getMetricsByHost(String host) { + Map metrics = InsertionOrderUtil.newMap(); + // JMX client operations for Cassandra. + try (NodeProbe probe = new NodeProbe(host, port, username, password)) { + MemoryUsage heapUsage = probe.getHeapMemoryUsage(); + metrics.put(MEM_USED, heapUsage.getUsed() / Bytes.MB); + metrics.put(MEM_COMMITED, heapUsage.getCommitted() / Bytes.MB); + metrics.put(MEM_MAX, heapUsage.getMax() / Bytes.MB); + metrics.put(MEM_UNIT, "MB"); + metrics.put(DATA_SIZE, probe.getLoadString()); + } catch (Exception e) { + metrics.put(EXCEPTION, e.toString()); + } + return metrics; + } +} diff --git a/hugegraph-cassandra/src/main/java/com/baidu/hugegraph/backend/store/cassandra/CassandraOptions.java b/hugegraph-cassandra/src/main/java/com/baidu/hugegraph/backend/store/cassandra/CassandraOptions.java index ebe15b940a..79ab796089 100644 --- a/hugegraph-cassandra/src/main/java/com/baidu/hugegraph/backend/store/cassandra/CassandraOptions.java +++ b/hugegraph-cassandra/src/main/java/com/baidu/hugegraph/backend/store/cassandra/CassandraOptions.java @@ -111,4 +111,12 @@ public static synchronized CassandraOptions instance() { allowValues("none", "snappy", "lz4"), "none" ); + + public static final ConfigOption CASSANDRA_JMX_PORT = + new ConfigOption<>( + "cassandra.jmx_port", + "The port of JMX API service for cassandra", + rangeInt(1, 65535), + 7199 + ); } diff --git a/hugegraph-cassandra/src/main/java/com/baidu/hugegraph/backend/store/cassandra/CassandraStore.java b/hugegraph-cassandra/src/main/java/com/baidu/hugegraph/backend/store/cassandra/CassandraStore.java index b1db12ba55..669f52be1d 100644 --- a/hugegraph-cassandra/src/main/java/com/baidu/hugegraph/backend/store/cassandra/CassandraStore.java +++ b/hugegraph-cassandra/src/main/java/com/baidu/hugegraph/backend/store/cassandra/CassandraStore.java @@ -29,11 +29,11 @@ import com.baidu.hugegraph.backend.BackendException; import com.baidu.hugegraph.backend.id.Id; import com.baidu.hugegraph.backend.query.Query; +import com.baidu.hugegraph.backend.store.AbstractBackendStore; import com.baidu.hugegraph.backend.store.BackendAction; import com.baidu.hugegraph.backend.store.BackendEntry; import com.baidu.hugegraph.backend.store.BackendFeatures; import com.baidu.hugegraph.backend.store.BackendMutation; -import com.baidu.hugegraph.backend.store.BackendStore; import com.baidu.hugegraph.backend.store.BackendStoreProvider; import com.baidu.hugegraph.config.HugeConfig; import com.baidu.hugegraph.type.HugeType; @@ -46,7 +46,7 @@ import com.datastax.driver.core.exceptions.InvalidQueryException; import com.datastax.driver.core.schemabuilder.SchemaBuilder; -public abstract class CassandraStore implements BackendStore { +public abstract class CassandraStore extends AbstractBackendStore { private static final Logger LOG = Log.logger(CassandraStore.class); @@ -58,6 +58,7 @@ public abstract class CassandraStore implements BackendStore { private final BackendStoreProvider provider; private final CassandraSessionPool sessions; + // TODO: move to parent class private final Map tables; private HugeConfig conf; @@ -77,9 +78,17 @@ public CassandraStore(final BackendStoreProvider provider, this.conf = null; + this.registerMetaHandlers(); LOG.debug("Store loaded: {}", store); } + private void registerMetaHandlers() { + this.registerMetaHandler("metrics", (session, meta, args) -> { + CassandraMetrics metrics = new CassandraMetrics(cluster(), conf); + return metrics.getMetrics(); + }); + } + protected void registerTableManager(HugeType type, CassandraTable table) { this.tables.put(type, table); } @@ -226,14 +235,6 @@ public Iterator query(Query query) { return table.query(this.sessions.session(), query); } - @Override - public R metadata(HugeType type, String meta, Object[] args) { - this.checkSessionConnected(); - - CassandraTable table = this.table(type); - return table.metadata(this.sessions.session(), meta, args); - } - @Override public BackendFeatures features() { return FEATURES; @@ -406,6 +407,7 @@ protected void clearTables() { } } + @Override protected final CassandraTable table(HugeType type) { assert type != null; CassandraTable table = this.tables.get(type); @@ -415,6 +417,12 @@ protected final CassandraTable table(HugeType type) { return table; } + @Override + protected CassandraSessionPool.Session session(HugeType type) { + this.checkSessionConnected(); + return this.sessions.session(); + } + protected final void checkClusterConnected() { E.checkState(this.sessions != null, "Cassandra store has not been initialized"); diff --git a/hugegraph-core/src/main/java/com/baidu/hugegraph/backend/store/AbstractBackendStore.java b/hugegraph-core/src/main/java/com/baidu/hugegraph/backend/store/AbstractBackendStore.java new file mode 100644 index 0000000000..69a1a0dfb2 --- /dev/null +++ b/hugegraph-core/src/main/java/com/baidu/hugegraph/backend/store/AbstractBackendStore.java @@ -0,0 +1,58 @@ +/* + * 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 + * License for the specific language governing permissions and limitations + * under the License. + */ + +package com.baidu.hugegraph.backend.store; + +import com.baidu.hugegraph.type.HugeType; + +public abstract class AbstractBackendStore implements BackendStore { + + private final MetaDispatcher dispatcher; + + public AbstractBackendStore() { + this.dispatcher = new MetaDispatcher(); + } + + protected MetaDispatcher metaDispatcher() { + return this.dispatcher; + } + + public + void registerMetaHandler(String name, MetaHandler handler) { + this.dispatcher.registerMetaHandler(name, handler); + } + + // Get metadata by key + public R metadata(HugeType type, String meta, Object[] args) { + BackendSession session = this.session(type); + MetaDispatcher dispatcher = null; + if (type == null) { + dispatcher = this.metaDispatcher(); + } else { + BackendTable table = this.table(type); + dispatcher = table.metaDispatcher(); + } + return dispatcher.dispatchMetaHandler(session, meta, args); + } + + protected abstract BackendTable table(HugeType type); + + // NOTE: Need to support passing null + protected abstract BackendSession session(HugeType type); +} diff --git a/hugegraph-core/src/main/java/com/baidu/hugegraph/backend/store/BackendMetrics.java b/hugegraph-core/src/main/java/com/baidu/hugegraph/backend/store/BackendMetrics.java new file mode 100644 index 0000000000..1f8c14dbd8 --- /dev/null +++ b/hugegraph-core/src/main/java/com/baidu/hugegraph/backend/store/BackendMetrics.java @@ -0,0 +1,40 @@ +/* + * 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 + * License for the specific language governing permissions and limitations + * under the License. + */ + +package com.baidu.hugegraph.backend.store; + +import java.util.Map; + +public interface BackendMetrics { + + public String BACKEND = "backend"; + + // Memory related metrics + public String MEM_USED = "mem_used"; + public String MEM_COMMITED = "mem_commited"; + public String MEM_MAX = "mem_max"; + public String MEM_UNIT = "mem_unit"; + + // Data load related metrics + public String DATA_SIZE = "data_size"; + + public String EXCEPTION = "exception"; + + public Map getMetrics(); +} diff --git a/hugegraph-core/src/main/java/com/baidu/hugegraph/backend/store/BackendTable.java b/hugegraph-core/src/main/java/com/baidu/hugegraph/backend/store/BackendTable.java index 40c91be663..f1070b5d48 100644 --- a/hugegraph-core/src/main/java/com/baidu/hugegraph/backend/store/BackendTable.java +++ b/hugegraph-core/src/main/java/com/baidu/hugegraph/backend/store/BackendTable.java @@ -22,10 +22,7 @@ import java.util.ArrayList; import java.util.Iterator; import java.util.List; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; -import com.baidu.hugegraph.backend.BackendException; import com.baidu.hugegraph.backend.query.ConditionQuery; import com.baidu.hugegraph.backend.query.IdQuery; import com.baidu.hugegraph.backend.query.Query; @@ -41,11 +38,11 @@ public abstract class BackendTable { private final String table; - private final Map> metaHandlers; + private final MetaDispatcher dispatcher; public BackendTable(String table) { this.table = table; - this.metaHandlers = new ConcurrentHashMap<>(); + this.dispatcher = new MetaDispatcher(); this.registerMetaHandlers(); } @@ -54,16 +51,12 @@ public String table() { return this.table; } - @SuppressWarnings("unchecked") - public R metadata(Session session, String meta, Object... args) { - if (!this.metaHandlers.containsKey(meta)) { - throw new BackendException("Invalid metadata name '%s'", meta); - } - return (R) this.metaHandlers.get(meta).handle(session, meta, args); + public MetaDispatcher metaDispatcher() { + return this.dispatcher; } public void registerMetaHandler(String name, MetaHandler handler) { - this.metaHandlers.put(name, handler); + this.dispatcher.registerMetaHandler(name, handler); } protected void registerMetaHandlers() { @@ -123,10 +116,6 @@ public static final String joinTableName(String prefix, String table) { public abstract void eliminate(Session session, Entry entry); - public interface MetaHandler { - public Object handle(Session session, String meta, Object... args); - } - /****************************** ShardSpliter ******************************/ public static abstract class ShardSpliter { diff --git a/hugegraph-core/src/main/java/com/baidu/hugegraph/backend/store/MetaDispatcher.java b/hugegraph-core/src/main/java/com/baidu/hugegraph/backend/store/MetaDispatcher.java new file mode 100644 index 0000000000..5c80d88b82 --- /dev/null +++ b/hugegraph-core/src/main/java/com/baidu/hugegraph/backend/store/MetaDispatcher.java @@ -0,0 +1,47 @@ +/* + * 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 + * License for the specific language governing permissions and limitations + * under the License. + */ + +package com.baidu.hugegraph.backend.store; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import com.baidu.hugegraph.backend.BackendException; + +public class MetaDispatcher { + + protected final Map metaHandlers; + + public MetaDispatcher() { + this.metaHandlers = new ConcurrentHashMap<>(); + } + + public void registerMetaHandler(String meta, MetaHandler handler) { + this.metaHandlers.put(meta, handler); + } + + @SuppressWarnings("unchecked") + public R dispatchMetaHandler(BackendSession session, + String meta, Object[] args) { + if (!this.metaHandlers.containsKey(meta)) { + throw new BackendException("Invalid metadata name '%s'", meta); + } + return (R) this.metaHandlers.get(meta).handle(session, meta, args); + } +} diff --git a/hugegraph-core/src/main/java/com/baidu/hugegraph/backend/store/MetaHandler.java b/hugegraph-core/src/main/java/com/baidu/hugegraph/backend/store/MetaHandler.java new file mode 100644 index 0000000000..f19270a450 --- /dev/null +++ b/hugegraph-core/src/main/java/com/baidu/hugegraph/backend/store/MetaHandler.java @@ -0,0 +1,25 @@ +/* + * 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 + * License for the specific language governing permissions and limitations + * under the License. + */ + +package com.baidu.hugegraph.backend.store; + +public interface MetaHandler { + + public Object handle(Session session, String meta, Object... args); +} diff --git a/hugegraph-core/src/main/java/com/baidu/hugegraph/backend/store/memory/InMemoryDBStore.java b/hugegraph-core/src/main/java/com/baidu/hugegraph/backend/store/memory/InMemoryDBStore.java index 553880ba8a..d1d921b9c3 100644 --- a/hugegraph-core/src/main/java/com/baidu/hugegraph/backend/store/memory/InMemoryDBStore.java +++ b/hugegraph-core/src/main/java/com/baidu/hugegraph/backend/store/memory/InMemoryDBStore.java @@ -30,13 +30,16 @@ import com.baidu.hugegraph.backend.id.Id; import com.baidu.hugegraph.backend.query.Query; import com.baidu.hugegraph.backend.serializer.TextBackendEntry; +import com.baidu.hugegraph.backend.store.AbstractBackendStore; import com.baidu.hugegraph.backend.store.BackendAction; import com.baidu.hugegraph.backend.store.BackendEntry; import com.baidu.hugegraph.backend.store.BackendFeatures; import com.baidu.hugegraph.backend.store.BackendMutation; -import com.baidu.hugegraph.backend.store.BackendStore; +import com.baidu.hugegraph.backend.store.BackendSession; import com.baidu.hugegraph.backend.store.BackendStoreProvider; +import com.baidu.hugegraph.backend.store.MetaDispatcher; import com.baidu.hugegraph.config.HugeConfig; +import com.baidu.hugegraph.exception.NotSupportException; import com.baidu.hugegraph.type.HugeType; import com.baidu.hugegraph.util.Log; @@ -53,7 +56,7 @@ * 1.remove by id + condition * 2.append/subtract edge-property */ -public class InMemoryDBStore implements BackendStore { +public class InMemoryDBStore extends AbstractBackendStore { private static final Logger LOG = Log.logger(InMemoryDBStore.class); @@ -76,13 +79,14 @@ public InMemoryDBStore(final BackendStoreProvider provider, @Override public R metadata(HugeType type, String meta, Object[] args) { - throw new UnsupportedOperationException("InMemoryDBStore.metadata()"); + throw new NotSupportException("InMemoryDBStore.metadata()"); } protected void registerTableManager(HugeType type, InMemoryDBTable table) { this.tables.put(type, table); } + @Override protected final InMemoryDBTable table(HugeType type) { assert type != null; InMemoryDBTable table = this.tables.get(type); @@ -92,6 +96,16 @@ protected final InMemoryDBTable table(HugeType type) { return table; } + @Override + protected BackendSession session(HugeType type) { + throw new NotSupportException("InMemoryDBStore.session()"); + } + + @Override + protected MetaDispatcher metaDispatcher() { + throw new NotSupportException("InMemoryDBStore.metaDispatcher()"); + } + @Override public Iterator query(Query query) { InMemoryDBTable table = this.table(InMemoryDBTable.tableType(query)); diff --git a/hugegraph-hbase/src/main/java/com/baidu/hugegraph/backend/store/hbase/HbaseStore.java b/hugegraph-hbase/src/main/java/com/baidu/hugegraph/backend/store/hbase/HbaseStore.java index 58c3b53b6c..8db4972e2f 100644 --- a/hugegraph-hbase/src/main/java/com/baidu/hugegraph/backend/store/hbase/HbaseStore.java +++ b/hugegraph-hbase/src/main/java/com/baidu/hugegraph/backend/store/hbase/HbaseStore.java @@ -34,18 +34,20 @@ import com.baidu.hugegraph.backend.BackendException; import com.baidu.hugegraph.backend.id.Id; import com.baidu.hugegraph.backend.query.Query; +import com.baidu.hugegraph.backend.store.AbstractBackendStore; import com.baidu.hugegraph.backend.store.BackendAction; import com.baidu.hugegraph.backend.store.BackendEntry; import com.baidu.hugegraph.backend.store.BackendFeatures; import com.baidu.hugegraph.backend.store.BackendMutation; -import com.baidu.hugegraph.backend.store.BackendStore; import com.baidu.hugegraph.backend.store.BackendStoreProvider; +import com.baidu.hugegraph.backend.store.MetaDispatcher; import com.baidu.hugegraph.config.HugeConfig; +import com.baidu.hugegraph.exception.NotSupportException; import com.baidu.hugegraph.type.HugeType; import com.baidu.hugegraph.util.E; import com.baidu.hugegraph.util.Log; -public abstract class HbaseStore implements BackendStore { +public abstract class HbaseStore extends AbstractBackendStore { private static final Logger LOG = Log.logger(HbaseStore.class); @@ -73,6 +75,7 @@ protected void registerTableManager(HugeType type, HbaseTable table) { this.tables.put(type, table); } + @Override protected final HbaseTable table(HugeType type) { assert type != null; HbaseTable table = this.tables.get(type); @@ -82,6 +85,12 @@ protected final HbaseTable table(HugeType type) { return table; } + @Override + protected HbaseSessions.Session session(HugeType type) { + this.checkOpened(); + return this.sessions.session(); + } + protected List tableNames() { return this.tables.values().stream().map(t -> t.table()) .collect(Collectors.toList()); @@ -283,12 +292,8 @@ public void rollbackTx() { } @Override - public R metadata(HugeType type, String meta, Object[] args) { - this.checkOpened(); - HbaseSessions.Session session = this.sessions.session(); - - HbaseTable table = this.table(type); - return table.metadata(session, meta, args); + public MetaDispatcher metaDispatcher() { + throw new NotSupportException("HBaseStore.metaDispatcher()"); } private void checkOpened() { diff --git a/hugegraph-mysql/src/main/java/com/baidu/hugegraph/backend/store/mysql/MysqlStore.java b/hugegraph-mysql/src/main/java/com/baidu/hugegraph/backend/store/mysql/MysqlStore.java index 4970cd6470..5fab742c0c 100644 --- a/hugegraph-mysql/src/main/java/com/baidu/hugegraph/backend/store/mysql/MysqlStore.java +++ b/hugegraph-mysql/src/main/java/com/baidu/hugegraph/backend/store/mysql/MysqlStore.java @@ -29,18 +29,20 @@ import com.baidu.hugegraph.backend.BackendException; import com.baidu.hugegraph.backend.id.Id; import com.baidu.hugegraph.backend.query.Query; +import com.baidu.hugegraph.backend.store.AbstractBackendStore; import com.baidu.hugegraph.backend.store.BackendAction; import com.baidu.hugegraph.backend.store.BackendEntry; import com.baidu.hugegraph.backend.store.BackendFeatures; import com.baidu.hugegraph.backend.store.BackendMutation; -import com.baidu.hugegraph.backend.store.BackendStore; import com.baidu.hugegraph.backend.store.BackendStoreProvider; +import com.baidu.hugegraph.backend.store.MetaDispatcher; import com.baidu.hugegraph.config.HugeConfig; +import com.baidu.hugegraph.exception.NotSupportException; import com.baidu.hugegraph.type.HugeType; import com.baidu.hugegraph.util.E; import com.baidu.hugegraph.util.Log; -public abstract class MysqlStore implements BackendStore { +public abstract class MysqlStore extends AbstractBackendStore { private static final Logger LOG = Log.logger(MysqlStore.class); @@ -251,7 +253,12 @@ public void rollbackTx() { @Override public R metadata(HugeType type, String meta, Object[] args) { - throw new UnsupportedOperationException("MysqlStore.metadata()"); + throw new NotSupportException("MysqlStore.metadata()"); + } + + @Override + protected MetaDispatcher metaDispatcher() { + throw new NotSupportException("MysqlStore.metaDispatcher()"); } @Override @@ -278,6 +285,7 @@ protected void clearTables() { } } + @Override protected final MysqlTable table(HugeType type) { assert type != null; MysqlTable table = this.tables.get(type); @@ -287,6 +295,12 @@ protected final MysqlTable table(HugeType type) { return table; } + @Override + protected MysqlSessions.Session session(HugeType type) { + this.checkSessionConnected(); + return this.sessions.session(); + } + protected final void checkClusterConnected() { E.checkState(this.sessions != null, "MySQL store has not been initialized"); diff --git a/hugegraph-rocksdb/src/main/java/com/baidu/hugegraph/backend/store/rocksdb/RocksDBMetrics.java b/hugegraph-rocksdb/src/main/java/com/baidu/hugegraph/backend/store/rocksdb/RocksDBMetrics.java new file mode 100644 index 0000000000..8936699e4f --- /dev/null +++ b/hugegraph-rocksdb/src/main/java/com/baidu/hugegraph/backend/store/rocksdb/RocksDBMetrics.java @@ -0,0 +1,60 @@ +/* + * 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 + * License for the specific language governing permissions and limitations + * under the License. + */ + +package com.baidu.hugegraph.backend.store.rocksdb; + +import java.util.Map; + +import com.baidu.hugegraph.backend.store.BackendMetrics; +import com.baidu.hugegraph.util.Bytes; +import com.baidu.hugegraph.util.InsertionOrderUtil; + +public class RocksDBMetrics implements BackendMetrics { + + private static final String INDEX_FILTER = + "rocksdb.estimate-table-readers-mem"; + private static final String MEM_TABLE = "rocksdb.cur-size-all-mem-tables"; + private static final String R_DATA_SIZE = "rocksdb.estimate-live-data-size"; + + private final RocksDBSessions.Session session; + + public RocksDBMetrics(RocksDBSessions.Session session) { + this.session = session; + } + + @Override + public Map getMetrics() { + Map metrics = InsertionOrderUtil.newMap(); + // NOTE: the unit of rocksdb mem property is kb + metrics.put(MEM_USED, this.getMemUsed() / Bytes.BASE); + metrics.put(MEM_UNIT, "MB"); + metrics.put(DATA_SIZE, this.getDataSize()); + return metrics; + } + + private long getMemUsed() { + long indexFilter = Long.parseLong(this.session.property(INDEX_FILTER)); + long memtable = Long.parseLong(this.session.property(MEM_TABLE)); + return indexFilter + memtable; + } + + private long getDataSize() { + return Long.parseLong(this.session.property(R_DATA_SIZE)); + } +} diff --git a/hugegraph-rocksdb/src/main/java/com/baidu/hugegraph/backend/store/rocksdb/RocksDBSessions.java b/hugegraph-rocksdb/src/main/java/com/baidu/hugegraph/backend/store/rocksdb/RocksDBSessions.java index 8f24b5054c..1500e8d6d1 100644 --- a/hugegraph-rocksdb/src/main/java/com/baidu/hugegraph/backend/store/rocksdb/RocksDBSessions.java +++ b/hugegraph-rocksdb/src/main/java/com/baidu/hugegraph/backend/store/rocksdb/RocksDBSessions.java @@ -54,6 +54,7 @@ public static abstract class Session extends BackendSession { public static final int SCAN_LT_END = 0x10; public static final int SCAN_LTE_END = 0x30; + public abstract String property(String property); public abstract String property(String table, String property); public abstract void put(String table, byte[] key, byte[] value); diff --git a/hugegraph-rocksdb/src/main/java/com/baidu/hugegraph/backend/store/rocksdb/RocksDBStdSessions.java b/hugegraph-rocksdb/src/main/java/com/baidu/hugegraph/backend/store/rocksdb/RocksDBStdSessions.java index b8ff69bd52..16f64462c9 100644 --- a/hugegraph-rocksdb/src/main/java/com/baidu/hugegraph/backend/store/rocksdb/RocksDBStdSessions.java +++ b/hugegraph-rocksdb/src/main/java/com/baidu/hugegraph/backend/store/rocksdb/RocksDBStdSessions.java @@ -419,6 +419,18 @@ public boolean hasChanges() { return this.batch.count() > 0; } + /** + * Get property value + */ + @Override + public String property(String property) { + try { + return rocksdb().getProperty(property); + } catch (RocksDBException e) { + throw new BackendException(e); + } + } + /** * Get property value by name from specified table */ diff --git a/hugegraph-rocksdb/src/main/java/com/baidu/hugegraph/backend/store/rocksdb/RocksDBStore.java b/hugegraph-rocksdb/src/main/java/com/baidu/hugegraph/backend/store/rocksdb/RocksDBStore.java index 2ce914a5fb..d78fddfe5c 100644 --- a/hugegraph-rocksdb/src/main/java/com/baidu/hugegraph/backend/store/rocksdb/RocksDBStore.java +++ b/hugegraph-rocksdb/src/main/java/com/baidu/hugegraph/backend/store/rocksdb/RocksDBStore.java @@ -39,11 +39,11 @@ import com.baidu.hugegraph.backend.BackendException; import com.baidu.hugegraph.backend.id.Id; import com.baidu.hugegraph.backend.query.Query; +import com.baidu.hugegraph.backend.store.AbstractBackendStore; import com.baidu.hugegraph.backend.store.BackendAction; import com.baidu.hugegraph.backend.store.BackendEntry; import com.baidu.hugegraph.backend.store.BackendFeatures; import com.baidu.hugegraph.backend.store.BackendMutation; -import com.baidu.hugegraph.backend.store.BackendStore; import com.baidu.hugegraph.backend.store.BackendStoreProvider; import com.baidu.hugegraph.backend.store.rocksdb.RocksDBSessions.Session; import com.baidu.hugegraph.config.HugeConfig; @@ -52,7 +52,7 @@ import com.baidu.hugegraph.util.Log; import com.google.common.collect.ImmutableList; -public abstract class RocksDBStore implements BackendStore { +public abstract class RocksDBStore extends AbstractBackendStore { private static final Logger LOG = Log.logger(RocksDBStore.class); @@ -80,12 +80,23 @@ public RocksDBStore(final BackendStoreProvider provider, this.store = store; this.sessions = null; this.tableDiskMapping = new HashMap<>(); + + this.registerMetaHandlers(); + } + + private void registerMetaHandlers() { + this.registerMetaHandler("metrics", (session, meta, args) -> { + RocksDBMetrics metrics = new RocksDBMetrics( + (RocksDBSessions.Session) session); + return metrics.getMetrics(); + }); } protected void registerTableManager(HugeType type, RocksDBTable table) { this.tables.put(type, table); } + @Override protected final RocksDBTable table(HugeType type) { assert type != null; RocksDBTable table = this.tables.get(type); @@ -372,12 +383,7 @@ public void rollbackTx() { } @Override - public R metadata(HugeType type, String meta, Object[] args) { - RocksDBTable table = this.table(type); - return table.metadata(this.session(type), meta, args); - } - - private Session session(HugeType tableType) { + protected Session session(HugeType tableType) { this.checkOpened(); // Optimized disk diff --git a/hugegraph-rocksdb/src/main/java/com/baidu/hugegraph/backend/store/rocksdbsst/RocksDBSstSessions.java b/hugegraph-rocksdb/src/main/java/com/baidu/hugegraph/backend/store/rocksdbsst/RocksDBSstSessions.java index de0e80cbbe..0deecbd3cf 100644 --- a/hugegraph-rocksdb/src/main/java/com/baidu/hugegraph/backend/store/rocksdbsst/RocksDBSstSessions.java +++ b/hugegraph-rocksdb/src/main/java/com/baidu/hugegraph/backend/store/rocksdbsst/RocksDBSstSessions.java @@ -22,8 +22,12 @@ import java.io.File; import java.nio.file.Path; import java.nio.file.Paths; -import java.util.*; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import java.util.Map.Entry; +import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import org.apache.commons.lang3.tuple.Pair; @@ -213,6 +217,14 @@ public Integer commit() { return count; } + /** + * Get property value + */ + @Override + public String property(String property) { + throw new NotSupportException("RocksDBSstStore property()"); + } + /** * Get property value by name from specified table */