You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@iotdb.apache.org by xi...@apache.org on 2022/08/11 06:37:25 UTC

[iotdb] branch master updated: [IOTDB-3980][Metric] Use asynchronous way to collect some predefined metrics. (#6911)

This is an automated email from the ASF dual-hosted git repository.

xingtanzjr pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/iotdb.git


The following commit(s) were added to refs/heads/master by this push:
     new 1b5d88b5e4 [IOTDB-3980][Metric] Use asynchronous way to collect some predefined metrics. (#6911)
1b5d88b5e4 is described below

commit 1b5d88b5e451bd93c1328753cc0692e6aa4e1982
Author: ZhangHongYin <46...@users.noreply.github.com>
AuthorDate: Thu Aug 11 14:37:20 2022 +0800

    [IOTDB-3980][Metric] Use asynchronous way to collect some predefined metrics. (#6911)
---
 .../main/assembly/resources/conf/iotdb-metric.yml  |   3 +
 .../org/apache/iotdb/metrics/MetricService.java    |  11 +-
 .../apache/iotdb/metrics/config/MetricConfig.java  |  12 ++
 .../metrics/config/MetricConfigDescriptor.java     |   5 +-
 .../iotdb/metrics/predefined/IMetricSet.java       |   6 +
 .../iotdb/db/service/metrics/MetricsService.java   |   2 +
 .../db/service/metrics/predefined/FileMetrics.java | 211 +++++++++++++--------
 .../service/metrics/predefined/SystemMetrics.java  |  57 ++++--
 8 files changed, 216 insertions(+), 91 deletions(-)

diff --git a/metrics/interface/src/main/assembly/resources/conf/iotdb-metric.yml b/metrics/interface/src/main/assembly/resources/conf/iotdb-metric.yml
index cf64f6ad88..92f33c27f1 100644
--- a/metrics/interface/src/main/assembly/resources/conf/iotdb-metric.yml
+++ b/metrics/interface/src/main/assembly/resources/conf/iotdb-metric.yml
@@ -39,6 +39,9 @@ predefinedMetrics:
   - JVM
   - FILE
 
+# The period of the collection of some metrics in asynchronous way, such as tsfile size.
+asyncCollectPeriodInSecond: 5
+
 # The http server's port for prometheus exporter to get metric data.
 prometheusExporterPort: 9091
 
diff --git a/metrics/interface/src/main/java/org/apache/iotdb/metrics/MetricService.java b/metrics/interface/src/main/java/org/apache/iotdb/metrics/MetricService.java
index 5ea4e57641..f462219f5b 100644
--- a/metrics/interface/src/main/java/org/apache/iotdb/metrics/MetricService.java
+++ b/metrics/interface/src/main/java/org/apache/iotdb/metrics/MetricService.java
@@ -23,6 +23,7 @@ import org.apache.iotdb.metrics.config.MetricConfig;
 import org.apache.iotdb.metrics.config.MetricConfigDescriptor;
 import org.apache.iotdb.metrics.config.ReloadLevel;
 import org.apache.iotdb.metrics.impl.DoNothingMetricManager;
+import org.apache.iotdb.metrics.predefined.IMetricSet;
 import org.apache.iotdb.metrics.reporter.CompositeReporter;
 import org.apache.iotdb.metrics.reporter.Reporter;
 import org.apache.iotdb.metrics.utils.PredefinedMetric;
@@ -31,6 +32,8 @@ import org.apache.iotdb.metrics.utils.ReporterType;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.util.ArrayList;
+import java.util.List;
 import java.util.ServiceLoader;
 import java.util.concurrent.atomic.AtomicBoolean;
 
@@ -44,11 +47,13 @@ public abstract class MetricService {
 
   protected MetricManager metricManager = new DoNothingMetricManager();
 
+  protected List<IMetricSet> metricSets = new ArrayList<>();
+
   protected CompositeReporter compositeReporter = new CompositeReporter();
 
   protected boolean isEnableMetric = metricConfig.getEnableMetric();
 
-  private AtomicBoolean firstInit = new AtomicBoolean(true);
+  private final AtomicBoolean firstInit = new AtomicBoolean(true);
 
   public MetricService() {}
 
@@ -79,6 +84,10 @@ public abstract class MetricService {
     compositeReporter.stopAll();
     metricManager = new DoNothingMetricManager();
     compositeReporter = new CompositeReporter();
+    for (IMetricSet metricSet : metricSets) {
+      metricSet.stopAsyncCollectedMetrics();
+    }
+    metricSets = new ArrayList<>();
   }
 
   protected void loadManager() {
diff --git a/metrics/interface/src/main/java/org/apache/iotdb/metrics/config/MetricConfig.java b/metrics/interface/src/main/java/org/apache/iotdb/metrics/config/MetricConfig.java
index f3d62ad96c..66f813c526 100644
--- a/metrics/interface/src/main/java/org/apache/iotdb/metrics/config/MetricConfig.java
+++ b/metrics/interface/src/main/java/org/apache/iotdb/metrics/config/MetricConfig.java
@@ -47,6 +47,8 @@ public class MetricConfig {
   private List<PredefinedMetric> predefinedMetrics =
       Arrays.asList(PredefinedMetric.JVM, PredefinedMetric.FILE);
 
+  private Integer asyncCollectPeriodInSecond = 5;
+
   /** the http server's port for prometheus exporter to get metric data. */
   private String prometheusExporterPort = "9091";
 
@@ -158,6 +160,7 @@ public class MetricConfig {
     metricReporterList = newMetricConfig.getMetricReporterList();
     metricLevel = newMetricConfig.getMetricLevel();
     predefinedMetrics = newMetricConfig.getPredefinedMetrics();
+    asyncCollectPeriodInSecond = newMetricConfig.getAsyncCollectPeriodInSecond();
     prometheusExporterPort = newMetricConfig.getPrometheusExporterPort();
     ioTDBReporterConfig = newMetricConfig.ioTDBReporterConfig;
   }
@@ -215,6 +218,14 @@ public class MetricConfig {
     this.predefinedMetrics = predefinedMetrics;
   }
 
+  public Integer getAsyncCollectPeriodInSecond() {
+    return asyncCollectPeriodInSecond;
+  }
+
+  public void setAsyncCollectPeriodInSecond(Integer asyncCollectPeriodInSecond) {
+    this.asyncCollectPeriodInSecond = asyncCollectPeriodInSecond;
+  }
+
   public String getPrometheusExporterPort() {
     return prometheusExporterPort;
   }
@@ -250,6 +261,7 @@ public class MetricConfig {
         && metricReporterList.equals(anotherMetricConfig.getMetricReporterList())
         && metricLevel.equals(anotherMetricConfig.getMetricLevel())
         && predefinedMetrics.equals(anotherMetricConfig.getPredefinedMetrics())
+        && asyncCollectPeriodInSecond.equals(anotherMetricConfig.getAsyncCollectPeriodInSecond())
         && prometheusExporterPort.equals(anotherMetricConfig.getPrometheusExporterPort())
         && ioTDBReporterConfig.equals(anotherMetricConfig.getIoTDBReporterConfig());
   }
diff --git a/metrics/interface/src/main/java/org/apache/iotdb/metrics/config/MetricConfigDescriptor.java b/metrics/interface/src/main/java/org/apache/iotdb/metrics/config/MetricConfigDescriptor.java
index a2256e03e6..520f8c3c5f 100644
--- a/metrics/interface/src/main/java/org/apache/iotdb/metrics/config/MetricConfigDescriptor.java
+++ b/metrics/interface/src/main/java/org/apache/iotdb/metrics/config/MetricConfigDescriptor.java
@@ -122,9 +122,10 @@ public class MetricConfigDescriptor {
         // restart reporters or restart service
         if (!metricConfig.getMonitorType().equals(newMetricConfig.getMonitorType())
             || !metricConfig.getMetricLevel().equals(newMetricConfig.getMetricLevel())
+            || !metricConfig.getPredefinedMetrics().equals(newMetricConfig.getPredefinedMetrics())
             || !metricConfig
-                .getPredefinedMetrics()
-                .equals(newMetricConfig.getPredefinedMetrics())) {
+                .getAsyncCollectPeriodInSecond()
+                .equals(newMetricConfig.getAsyncCollectPeriodInSecond())) {
           reloadLevel = ReloadLevel.RESTART_METRIC;
         } else {
           reloadLevel = ReloadLevel.RESTART_REPORTER;
diff --git a/metrics/interface/src/main/java/org/apache/iotdb/metrics/predefined/IMetricSet.java b/metrics/interface/src/main/java/org/apache/iotdb/metrics/predefined/IMetricSet.java
index 349934b7cd..b333cef0ab 100644
--- a/metrics/interface/src/main/java/org/apache/iotdb/metrics/predefined/IMetricSet.java
+++ b/metrics/interface/src/main/java/org/apache/iotdb/metrics/predefined/IMetricSet.java
@@ -28,4 +28,10 @@ public interface IMetricSet {
 
   /** get type of metric set */
   PredefinedMetric getType();
+
+  /** start async collectd metric */
+  default void startAsyncCollectedMetrics() {}
+
+  /** stop async collectd metric */
+  default void stopAsyncCollectedMetrics() {}
 }
diff --git a/server/src/main/java/org/apache/iotdb/db/service/metrics/MetricsService.java b/server/src/main/java/org/apache/iotdb/db/service/metrics/MetricsService.java
index 74228c1ae6..0f0886f62c 100644
--- a/server/src/main/java/org/apache/iotdb/db/service/metrics/MetricsService.java
+++ b/server/src/main/java/org/apache/iotdb/db/service/metrics/MetricsService.java
@@ -100,6 +100,8 @@ public class MetricsService extends MetricService implements MetricsServiceMBean
         return;
     }
     metricSet.bindTo(metricManager);
+    metricSet.startAsyncCollectedMetrics();
+    metricSets.add(metricSet);
   }
 
   @Override
diff --git a/server/src/main/java/org/apache/iotdb/db/service/metrics/predefined/FileMetrics.java b/server/src/main/java/org/apache/iotdb/db/service/metrics/predefined/FileMetrics.java
index b381aaaeb6..3889dd7ac2 100644
--- a/server/src/main/java/org/apache/iotdb/db/service/metrics/predefined/FileMetrics.java
+++ b/server/src/main/java/org/apache/iotdb/db/service/metrics/predefined/FileMetrics.java
@@ -19,125 +19,78 @@
 
 package org.apache.iotdb.db.service.metrics.predefined;
 
+import org.apache.iotdb.commons.concurrent.threadpool.ScheduledExecutorUtil;
 import org.apache.iotdb.commons.conf.IoTDBConstant;
 import org.apache.iotdb.commons.utils.FileUtils;
 import org.apache.iotdb.db.conf.IoTDBDescriptor;
 import org.apache.iotdb.db.service.metrics.enums.Metric;
 import org.apache.iotdb.db.service.metrics.enums.Tag;
+import org.apache.iotdb.db.wal.WALManager;
 import org.apache.iotdb.metrics.MetricManager;
+import org.apache.iotdb.metrics.config.MetricConfigDescriptor;
 import org.apache.iotdb.metrics.predefined.IMetricSet;
 import org.apache.iotdb.metrics.utils.MetricLevel;
 import org.apache.iotdb.metrics.utils.PredefinedMetric;
 
 import java.io.File;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
 import java.util.stream.Stream;
 
 public class FileMetrics implements IMetricSet {
+  private final String[] walDirs = IoTDBDescriptor.getInstance().getConfig().getWalDirs();
+  private final String[] dataDirs = IoTDBDescriptor.getInstance().getConfig().getDataDirs();
+  private final ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();
+  private long walFileTotalSize = 0L;
+  private long walFileTotalCount = 0L;
+  private long sequenceFileTotalSize = 0L;
+  private long sequenceFileTotalCount = 0L;
+  private long unsequenceFileTotalSize = 0L;
+  private long unsequenceFileTotalCount = 0L;
+
   @Override
   public void bindTo(MetricManager metricManager) {
-    String[] walDirs = IoTDBDescriptor.getInstance().getConfig().getWalDirs();
     metricManager.getOrCreateAutoGauge(
         Metric.FILE_SIZE.toString(),
         MetricLevel.IMPORTANT,
-        walDirs,
-        value -> Stream.of(value).mapToLong(FileUtils::getDirSize).sum(),
+        this,
+        FileMetrics::getWalFileTotalSize,
         Tag.NAME.toString(),
         "wal");
-
-    String[] dataDirs = IoTDBDescriptor.getInstance().getConfig().getDataDirs();
     metricManager.getOrCreateAutoGauge(
         Metric.FILE_SIZE.toString(),
         MetricLevel.IMPORTANT,
-        dataDirs,
-        value ->
-            Stream.of(value)
-                .mapToLong(
-                    dir -> {
-                      dir += File.separator + IoTDBConstant.SEQUENCE_FLODER_NAME;
-                      return FileUtils.getDirSize(dir);
-                    })
-                .sum(),
+        this,
+        FileMetrics::getSequenceFileTotalSize,
         Tag.NAME.toString(),
         "seq");
     metricManager.getOrCreateAutoGauge(
         Metric.FILE_SIZE.toString(),
         MetricLevel.IMPORTANT,
-        dataDirs,
-        value ->
-            Stream.of(value)
-                .mapToLong(
-                    dir -> {
-                      dir += File.separator + IoTDBConstant.UNSEQUENCE_FLODER_NAME;
-                      return FileUtils.getDirSize(dir);
-                    })
-                .sum(),
+        this,
+        FileMetrics::getUnsequenceFileTotalSize,
         Tag.NAME.toString(),
         "unseq");
     metricManager.getOrCreateAutoGauge(
         Metric.FILE_COUNT.toString(),
         MetricLevel.IMPORTANT,
-        walDirs,
-        value ->
-            Stream.of(value)
-                .mapToLong(
-                    dir -> {
-                      File walFolder = new File(dir);
-                      File[] walNodeFolders = walFolder.listFiles(File::isDirectory);
-                      long result = 0L;
-                      if (null != walNodeFolders) {
-                        for (File walNodeFolder : walNodeFolders) {
-                          if (walNodeFolder.exists() && walNodeFolder.isDirectory()) {
-                            result +=
-                                org.apache.commons.io.FileUtils.listFiles(walNodeFolder, null, true)
-                                    .size();
-                          }
-                        }
-                      }
-                      return result;
-                    })
-                .sum(),
+        this,
+        FileMetrics::getWalFileTotalCount,
         Tag.NAME.toString(),
         "wal");
     metricManager.getOrCreateAutoGauge(
         Metric.FILE_COUNT.toString(),
         MetricLevel.IMPORTANT,
-        dataDirs,
-        value ->
-            Stream.of(value)
-                .mapToLong(
-                    dir -> {
-                      dir += File.separator + IoTDBConstant.SEQUENCE_FLODER_NAME;
-                      File folder = new File(dir);
-                      if (folder.exists()) {
-                        return org.apache.commons.io.FileUtils.listFiles(
-                                new File(dir), new String[] {"tsfile"}, true)
-                            .size();
-                      } else {
-                        return 0L;
-                      }
-                    })
-                .sum(),
+        this,
+        FileMetrics::getSequenceFileTotalCount,
         Tag.NAME.toString(),
         "seq");
     metricManager.getOrCreateAutoGauge(
         Metric.FILE_COUNT.toString(),
         MetricLevel.IMPORTANT,
-        dataDirs,
-        value ->
-            Stream.of(value)
-                .mapToLong(
-                    dir -> {
-                      dir += File.separator + IoTDBConstant.UNSEQUENCE_FLODER_NAME;
-                      File folder = new File(dir);
-                      if (folder.exists()) {
-                        return org.apache.commons.io.FileUtils.listFiles(
-                                new File(dir), new String[] {"tsfile"}, true)
-                            .size();
-                      } else {
-                        return 0L;
-                      }
-                    })
-                .sum(),
+        this,
+        FileMetrics::getUnsequenceFileTotalCount,
         Tag.NAME.toString(),
         "unseq");
   }
@@ -146,4 +99,112 @@ public class FileMetrics implements IMetricSet {
   public PredefinedMetric getType() {
     return PredefinedMetric.FILE;
   }
+
+  @Override
+  public void startAsyncCollectedMetrics() {
+    ScheduledExecutorUtil.safelyScheduleAtFixedRate(
+        service,
+        this::collect,
+        1,
+        MetricConfigDescriptor.getInstance().getMetricConfig().getAsyncCollectPeriodInSecond(),
+        TimeUnit.SECONDS);
+  }
+
+  @Override
+  public void stopAsyncCollectedMetrics() {
+    service.shutdown();
+  }
+
+  private void collect() {
+    walFileTotalSize = WALManager.getInstance().getTotalDiskUsage();
+    sequenceFileTotalSize =
+        Stream.of(dataDirs)
+            .mapToLong(
+                dir -> {
+                  dir += File.separator + IoTDBConstant.SEQUENCE_FLODER_NAME;
+                  return FileUtils.getDirSize(dir);
+                })
+            .sum();
+    unsequenceFileTotalSize =
+        Stream.of(dataDirs)
+            .mapToLong(
+                dir -> {
+                  dir += File.separator + IoTDBConstant.UNSEQUENCE_FLODER_NAME;
+                  return FileUtils.getDirSize(dir);
+                })
+            .sum();
+    walFileTotalCount =
+        Stream.of(walDirs)
+            .mapToLong(
+                dir -> {
+                  File walFolder = new File(dir);
+                  File[] walNodeFolders = walFolder.listFiles(File::isDirectory);
+                  long result = 0L;
+                  if (null != walNodeFolders) {
+                    for (File walNodeFolder : walNodeFolders) {
+                      if (walNodeFolder.exists() && walNodeFolder.isDirectory()) {
+                        result +=
+                            org.apache.commons.io.FileUtils.listFiles(walNodeFolder, null, true)
+                                .size();
+                      }
+                    }
+                  }
+                  return result;
+                })
+            .sum();
+    sequenceFileTotalCount =
+        Stream.of(dataDirs)
+            .mapToLong(
+                dir -> {
+                  dir += File.separator + IoTDBConstant.SEQUENCE_FLODER_NAME;
+                  File folder = new File(dir);
+                  if (folder.exists()) {
+                    return org.apache.commons.io.FileUtils.listFiles(
+                            new File(dir), new String[] {"tsfile"}, true)
+                        .size();
+                  } else {
+                    return 0L;
+                  }
+                })
+            .sum();
+    unsequenceFileTotalCount =
+        Stream.of(dataDirs)
+            .mapToLong(
+                dir -> {
+                  dir += File.separator + IoTDBConstant.UNSEQUENCE_FLODER_NAME;
+                  File folder = new File(dir);
+                  if (folder.exists()) {
+                    return org.apache.commons.io.FileUtils.listFiles(
+                            new File(dir), new String[] {"tsfile"}, true)
+                        .size();
+                  } else {
+                    return 0L;
+                  }
+                })
+            .sum();
+  }
+
+  public long getWalFileTotalSize() {
+    return walFileTotalSize;
+  }
+
+  public long getWalFileTotalCount() {
+    return walFileTotalCount;
+  }
+
+  public long getSequenceFileTotalSize() {
+    return sequenceFileTotalSize;
+  }
+
+  public long getSequenceFileTotalCount() {
+    return sequenceFileTotalCount;
+  }
+
+  public long getUnsequenceFileTotalSize() {
+    return unsequenceFileTotalSize;
+  }
+
+  public long getUnsequenceFileTotalCount() {
+    return unsequenceFileTotalCount;
+  }
 }
diff --git a/server/src/main/java/org/apache/iotdb/db/service/metrics/predefined/SystemMetrics.java b/server/src/main/java/org/apache/iotdb/db/service/metrics/predefined/SystemMetrics.java
index 4069a5afc3..4a97ce47cc 100644
--- a/server/src/main/java/org/apache/iotdb/db/service/metrics/predefined/SystemMetrics.java
+++ b/server/src/main/java/org/apache/iotdb/db/service/metrics/predefined/SystemMetrics.java
@@ -18,10 +18,11 @@
  */
 package org.apache.iotdb.db.service.metrics.predefined;
 
-import org.apache.iotdb.db.conf.IoTDBDescriptor;
+import org.apache.iotdb.commons.concurrent.threadpool.ScheduledExecutorUtil;
 import org.apache.iotdb.db.service.metrics.enums.Metric;
 import org.apache.iotdb.db.service.metrics.enums.Tag;
 import org.apache.iotdb.metrics.MetricManager;
+import org.apache.iotdb.metrics.config.MetricConfigDescriptor;
 import org.apache.iotdb.metrics.predefined.IMetricSet;
 import org.apache.iotdb.metrics.utils.MetricLevel;
 import org.apache.iotdb.metrics.utils.PredefinedMetric;
@@ -30,9 +31,15 @@ import com.sun.management.OperatingSystemMXBean;
 
 import java.io.File;
 import java.lang.management.ManagementFactory;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
 
 public class SystemMetrics implements IMetricSet {
   private com.sun.management.OperatingSystemMXBean osMXBean;
+  private final ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();
+  private long systemDiskTotalSpace = 0L;
+  private long systemDiskFreeSpace = 0L;
 
   public SystemMetrics() {
     osMXBean = (OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();
@@ -108,34 +115,58 @@ public class SystemMetrics implements IMetricSet {
         Metric.SYS_DISK_TOTAL_SPACE.toString(),
         MetricLevel.CORE,
         this,
-        a -> getSysDiskTotalSpace(),
+        SystemMetrics::getSystemDiskTotalSpace,
         Tag.NAME.toString(),
         "system");
     metricManager.getOrCreateAutoGauge(
         Metric.SYS_DISK_FREE_SPACE.toString(),
         MetricLevel.CORE,
         this,
-        a -> getSysDickFreeSpace(),
+        SystemMetrics::getSystemDiskFreeSpace,
         Tag.NAME.toString(),
         "system");
-    String[] dataDirs = IoTDBDescriptor.getInstance().getConfig().getDataDirs();
   }
 
-  private long getSysDiskTotalSpace() {
-    File[] files = File.listRoots();
-    long sysTotalSpace = 0L;
-    for (File file : files) {
-      sysTotalSpace += file.getTotalSpace();
-    }
-    return sysTotalSpace;
+  @Override
+  public void startAsyncCollectedMetrics() {
+    ScheduledExecutorUtil.safelyScheduleAtFixedRate(
+        service,
+        this::collect,
+        1,
+        MetricConfigDescriptor.getInstance().getMetricConfig().getAsyncCollectPeriodInSecond(),
+        TimeUnit.SECONDS);
   }
 
-  private long getSysDickFreeSpace() {
+  @Override
+  public void stopAsyncCollectedMetrics() {
+    service.shutdown();
+  }
+
+  private void collect() {
     File[] files = File.listRoots();
+    long sysTotalSpace = 0L;
     long sysFreeSpace = 0L;
     for (File file : files) {
+      sysTotalSpace += file.getTotalSpace();
       sysFreeSpace += file.getFreeSpace();
     }
-    return sysFreeSpace;
+    systemDiskTotalSpace = sysTotalSpace;
+    systemDiskFreeSpace = sysFreeSpace;
+  }
+
+  public long getSystemDiskTotalSpace() {
+    return systemDiskTotalSpace;
+  }
+
+  public void setSystemDiskTotalSpace(long systemDiskTotalSpace) {
+    this.systemDiskTotalSpace = systemDiskTotalSpace;
+  }
+
+  public long getSystemDiskFreeSpace() {
+    return systemDiskFreeSpace;
+  }
+
+  public void setSystemDiskFreeSpace(long systemDiskFreeSpace) {
+    this.systemDiskFreeSpace = systemDiskFreeSpace;
   }
 }