You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@iotdb.apache.org by su...@apache.org on 2019/06/06 08:18:47 UTC
[incubator-iotdb] branch time_statstic updated: jmx dynamic control
parameter and function
This is an automated email from the ASF dual-hosted git repository.
suyue pushed a commit to branch time_statstic
in repository https://gitbox.apache.org/repos/asf/incubator-iotdb.git
The following commit(s) were added to refs/heads/time_statstic by this push:
new 1fe9860 jmx dynamic control parameter and function
1fe9860 is described below
commit 1fe986058f6d710995aa55c2594d49e0c331ee8f
Author: suyue <23...@qq.com>
AuthorDate: Thu Jun 6 16:17:52 2019 +0800
jmx dynamic control parameter and function
---
iotdb/iotdb/conf/iotdb-engine.properties | 4 +-
iotdb/iotdb/conf/logback.xml | 2 +-
.../java/org/apache/iotdb/db/conf/IoTDBConfig.java | 27 +-
.../org/apache/iotdb/db/conf/IoTDBDescriptor.java | 9 +-
.../apache/iotdb/db/cost/stastic/Measurement.java | 144 --------
.../iotdb/db/cost/statistic/Measurement.java | 387 +++++++++++++++++++++
.../iotdb/db/cost/statistic/MeasurementMBean.java | 46 +++
.../db/cost/{stastic => statistic}/Operation.java | 2 +-
.../org/apache/iotdb/db/cost/statistic/Test.java | 35 ++
.../iotdb/db/engine/filenode/FileNodeManager.java | 4 +-
.../org/apache/iotdb/db/qp/QueryProcessor.java | 4 +-
.../iotdb/db/qp/executor/OverflowQPExecutor.java | 4 +-
.../java/org/apache/iotdb/db/service/IoTDB.java | 2 +
.../org/apache/iotdb/db/service/ServiceType.java | 3 +-
.../org/apache/iotdb/db/service/TSServiceImpl.java | 4 +-
15 files changed, 511 insertions(+), 166 deletions(-)
diff --git a/iotdb/iotdb/conf/iotdb-engine.properties b/iotdb/iotdb/conf/iotdb-engine.properties
index f97b542..f8bca91 100644
--- a/iotdb/iotdb/conf/iotdb-engine.properties
+++ b/iotdb/iotdb/conf/iotdb-engine.properties
@@ -222,6 +222,8 @@ update_historical_data_possibility=false
# performance statistic configuration
# Is stat time cost of sub-module in write process enable
-enable_write_performance_stat=true
+enable_performance_stat=false
# The interval of small flush in ms.
performance_stat_display_interval=60000
+# The memory used for performance_stat.
+performance_stat_memory_in_kb=20
diff --git a/iotdb/iotdb/conf/logback.xml b/iotdb/iotdb/conf/logback.xml
index 7e04838..ff7c459 100644
--- a/iotdb/iotdb/conf/logback.xml
+++ b/iotdb/iotdb/conf/logback.xml
@@ -153,7 +153,7 @@
<appender-ref ref="FILEALL"/>
<appender-ref ref="stdout"/>
</root>
- <logger level="info" name="org.apache.iotdb.db.cost.stastic">
+ <logger level="info" name="org.apache.iotdb.db.cost.statistic">
<appender-ref ref="FILE_COST_MEASURE"/>
</logger>
</configuration>
diff --git a/iotdb/src/main/java/org/apache/iotdb/db/conf/IoTDBConfig.java b/iotdb/src/main/java/org/apache/iotdb/db/conf/IoTDBConfig.java
index 178d517..22b0bab 100644
--- a/iotdb/src/main/java/org/apache/iotdb/db/conf/IoTDBConfig.java
+++ b/iotdb/src/main/java/org/apache/iotdb/db/conf/IoTDBConfig.java
@@ -283,15 +283,20 @@ public class IoTDBConfig {
private String rpcImplClassName = TSServiceImpl.class.getName();
/**
- * Is stat time cost of sub-module in write process enable.
+ * Is stat performance of sub-module enable.
*/
- private boolean enableWritePerformanceStat = false;
+ private boolean enablePerformanceStat = false;
/**
- * The display of stat time cost interval in ms.
+ * The display of stat performance interval in ms.
*/
private long performanceStatDisplayInterval = 60000;
+ /**
+ * The memory used for stat performance.
+ */
+ private int performance_stat_memory_in_kb = 20;
+
public IoTDBConfig() {
// empty constructor
}
@@ -840,12 +845,12 @@ public class IoTDBConfig {
this.rpcImplClassName = rpcImplClassName;
}
- public boolean isEnableWritePerformanceStat() {
- return enableWritePerformanceStat;
+ public boolean isEnablePerformanceStat() {
+ return enablePerformanceStat;
}
- public void setEnableWritePerformanceStat(boolean enableWritePerformanceStat) {
- this.enableWritePerformanceStat = enableWritePerformanceStat;
+ public void setEnablePerformanceStat(boolean enablePerformanceStat) {
+ this.enablePerformanceStat = enablePerformanceStat;
}
public long getPerformanceStatDisplayInterval() {
@@ -855,4 +860,12 @@ public class IoTDBConfig {
public void setPerformanceStatDisplayInterval(long performanceStatDisplayInterval) {
this.performanceStatDisplayInterval = performanceStatDisplayInterval;
}
+
+ public int getPerformance_stat_memory_in_kb() {
+ return performance_stat_memory_in_kb;
+ }
+
+ public void setPerformance_stat_memory_in_kb(int performance_stat_memory_in_kb) {
+ this.performance_stat_memory_in_kb = performance_stat_memory_in_kb;
+ }
}
diff --git a/iotdb/src/main/java/org/apache/iotdb/db/conf/IoTDBDescriptor.java b/iotdb/src/main/java/org/apache/iotdb/db/conf/IoTDBDescriptor.java
index 571012c..0f1d752 100644
--- a/iotdb/src/main/java/org/apache/iotdb/db/conf/IoTDBDescriptor.java
+++ b/iotdb/src/main/java/org/apache/iotdb/db/conf/IoTDBDescriptor.java
@@ -251,13 +251,16 @@ public class IoTDBDescriptor {
conf.getZoneID(), e);
}
- conf.setEnableWritePerformanceStat(Boolean
- .parseBoolean(properties.getProperty("enable_write_performance_stat",
- Boolean.toString(conf.isEnableWritePerformanceStat())).trim()));
+ conf.setEnablePerformanceStat(Boolean
+ .parseBoolean(properties.getProperty("enable_performance_stat",
+ Boolean.toString(conf.isEnablePerformanceStat())).trim()));
conf.setPerformanceStatDisplayInterval(Long
.parseLong(properties.getProperty("performance_stat_display_interval",
Long.toString(conf.getPerformanceStatDisplayInterval())).trim()));
+ conf.setPerformance_stat_memory_in_kb(Integer
+ .parseInt(properties.getProperty("performance_stat_memory_in_kb",
+ Integer.toString(conf.getPerformance_stat_memory_in_kb())).trim()));
} catch (IOException e) {
LOGGER.warn("Cannot load config file because, use default configuration", e);
} catch (Exception e) {
diff --git a/iotdb/src/main/java/org/apache/iotdb/db/cost/stastic/Measurement.java b/iotdb/src/main/java/org/apache/iotdb/db/cost/stastic/Measurement.java
deleted file mode 100644
index fba0493..0000000
--- a/iotdb/src/main/java/org/apache/iotdb/db/cost/stastic/Measurement.java
+++ /dev/null
@@ -1,144 +0,0 @@
-/**
- * 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.iotdb.db.cost.stastic;
-
-import java.util.Date;
-import java.util.Queue;
-import java.util.concurrent.ConcurrentLinkedQueue;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
-import org.apache.iotdb.db.concurrent.IoTDBThreadPoolFactory;
-import org.apache.iotdb.db.concurrent.ThreadName;
-import org.apache.iotdb.db.conf.IoTDBDescriptor;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class Measurement {
-
- /**
- * queue for store time latrncies async.
- */
- private Queue<Long>[] operationLatenciesQueue;
-
- /**
- * latencies sum of each operation.
- */
- private long[] operationLatencies;
-
- /**
- * count of each operation.
- */
- private long[] operationCnt;
-
- /**
- * display thread.
- */
- private ScheduledExecutorService service;
-
- public static final Measurement INSTANCE = AsyncMeasurementHolder.MEASUREMENT;
-
- private boolean isEnableStat;
- private long displayIntervalInMs;
- private static final Logger LOGGER = LoggerFactory.getLogger(Measurement.class);
-
-
-
- private Measurement(){
- isEnableStat = IoTDBDescriptor.getInstance().getConfig().isEnableWritePerformanceStat();
- if (isEnableStat) {
- displayIntervalInMs = IoTDBDescriptor.getInstance().getConfig().getPerformanceStatDisplayInterval();
- operationLatenciesQueue = new ConcurrentLinkedQueue[Operation.values().length];
- operationLatencies = new long[Operation.values().length];
- operationCnt = new long[Operation.values().length];
- for (Operation op : Operation.values()){
- operationLatenciesQueue[op.ordinal()] = new ConcurrentLinkedQueue<>();
- operationCnt[op.ordinal()] = 0;
- operationLatencies[op.ordinal()] = 0;
- }
-
- for (int i =0; i <operationLatenciesQueue.length; i++) {
- new Thread(new NumThread(i)).start();
- }
-
- service = IoTDBThreadPoolFactory.newScheduledThreadPool(1,
- ThreadName.TIME_COST_STATSTIC.getName());
- service.scheduleWithFixedDelay(
- new Measurement.DisplayRunnable(), 10, displayIntervalInMs, TimeUnit.MILLISECONDS);
- System.out.println("init finish!");
- }
- }
- class NumThread implements Runnable{
- int i;
- public NumThread(int i) {
- this.i = i;
- }
-
- @Override
- public void run() {
- Queue<Long> queue = operationLatenciesQueue[i];
- while (true) {
- Long time = queue.poll();
- if (time != null) {
- operationLatencies[i] += time;
- operationCnt[i]++;
- }else {
- try {
- Thread.sleep(10);
- } catch (InterruptedException e) {
- }
- }
- }
- }
- }
-
- public void addOperationLatency(Operation op, long startTime) {
- if (isEnableStat) {
- operationLatenciesQueue[op.ordinal()].add((System.nanoTime() - startTime));
- }
- }
-
- private static class AsyncMeasurementHolder{
- private static final Measurement MEASUREMENT = new Measurement();
- private AsyncMeasurementHolder(){}
- }
-
- public void showMeasurements() {
- Date date = new Date();
- LOGGER.info("====================================={} Measurement (ms)======================================", date.toString());
- String head = String.format("%-45s%-30s%-30s%-30s","OPERATION", "COUNT", "TOTAL_TIME", "AVG_TIME");
- LOGGER.info(head);
- for(Operation operation : Operation.values()){
- long cnt = operationCnt[operation.ordinal()];
- long totalInMs = 0;
- totalInMs = operationLatencies[operation.ordinal()] / 1000000;
- String avg = String.format("%.4f", (totalInMs/(cnt+1e-9)));
- String item = String.format("%-45s%-30s%-30s%-30s", operation.name, cnt+"", totalInMs+"", avg);
- LOGGER.info(item);
- }
- LOGGER.info(
- "=================================================================================================================");
- }
-
- class DisplayRunnable implements Runnable{
- @Override
- public void run() {
- showMeasurements();
- }
- }
-}
diff --git a/iotdb/src/main/java/org/apache/iotdb/db/cost/statistic/Measurement.java b/iotdb/src/main/java/org/apache/iotdb/db/cost/statistic/Measurement.java
new file mode 100644
index 0000000..650bb3e
--- /dev/null
+++ b/iotdb/src/main/java/org/apache/iotdb/db/cost/statistic/Measurement.java
@@ -0,0 +1,387 @@
+/**
+ * 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.iotdb.db.cost.statistic;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Queue;
+import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.Future;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.ReentrantLock;
+import org.apache.iotdb.db.concurrent.IoTDBThreadPoolFactory;
+import org.apache.iotdb.db.concurrent.ThreadName;
+import org.apache.iotdb.db.conf.IoTDBConfig;
+import org.apache.iotdb.db.conf.IoTDBConstant;
+import org.apache.iotdb.db.conf.IoTDBDescriptor;
+import org.apache.iotdb.db.exception.StartupException;
+import org.apache.iotdb.db.service.IService;
+import org.apache.iotdb.db.service.JMXService;
+import org.apache.iotdb.db.service.ServiceType;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * <p>
+ * Measurement is used to record execution time of operations defined in enum class Operation.
+ * It can display average time of each operation, and proportion of operation whose execution time
+ * fall into time range defined in BUCKET_IN_MS. If you want to change abscissa of histogram, just
+ * change the BUCKET_IN_MS array.
+ * For recording a operation, you should:
+ * 1) add a item in enum class Operation.
+ * 2) call <code>startTimeInNano = System.nanoTime()</code> to recode startTime of that operation.
+ * 3) call <code>Measurement.INSTANCE.addOperationLatency(operation, startTimeInNano)</code> at the
+ * end of that operation;
+ * @see Operation
+ */
+public class Measurement implements MeasurementMBean, IService {
+
+ /**
+ * queue for async store time latencies.
+ */
+ private Queue<Long>[] operationLatenciesQueue;
+
+ /**
+ * size of each queue, this is calculated by memory.
+ */
+ private final long QUEUE_SIZE;
+
+ /**
+ * latencies sum of each operation.
+ */
+ private long[] operationLatencies;
+
+ /**
+ * the num of each operation.
+ */
+ private long[] operationCnt;
+
+ /**
+ * abscissa of histogram.
+ */
+ private final int BUCKET_IN_MS[] = {1, 4, 16, 64, 256, 1024, Integer.MAX_VALUE};
+
+ /**
+ * length of BUCKET_IN_MS.
+ */
+ private final int BUCKET_SIZE = BUCKET_IN_MS.length;
+
+ /**
+ * the num of operation that execution time falls into time range of BUCKET_IN_MS. The outer array
+ * is each operation, the inner array is each time range in BUCKET_IN_MS.
+ */
+ private long[][] operationHistogram;
+
+ /**
+ * display thread and queue consumer thread.
+ */
+ private ScheduledExecutorService service;
+
+ /**
+ * future task of display thread and queue consumer thread.
+ */
+ private List<Future<?>> futureList;
+
+ /**
+ * lock for change state: start() and stopStatistic().
+ */
+ private ReentrantLock stateChangeLock = new ReentrantLock();
+
+ public static final Measurement INSTANCE = AsyncMeasurementHolder.MEASUREMENT;
+
+ private boolean isEnableStat;
+ private long displayIntervalInMs;
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(Measurement.class);
+ private final int MS_TO_NANO = 1000_000;
+ private final String mbeanName = String
+ .format("%s:%s=%s", "org.apache.iotdb.db.cost.statistic", IoTDBConstant.JMX_TYPE,
+ getID().getJmxName());
+
+ private Measurement() {
+ IoTDBConfig tdbConfig = IoTDBDescriptor.getInstance().getConfig();
+ isEnableStat = tdbConfig.isEnablePerformanceStat();
+ displayIntervalInMs = tdbConfig.getPerformanceStatDisplayInterval();
+ int memory_in_kb = tdbConfig.getPerformance_stat_memory_in_kb();
+
+ QUEUE_SIZE = memory_in_kb * 1000 / Operation.values().length / 8;
+ operationLatenciesQueue = new ConcurrentLinkedQueue[Operation.values().length];
+ operationLatencies = new long[Operation.values().length];
+ operationCnt = new long[Operation.values().length];
+ for (Operation op : Operation.values()) {
+ operationLatenciesQueue[op.ordinal()] = new ConcurrentLinkedQueue<>();
+ operationCnt[op.ordinal()] = 0;
+ operationLatencies[op.ordinal()] = 0;
+ }
+ operationHistogram = new long[Operation.values().length][BUCKET_SIZE];
+ for (Operation operation : Operation.values()) {
+ for (int i = 0; i < BUCKET_SIZE; i++) {
+ operationHistogram[operation.ordinal()][i] = 0;
+ }
+ }
+
+ service = IoTDBThreadPoolFactory.newScheduledThreadPool(
+ 2, ThreadName.TIME_COST_STATSTIC.getName());
+ futureList = new ArrayList<>();
+ }
+
+ public void addOperationLatency(Operation op, long startTime) {
+ if (isEnableStat && operationLatenciesQueue[op.ordinal()].size() < QUEUE_SIZE) {
+ operationLatenciesQueue[op.ordinal()].add((System.nanoTime() - startTime));
+ }
+ }
+
+ @Override
+ public void startContinuousStatistics() {
+ stateChangeLock.lock();
+ try {
+ if (isEnableStat) {
+ return;
+ }
+ isEnableStat = true;
+ futureList.clear();
+ Future future = service.scheduleWithFixedDelay(
+ new Measurement.DisplayRunnable(), 20, displayIntervalInMs, TimeUnit.MILLISECONDS);
+ futureList.add(future);
+ futureList.add(service.schedule(new QueueConsumerThread(), 10, TimeUnit.MILLISECONDS));
+
+
+ } catch (Exception e) {
+ LOGGER.error("Find error when start performance statistic thread, because {}", e);
+ } finally {
+ stateChangeLock.unlock();
+ }
+ }
+
+ @Override
+ public void startOneTimeStatistics(){
+ stateChangeLock.lock();
+ try {
+ if (isEnableStat) {
+ return;
+ }
+ isEnableStat = true;
+ futureList.clear();
+ futureList.add(service.schedule(new QueueConsumerThread(), 10, TimeUnit.MILLISECONDS));
+ Future future = service.schedule(()->{
+ showMeasurements();
+ stopStatistic();
+ }, displayIntervalInMs, TimeUnit.MILLISECONDS);
+ futureList.add(future);
+ } catch (Exception e) {
+ LOGGER.error("Find error when start performance statistic thread, because {}", e);
+ } finally {
+ stateChangeLock.unlock();
+ }
+ }
+
+ @Override
+ public void stopStatistic() {
+ stateChangeLock.lock();
+ try {
+ if(isEnableStat == false){
+ return;
+ }
+ isEnableStat = false;
+ for (Future future : futureList) {
+ if (future != null) {
+ future.cancel(true);
+
+ }
+ }
+ } catch (Exception e) {
+ LOGGER.error("Find error when stopStatistic time cost statstic thread, because {}", e);
+ } finally {
+ stateChangeLock.unlock();
+ }
+
+ }
+
+ /**
+ * start service.
+ */
+ @Override
+ public void start() throws StartupException {
+ // start display thread and consumer threads.
+ if (isEnableStat) {
+ Future future = service.scheduleWithFixedDelay(
+ new Measurement.DisplayRunnable(), 20, displayIntervalInMs, TimeUnit.MILLISECONDS);
+ futureList.add(future);
+ futureList.add(service.schedule(new QueueConsumerThread(), 10, TimeUnit.MILLISECONDS));
+
+ }
+ try {
+ JMXService.registerMBean(INSTANCE, mbeanName);
+ } catch (Exception e) {
+ String errorMessage = String
+ .format("Failed to start %s because of %s", this.getID().getName(),
+ e.getMessage());
+ throw new StartupException(errorMessage, e);
+ }
+ }
+
+ /**
+ * stop service.
+ */
+ @Override
+ public void stop() {
+ JMXService.deregisterMBean(mbeanName);
+ if (service == null || service.isShutdown()) {
+ return;
+ }
+ stopStatistic();
+ futureList.clear();
+ service.shutdownNow();
+ try {
+ service.awaitTermination(5, TimeUnit.SECONDS);
+ } catch (InterruptedException e) {
+ LOGGER.error("Performance statistic service could not be shutdown, {}", e.getMessage());
+ // Restore interrupted state...
+ Thread.currentThread().interrupt();
+ }
+ }
+
+ @Override
+ public ServiceType getID() {
+ return ServiceType.PERFORMANCE_STATISTIC_SERVICE;
+ }
+
+ @Override
+ public boolean isEnableStat() {
+ return isEnableStat;
+ }
+
+ @Override
+ public void setEnableStat(boolean enableStat) {
+ isEnableStat = enableStat;
+ }
+
+ public long getDisplayIntervalInMs() {
+ return displayIntervalInMs;
+ }
+
+ public void setDisplayIntervalInMs(long displayIntervalInMs) {
+ this.displayIntervalInMs = displayIntervalInMs;
+ }
+
+ private static class AsyncMeasurementHolder {
+
+ private static final Measurement MEASUREMENT = new Measurement();
+
+ private AsyncMeasurementHolder() {
+ }
+ }
+
+ private void showMeasurements() {
+ Date date = new Date();
+ LOGGER.info(
+ "====================================={} Measurement (ms)======================================",
+ date.toString());
+ String head = String
+ .format("%-45s%-25s%-25s%-25s", "OPERATION", "COUNT", "TOTAL_TIME", "AVG_TIME");
+ LOGGER.info(head);
+ for (Operation operation : Operation.values()) {
+ long cnt = operationCnt[operation.ordinal()];
+ long totalInMs = 0;
+ totalInMs = operationLatencies[operation.ordinal()] / 1000000;
+ String avg = String.format("%.4f", (totalInMs / (cnt + 1e-9)));
+ String item = String
+ .format("%-45s%-25s%-25s%-25s", operation.name, cnt + "", totalInMs + "", avg);
+ LOGGER.info(item);
+ }
+ LOGGER.info(
+ "==========================================OPERATION HISTOGRAM====================================================");
+ String histogramHead = String.format("%-45s", "OPERATION");
+ for (int i = 0; i < BUCKET_SIZE; i++) {
+ histogramHead += String.format("%-8s", BUCKET_IN_MS[i] + "ms");
+ }
+ LOGGER.info(histogramHead);
+ for (Operation operation : Operation.values()) {
+ String item = String.format("%-45s", operation.getName());
+ long cnt = operationCnt[operation.ordinal()];
+ for (int i = 0; i < BUCKET_SIZE; i++) {
+ String avg = String
+ .format("%.2f", (operationHistogram[operation.ordinal()][i] / (cnt + 1e-9) * 100));
+ item += String.format("%-8s", avg + "%");
+ }
+ LOGGER.info(item);
+ }
+
+ LOGGER.info(
+ "=================================================================================================================");
+ }
+
+ class DisplayRunnable implements Runnable {
+
+ @Override
+ public void run() {
+ showMeasurements();
+ }
+ }
+
+ class QueueConsumerThread implements Runnable {
+
+ @Override
+ public void run() {
+ consumer();
+ }
+
+ private void consumer(){
+ int cnt = 0;
+ boolean allEmpty = false;
+ while (true) {
+ cnt++;
+ if (cnt > 2 * QUEUE_SIZE || allEmpty) {
+ try {
+ Thread.sleep(1000);
+ cnt = 0;
+ allEmpty = false;
+ continue;
+ } catch (InterruptedException e) {
+ return;
+ }
+ }
+ allEmpty = true;
+ for (Operation op : Operation.values()) {
+ int idx = op.ordinal();
+ Queue<Long> queue = operationLatenciesQueue[idx];
+ Long time = queue.poll();
+ if (time != null) {
+ operationLatencies[idx] += time;
+ operationCnt[idx]++;
+ operationHistogram[idx][calIndex(time)]++;
+ allEmpty = false;
+ }
+ }
+ }
+ }
+ }
+ private int calIndex(long x) {
+ x /= MS_TO_NANO;
+ for (int i = 0; i < MS_TO_NANO; i++) {
+ if (BUCKET_IN_MS[i] >= x) {
+ return i;
+ }
+ }
+ return BUCKET_SIZE - 1;
+ }
+
+}
diff --git a/iotdb/src/main/java/org/apache/iotdb/db/cost/statistic/MeasurementMBean.java b/iotdb/src/main/java/org/apache/iotdb/db/cost/statistic/MeasurementMBean.java
new file mode 100644
index 0000000..4250f9c
--- /dev/null
+++ b/iotdb/src/main/java/org/apache/iotdb/db/cost/statistic/MeasurementMBean.java
@@ -0,0 +1,46 @@
+/**
+ * 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.iotdb.db.cost.statistic;
+
+public interface MeasurementMBean {
+
+ /**
+ * start display performance statistic every interval of displayIntervalInMs.
+ */
+ void startContinuousStatistics();
+
+ /**
+ * start display performance statistic after interval of displayIntervalInMs.
+ */
+ void startOneTimeStatistics();
+
+ /**
+ * stop display performance statistic.
+ */
+ void stopStatistic();
+
+ boolean isEnableStat();
+
+ void setEnableStat(boolean enableStat);
+
+ long getDisplayIntervalInMs();
+
+ void setDisplayIntervalInMs(long displayIntervalInMs);
+}
diff --git a/iotdb/src/main/java/org/apache/iotdb/db/cost/stastic/Operation.java b/iotdb/src/main/java/org/apache/iotdb/db/cost/statistic/Operation.java
similarity index 97%
rename from iotdb/src/main/java/org/apache/iotdb/db/cost/stastic/Operation.java
rename to iotdb/src/main/java/org/apache/iotdb/db/cost/statistic/Operation.java
index d140fe9..4e5c363 100644
--- a/iotdb/src/main/java/org/apache/iotdb/db/cost/stastic/Operation.java
+++ b/iotdb/src/main/java/org/apache/iotdb/db/cost/statistic/Operation.java
@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.iotdb.db.cost.stastic;
+package org.apache.iotdb.db.cost.statistic;
public enum Operation {
EXECUTE_BATCH_SQL("EXECUTE_BATCH_SQL"),
diff --git a/iotdb/src/main/java/org/apache/iotdb/db/cost/statistic/Test.java b/iotdb/src/main/java/org/apache/iotdb/db/cost/statistic/Test.java
new file mode 100644
index 0000000..2172a87
--- /dev/null
+++ b/iotdb/src/main/java/org/apache/iotdb/db/cost/statistic/Test.java
@@ -0,0 +1,35 @@
+package org.apache.iotdb.db.cost.statistic;
+
+public class Test {
+
+ public static void main(String[] args) {
+ Measurement.INSTANCE.addOperationLatency(Operation.EXECUTE_BATCH_SQL, System.nanoTime());
+ Measurement.INSTANCE.addOperationLatency(Operation.EXECUTE_BATCH_SQL, System.nanoTime()-8000000);
+
+ try {
+ Measurement.INSTANCE.start();
+ Measurement.INSTANCE.startContinuousStatistics();
+ Measurement.INSTANCE.addOperationLatency(Operation.EXECUTE_BATCH_SQL, System.nanoTime());
+ Measurement.INSTANCE.addOperationLatency(Operation.EXECUTE_BATCH_SQL, System.nanoTime()-8000000);
+ Thread.currentThread().sleep(2000);
+ Measurement.INSTANCE.stopStatistic();
+ Measurement.INSTANCE.stopStatistic();
+ Measurement.INSTANCE.stopStatistic();
+ System.out.println("After stopStatistic!");
+ Thread.currentThread().sleep(1000);
+ Measurement.INSTANCE.startContinuousStatistics();
+ System.out.println("RE start!");
+ Thread.currentThread().sleep(2000);
+ Measurement.INSTANCE.startContinuousStatistics();
+ System.out.println("RE start2!");
+ Thread.currentThread().sleep(2000);
+ Measurement.INSTANCE.stopStatistic();
+ System.out.println("After stopStatistic2!");
+ Measurement.INSTANCE.stop();
+
+ }
+ catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/iotdb/src/main/java/org/apache/iotdb/db/engine/filenode/FileNodeManager.java b/iotdb/src/main/java/org/apache/iotdb/db/engine/filenode/FileNodeManager.java
index 2adf3f6..49f8f2c 100644
--- a/iotdb/src/main/java/org/apache/iotdb/db/engine/filenode/FileNodeManager.java
+++ b/iotdb/src/main/java/org/apache/iotdb/db/engine/filenode/FileNodeManager.java
@@ -36,8 +36,8 @@ import org.apache.iotdb.db.conf.IoTDBConfig;
import org.apache.iotdb.db.conf.IoTDBConstant;
import org.apache.iotdb.db.conf.IoTDBDescriptor;
import org.apache.iotdb.db.conf.directories.Directories;
-import org.apache.iotdb.db.cost.stastic.Measurement;
-import org.apache.iotdb.db.cost.stastic.Operation;
+import org.apache.iotdb.db.cost.statistic.Measurement;
+import org.apache.iotdb.db.cost.statistic.Operation;
import org.apache.iotdb.db.engine.Processor;
import org.apache.iotdb.db.engine.bufferwrite.BufferWriteProcessor;
import org.apache.iotdb.db.engine.memcontrol.BasicMemController;
diff --git a/iotdb/src/main/java/org/apache/iotdb/db/qp/QueryProcessor.java b/iotdb/src/main/java/org/apache/iotdb/db/qp/QueryProcessor.java
index 70dc42a..356fe74 100644
--- a/iotdb/src/main/java/org/apache/iotdb/db/qp/QueryProcessor.java
+++ b/iotdb/src/main/java/org/apache/iotdb/db/qp/QueryProcessor.java
@@ -21,8 +21,8 @@ package org.apache.iotdb.db.qp;
import java.time.ZoneId;
import org.apache.iotdb.db.conf.IoTDBConfig;
import org.apache.iotdb.db.conf.IoTDBDescriptor;
-import org.apache.iotdb.db.cost.stastic.Measurement;
-import org.apache.iotdb.db.cost.stastic.Operation;
+import org.apache.iotdb.db.cost.statistic.Measurement;
+import org.apache.iotdb.db.cost.statistic.Operation;
import org.apache.iotdb.db.exception.ArgsErrorException;
import org.apache.iotdb.db.exception.ProcessorException;
import org.apache.iotdb.db.exception.qp.IllegalASTFormatException;
diff --git a/iotdb/src/main/java/org/apache/iotdb/db/qp/executor/OverflowQPExecutor.java b/iotdb/src/main/java/org/apache/iotdb/db/qp/executor/OverflowQPExecutor.java
index 90b77e6..475fa3d 100644
--- a/iotdb/src/main/java/org/apache/iotdb/db/qp/executor/OverflowQPExecutor.java
+++ b/iotdb/src/main/java/org/apache/iotdb/db/qp/executor/OverflowQPExecutor.java
@@ -31,8 +31,8 @@ import org.apache.iotdb.db.auth.entity.PathPrivilege;
import org.apache.iotdb.db.auth.entity.PrivilegeType;
import org.apache.iotdb.db.auth.entity.Role;
import org.apache.iotdb.db.auth.entity.User;
-import org.apache.iotdb.db.cost.stastic.Measurement;
-import org.apache.iotdb.db.cost.stastic.Operation;
+import org.apache.iotdb.db.cost.statistic.Measurement;
+import org.apache.iotdb.db.cost.statistic.Operation;
import org.apache.iotdb.db.engine.filenode.FileNodeManager;
import org.apache.iotdb.db.exception.ArgsErrorException;
import org.apache.iotdb.db.exception.FileNodeManagerException;
diff --git a/iotdb/src/main/java/org/apache/iotdb/db/service/IoTDB.java b/iotdb/src/main/java/org/apache/iotdb/db/service/IoTDB.java
index a7cf296..0d85814 100644
--- a/iotdb/src/main/java/org/apache/iotdb/db/service/IoTDB.java
+++ b/iotdb/src/main/java/org/apache/iotdb/db/service/IoTDB.java
@@ -24,6 +24,7 @@ import org.apache.iotdb.db.concurrent.IoTDBDefaultThreadExceptionHandler;
import org.apache.iotdb.db.conf.IoTDBConfig;
import org.apache.iotdb.db.conf.IoTDBConstant;
import org.apache.iotdb.db.conf.IoTDBDescriptor;
+import org.apache.iotdb.db.cost.statistic.Measurement;
import org.apache.iotdb.db.engine.filenode.FileNodeManager;
import org.apache.iotdb.db.engine.memcontrol.BasicMemController;
import org.apache.iotdb.db.exception.FileNodeManagerException;
@@ -104,6 +105,7 @@ public class IoTDB implements IoTDBMBean {
registerManager.register(StatMonitor.getInstance());
registerManager.register(BasicMemController.getInstance());
registerManager.register(SyncServiceManager.getInstance());
+ registerManager.register(Measurement.INSTANCE);
JMXService.registerMBean(getInstance(), mbeanName);
diff --git a/iotdb/src/main/java/org/apache/iotdb/db/service/ServiceType.java b/iotdb/src/main/java/org/apache/iotdb/db/service/ServiceType.java
index 4b396f2..c4cf00d 100644
--- a/iotdb/src/main/java/org/apache/iotdb/db/service/ServiceType.java
+++ b/iotdb/src/main/java/org/apache/iotdb/db/service/ServiceType.java
@@ -30,7 +30,8 @@ public enum ServiceType {
JVM_MEM_CONTROL_SERVICE("Memory Controller", ""),
AUTHORIZATION_SERVICE("Authorization ServerService", ""),
FILE_READER_MANAGER_SERVICE("File reader manager ServerService", ""),
- SYNC_SERVICE("SYNC ServerService", "");
+ SYNC_SERVICE("SYNC ServerService", ""),
+ PERFORMANCE_STATISTIC_SERVICE("PERFORMANCE_STATISTIC_SERVICE","PERFORMANCE_STATISTIC_SERVICE");
private String name;
private String jmxName;
diff --git a/iotdb/src/main/java/org/apache/iotdb/db/service/TSServiceImpl.java b/iotdb/src/main/java/org/apache/iotdb/db/service/TSServiceImpl.java
index 89f9265..5c12d59 100644
--- a/iotdb/src/main/java/org/apache/iotdb/db/service/TSServiceImpl.java
+++ b/iotdb/src/main/java/org/apache/iotdb/db/service/TSServiceImpl.java
@@ -35,8 +35,8 @@ import org.apache.iotdb.db.auth.authorizer.LocalFileAuthorizer;
import org.apache.iotdb.db.conf.IoTDBConfig;
import org.apache.iotdb.db.conf.IoTDBConstant;
import org.apache.iotdb.db.conf.IoTDBDescriptor;
-import org.apache.iotdb.db.cost.stastic.Measurement;
-import org.apache.iotdb.db.cost.stastic.Operation;
+import org.apache.iotdb.db.cost.statistic.Measurement;
+import org.apache.iotdb.db.cost.statistic.Operation;
import org.apache.iotdb.db.engine.filenode.FileNodeManager;
import org.apache.iotdb.db.exception.ArgsErrorException;
import org.apache.iotdb.db.exception.FileNodeManagerException;