From 10dbe9d3d2614e52e1f95ddfe151978117ef4640 Mon Sep 17 00:00:00 2001 From: Peng Junzhi <201250214@smail.nju.edu.cn> Date: Mon, 24 Mar 2025 23:11:30 +0800 Subject: [PATCH 01/15] multi-disk aware --- .../org/apache/iotdb/db/conf/IoTDBConfig.java | 19 +++++ .../apache/iotdb/db/conf/IoTDBDescriptor.java | 12 +++ .../storageengine/dataregion/DataRegion.java | 76 +++++++++++++++---- .../conf/iotdb-system.properties.template | 18 +++++ 4 files changed, 112 insertions(+), 13 deletions(-) diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/conf/IoTDBConfig.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/conf/IoTDBConfig.java index f4c62d33585a8..1e07c259d120e 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/conf/IoTDBConfig.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/conf/IoTDBConfig.java @@ -1073,6 +1073,7 @@ public class IoTDBConfig { + CONSENSUS_FOLDER_NAME + File.separator + DELETION_FOLDER_NAME; + private boolean enableMultiDisksAwareLoadForIoTV2 = false; /** Load related */ private double maxAllocateMemoryRatioForLoad = 0.8; @@ -1132,6 +1133,8 @@ public class IoTDBConfig { /** initialized as empty, updated based on the latest `systemDir` during querying */ private String[] pipeReceiverFileDirs = new String[0]; + private boolean enableMultiDisksAwareLoadForPipe = false; + /** Resource control */ private boolean quotaEnable = false; @@ -3912,6 +3915,14 @@ public void setPipeReceiverFileDirs(String[] pipeReceiverFileDirs) { this.pipeReceiverFileDirs = pipeReceiverFileDirs; } + public boolean isEnableMultiDisksAwareLoadForPipe() { + return this.enableMultiDisksAwareLoadForPipe; + } + + public void setEnableMultiDisksAwareLoadForPipe(boolean enableMultiDisksAwareLoadForPipe) { + this.enableMultiDisksAwareLoadForPipe = enableMultiDisksAwareLoadForPipe; + } + public String[] getPipeReceiverFileDirs() { return (Objects.isNull(this.pipeReceiverFileDirs) || this.pipeReceiverFileDirs.length == 0) ? new String[] {systemDir + File.separator + "pipe" + File.separator + "receiver"} @@ -3937,6 +3948,14 @@ public String[] getIotConsensusV2ReceiverFileDirs() { : this.iotConsensusV2ReceiverFileDirs; } + public boolean isEnableMultiDisksAwareLoadForIoTV2() { + return this.enableMultiDisksAwareLoadForIoTV2; + } + + public void setEnableMultiDisksAwareLoadForIoTV2(boolean enableMultiDisksAwareLoadForIoTV2) { + this.enableMultiDisksAwareLoadForIoTV2 = enableMultiDisksAwareLoadForIoTV2; + } + public boolean isQuotaEnable() { return quotaEnable; } diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/conf/IoTDBDescriptor.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/conf/IoTDBDescriptor.java index 98b80de001dd0..1a3eacc8c9406 100755 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/conf/IoTDBDescriptor.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/conf/IoTDBDescriptor.java @@ -2404,6 +2404,12 @@ private void loadPipeProps(TrimProperties properties) { .filter(dir -> !dir.isEmpty()) .toArray(String[]::new)); + conf.setEnableMultiDisksAwareLoadForPipe( + Boolean.parseBoolean( + properties.getProperty( + "enable_multi_disks_aware_load_for_pipe", + Boolean.toString(conf.isEnableMultiDisksAwareLoadForPipe())))); + conf.setIotConsensusV2ReceiverFileDirs( Arrays.stream( properties @@ -2415,6 +2421,12 @@ private void loadPipeProps(TrimProperties properties) { .filter(dir -> !dir.isEmpty()) .toArray(String[]::new)); + conf.setEnableMultiDisksAwareLoadForIoTV2( + Boolean.parseBoolean( + properties.getProperty( + "enable_multi_disks_aware_load_for_iotv2", + Boolean.toString(conf.isEnableMultiDisksAwareLoadForIoTV2())))); + conf.setIotConsensusV2DeletionFileDir( properties.getProperty( "iot_consensus_v2_deletion_file_dir", conf.getIotConsensusV2DeletionFileDir())); diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/DataRegion.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/DataRegion.java index a2e6873360bf8..0b083736e9b4b 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/DataRegion.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/DataRegion.java @@ -23,6 +23,7 @@ import org.apache.iotdb.commons.cluster.NodeStatus; import org.apache.iotdb.commons.concurrent.IoTDBThreadPoolFactory; import org.apache.iotdb.commons.conf.CommonDescriptor; +import org.apache.iotdb.commons.conf.IoTDBConstant; import org.apache.iotdb.commons.consensus.DataRegionId; import org.apache.iotdb.commons.exception.MetadataException; import org.apache.iotdb.commons.file.SystemFileFactory; @@ -154,8 +155,13 @@ import java.io.File; import java.io.IOException; +import java.nio.file.FileSystem; +import java.nio.file.FileSystems; import java.nio.file.Files; +import java.nio.file.Path; import java.nio.file.Paths; +import java.nio.file.attribute.FileAttributeView; +import java.nio.file.spi.FileSystemProvider; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -325,6 +331,8 @@ public class DataRegion implements IDataRegionForQuery { private final DataRegionMetrics metrics; + private final Map rootDisks2DataDirsMapForLoad; + /** * Construct a database processor. * @@ -388,6 +396,18 @@ public DataRegion( recover(); } + // init data dirs' root disks + this.rootDisks2DataDirsMapForLoad = new HashMap<>(config.getDataDirs().length); + for (String dataDir : config.getDataDirs()) { + File dataDirFile = new File(dataDir); + String dataDirRoot = + dataDirFile + .getAbsolutePath() + .substring(0, dataDirFile.getAbsolutePath().indexOf(dataDirFile.getName())); + this.rootDisks2DataDirsMapForLoad.put( + dataDirRoot, fsFactory.getFile(dataDir, IoTDBConstant.UNSEQUENCE_FOLDER_NAME).getPath()); + } + this.metrics = new DataRegionMetrics(this); MetricService.getInstance().addMetricSet(metrics); } @@ -400,6 +420,7 @@ public DataRegion(String databaseName, String id) { this.partitionMaxFileVersions = new HashMap<>(); partitionMaxFileVersions.put(0L, 0L); upgradeModFileThreadPool = null; + this.rootDisks2DataDirsMapForLoad = new HashMap<>(); this.metrics = new DataRegionMetrics(this); } @@ -3051,17 +3072,46 @@ private boolean loadTsFileToUnSequence( final boolean deleteOriginFile, boolean isGeneratedByPipe) throws LoadFileException, DiskSpaceInsufficientException { - final File targetFile = - fsFactory.getFile( - TierManager.getInstance().getNextFolderForTsFile(0, false), - databaseName - + File.separatorChar - + dataRegionId - + File.separatorChar - + filePartitionId - + File.separator - + tsFileResource.getTsFile().getName()); - tsFileResource.setFile(targetFile); + File targetFile = null; + boolean needDownGradeToSequence = true; + final String fileDirRoot = + tsFileToLoad + .getAbsolutePath() + .substring(0, tsFileToLoad.getAbsolutePath().indexOf(tsFileToLoad.getName())); + if ((config.isEnableMultiDisksAwareLoadForIoTV2() + && tsFileResource.isGeneratedByPipeConsensus()) + || (config.isEnableMultiDisksAwareLoadForPipe() && tsFileResource.isGeneratedByPipe())) { + if (rootDisks2DataDirsMapForLoad.containsKey(fileDirRoot)) { + targetFile = + fsFactory.getFile( + rootDisks2DataDirsMapForLoad.get(fileDirRoot), + databaseName + + File.separatorChar + + dataRegionId + + File.separatorChar + + filePartitionId + + File.separator + + tsFileResource.getTsFile().getName()); + needDownGradeToSequence = false; + } + } + + if (needDownGradeToSequence) { + targetFile = + fsFactory.getFile( + TierManager.getInstance().getNextFolderForTsFile(0, false), + databaseName + + File.separatorChar + + dataRegionId + + File.separatorChar + + filePartitionId + + File.separator + + tsFileResource.getTsFile().getName()); + } + + // var used in lambda must be final + final File finalTargetFile = targetFile; + tsFileResource.setFile(finalTargetFile); if (tsFileManager.contains(tsFileResource, false)) { logger.warn("The file {} has already been loaded in unsequence list", tsFileResource); return false; @@ -3082,13 +3132,13 @@ private boolean loadTsFileToUnSequence( if (deleteOriginFile) { RetryUtils.retryOnException( () -> { - FileUtils.moveFile(tsFileToLoad, targetFile); + FileUtils.moveFile(tsFileToLoad, finalTargetFile); return null; }); } else { RetryUtils.retryOnException( () -> { - Files.copy(tsFileToLoad.toPath(), targetFile.toPath()); + Files.copy(tsFileToLoad.toPath(), finalTargetFile.toPath()); return null; }); } diff --git a/iotdb-core/node-commons/src/assembly/resources/conf/iotdb-system.properties.template b/iotdb-core/node-commons/src/assembly/resources/conf/iotdb-system.properties.template index e3ab5cdf39e77..cb4dd96b0bdac 100644 --- a/iotdb-core/node-commons/src/assembly/resources/conf/iotdb-system.properties.template +++ b/iotdb-core/node-commons/src/assembly/resources/conf/iotdb-system.properties.template @@ -319,6 +319,15 @@ sort_tmp_dir=data/datanode/tmp # If its prefix is "/", then the path is absolute. Otherwise, it is relative. dn_pipe_receiver_file_dirs=data/datanode/system/pipe/receiver +# enable_multi_disks_aware_load_for_pipe +# Whether to enable multi-disks aware load for pipe. +# The load process will try to move tsFile within the same disk if set true. +# Recommend set to true if amount of pipe receiver disks is equal to data disks' to ensure io-balance and storage-balance at the same time. +# Notice: Default is false because storage-balance is ensured with higher priority. +# effectiveMode: restart +# Datatype: Boolean +enable_multi_disks_aware_load_for_pipe=false + # iot_consensus_v2_receiver_file_dirs # If this property is unset, system will save the data in the default relative path directory under the IoTDB folder(i.e., %IOTDB_HOME%/${dn_system_dir}/pipe/consensus/receiver). # If it is absolute, system will save the data in the exact location it points to. @@ -346,6 +355,15 @@ iot_consensus_v2_receiver_file_dirs=data/datanode/system/pipe/consensus/receiver # If its prefix is "/", then the path is absolute. Otherwise, it is relative. iot_consensus_v2_deletion_file_dir=data/datanode/system/pipe/consensus/deletion +# enable_multi_disks_aware_load_for_iotv2 +# Whether to enable multi-disks aware load for iot consensus v2. +# The load process will try to move tsFile within the same disk if set true. +# Recommend set to true if amount of iotv2 receiver disks is equal to data disks' to ensure io-balance and storage-balance at the same time. +# Notice: Default is false because storage-balance is ensured with higher priority. +# effectiveMode: restart +# Datatype: Boolean +enable_multi_disks_aware_load_for_iotv2=false + #################### ### Metric Configuration #################### From 9604630c681c52be5a2fdb633e8915b386a11081 Mon Sep 17 00:00:00 2001 From: Peng Junzhi <201250214@smail.nju.edu.cn> Date: Mon, 24 Mar 2025 23:25:51 +0800 Subject: [PATCH 02/15] get mount point --- .../storageengine/dataregion/DataRegion.java | 36 +++++++++++-------- .../apache/iotdb/commons/utils/PathUtils.java | 20 +++++++++++ 2 files changed, 41 insertions(+), 15 deletions(-) diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/DataRegion.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/DataRegion.java index 0b083736e9b4b..b2a4c70d94a4e 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/DataRegion.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/DataRegion.java @@ -35,6 +35,7 @@ import org.apache.iotdb.commons.service.metric.enums.Metric; import org.apache.iotdb.commons.service.metric.enums.Tag; import org.apache.iotdb.commons.utils.CommonDateTimeUtils; +import org.apache.iotdb.commons.utils.PathUtils; import org.apache.iotdb.commons.utils.RetryUtils; import org.apache.iotdb.commons.utils.TestOnly; import org.apache.iotdb.commons.utils.TimePartitionUtils; @@ -155,13 +156,8 @@ import java.io.File; import java.io.IOException; -import java.nio.file.FileSystem; -import java.nio.file.FileSystems; import java.nio.file.Files; -import java.nio.file.Path; import java.nio.file.Paths; -import java.nio.file.attribute.FileAttributeView; -import java.nio.file.spi.FileSystemProvider; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -400,12 +396,16 @@ public DataRegion( this.rootDisks2DataDirsMapForLoad = new HashMap<>(config.getDataDirs().length); for (String dataDir : config.getDataDirs()) { File dataDirFile = new File(dataDir); - String dataDirRoot = - dataDirFile - .getAbsolutePath() - .substring(0, dataDirFile.getAbsolutePath().indexOf(dataDirFile.getName())); - this.rootDisks2DataDirsMapForLoad.put( - dataDirRoot, fsFactory.getFile(dataDir, IoTDBConstant.UNSEQUENCE_FOLDER_NAME).getPath()); + try { + String mountPoint = PathUtils.getMountPoint(dataDirFile.getCanonicalPath()); + this.rootDisks2DataDirsMapForLoad.put( + mountPoint, fsFactory.getFile(dataDir, IoTDBConstant.UNSEQUENCE_FOLDER_NAME).getPath()); + } catch (Exception e) { + logger.warn( + "Exception occurs when reading data dir's mount point {}, may because your OS is windows.", + dataDir, + e); + } } this.metrics = new DataRegionMetrics(this); @@ -3074,10 +3074,16 @@ private boolean loadTsFileToUnSequence( throws LoadFileException, DiskSpaceInsufficientException { File targetFile = null; boolean needDownGradeToSequence = true; - final String fileDirRoot = - tsFileToLoad - .getAbsolutePath() - .substring(0, tsFileToLoad.getAbsolutePath().indexOf(tsFileToLoad.getName())); + String fileDirRoot = null; + try { + fileDirRoot = PathUtils.getMountPoint(tsFileToLoad.getCanonicalPath()); + } catch (Exception e) { + logger.warn( + "Exception occurs when reading target file's mount point {}, may because your OS is windows.", + tsFileToLoad, + e); + } + if ((config.isEnableMultiDisksAwareLoadForIoTV2() && tsFileResource.isGeneratedByPipeConsensus()) || (config.isEnableMultiDisksAwareLoadForPipe() && tsFileResource.isGeneratedByPipe())) { diff --git a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/utils/PathUtils.java b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/utils/PathUtils.java index 5a2369f72a96e..a6cc235a51b87 100644 --- a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/utils/PathUtils.java +++ b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/utils/PathUtils.java @@ -28,6 +28,7 @@ import org.apache.tsfile.read.common.parser.PathNodesGenerator; import org.apache.tsfile.read.common.parser.PathVisitor; +import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -224,4 +225,23 @@ public static String unQualifyDatabaseName(String databaseName) { public static boolean isTableModelDatabase(final String databaseName) { return !databaseName.startsWith("root."); } + + /** + * Get the mount point of one specific file given its path. NOTE: only can be used in Linux and + * MacOS System. + */ + public static String getMountPoint(String path) throws IOException, InterruptedException { + Process process = Runtime.getRuntime().exec("df " + path); + process.waitFor(); + + try (java.util.Scanner scanner = new java.util.Scanner(process.getInputStream())) { + if (scanner.hasNextLine()) { + scanner.nextLine(); + String line = scanner.nextLine().trim(); + String[] parts = line.split("\\s+"); + return parts[parts.length - 1]; + } + } + return null; + } } From 5a1602d0dffcfefc7d7f3a9566130e35a25a2607 Mon Sep 17 00:00:00 2001 From: Peng Junzhi <201250214@smail.nju.edu.cn> Date: Tue, 25 Mar 2025 00:00:57 +0800 Subject: [PATCH 03/15] enhance log --- .../apache/iotdb/db/storageengine/dataregion/DataRegion.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/DataRegion.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/DataRegion.java index b2a4c70d94a4e..058ebb41a9082 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/DataRegion.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/DataRegion.java @@ -394,12 +394,13 @@ public DataRegion( // init data dirs' root disks this.rootDisks2DataDirsMapForLoad = new HashMap<>(config.getDataDirs().length); - for (String dataDir : config.getDataDirs()) { + for (String dataDir : config.getTierDataDirs()[0]) { File dataDirFile = new File(dataDir); try { String mountPoint = PathUtils.getMountPoint(dataDirFile.getCanonicalPath()); this.rootDisks2DataDirsMapForLoad.put( mountPoint, fsFactory.getFile(dataDir, IoTDBConstant.UNSEQUENCE_FOLDER_NAME).getPath()); + logger.info("Add {}'s mount point {}", dataDir, mountPoint); } catch (Exception e) { logger.warn( "Exception occurs when reading data dir's mount point {}, may because your OS is windows.", From 7794fe5ae836e788149cab999d09f9cac131b5a4 Mon Sep 17 00:00:00 2001 From: Peng Junzhi <201250214@smail.nju.edu.cn> Date: Tue, 25 Mar 2025 09:39:03 +0800 Subject: [PATCH 04/15] fix up --- .../apache/iotdb/db/storageengine/dataregion/DataRegion.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/DataRegion.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/DataRegion.java index 058ebb41a9082..265e82d4084df 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/DataRegion.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/DataRegion.java @@ -393,7 +393,7 @@ public DataRegion( } // init data dirs' root disks - this.rootDisks2DataDirsMapForLoad = new HashMap<>(config.getDataDirs().length); + this.rootDisks2DataDirsMapForLoad = new HashMap<>(config.getTierDataDirs()[0].length); for (String dataDir : config.getTierDataDirs()[0]) { File dataDirFile = new File(dataDir); try { From 81050909a3960ff373cd15708c624e72cb0d617e Mon Sep 17 00:00:00 2001 From: Peng Junzhi <201250214@smail.nju.edu.cn> Date: Tue, 25 Mar 2025 09:50:33 +0800 Subject: [PATCH 05/15] fix up --- .../storageengine/dataregion/DataRegion.java | 41 +++++++++++-------- 1 file changed, 24 insertions(+), 17 deletions(-) diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/DataRegion.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/DataRegion.java index 265e82d4084df..9b37e0820d5bf 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/DataRegion.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/DataRegion.java @@ -394,20 +394,23 @@ public DataRegion( // init data dirs' root disks this.rootDisks2DataDirsMapForLoad = new HashMap<>(config.getTierDataDirs()[0].length); - for (String dataDir : config.getTierDataDirs()[0]) { - File dataDirFile = new File(dataDir); - try { - String mountPoint = PathUtils.getMountPoint(dataDirFile.getCanonicalPath()); - this.rootDisks2DataDirsMapForLoad.put( - mountPoint, fsFactory.getFile(dataDir, IoTDBConstant.UNSEQUENCE_FOLDER_NAME).getPath()); - logger.info("Add {}'s mount point {}", dataDir, mountPoint); - } catch (Exception e) { - logger.warn( - "Exception occurs when reading data dir's mount point {}, may because your OS is windows.", - dataDir, - e); - } - } + Arrays.stream(config.getTierDataDirs()[0]) + .filter(Objects::nonNull) + .map(v -> fsFactory.getFile(v, IoTDBConstant.UNSEQUENCE_FOLDER_NAME).getPath()) + .forEach( + dataDirPath -> { + File dataDirFile = new File(dataDirPath); + try { + String mountPoint = PathUtils.getMountPoint(dataDirFile.getCanonicalPath()); + this.rootDisks2DataDirsMapForLoad.put(mountPoint, dataDirPath); + logger.info("Add {}'s mount point {}", dataDirPath, mountPoint); + } catch (Exception e) { + logger.warn( + "Exception occurs when reading data dir's mount point {}, may because your OS is windows.", + dataDirPath, + e); + } + }); this.metrics = new DataRegionMetrics(this); MetricService.getInstance().addMetricSet(metrics); @@ -3074,7 +3077,7 @@ private boolean loadTsFileToUnSequence( boolean isGeneratedByPipe) throws LoadFileException, DiskSpaceInsufficientException { File targetFile = null; - boolean needDownGradeToSequence = true; + boolean needDownGradeToSequenceStrategy = true; String fileDirRoot = null; try { fileDirRoot = PathUtils.getMountPoint(tsFileToLoad.getCanonicalPath()); @@ -3085,10 +3088,13 @@ private boolean loadTsFileToUnSequence( e); } + // only IoTV2 and Pipe will try to enable multi-disks awareness if ((config.isEnableMultiDisksAwareLoadForIoTV2() && tsFileResource.isGeneratedByPipeConsensus()) || (config.isEnableMultiDisksAwareLoadForPipe() && tsFileResource.isGeneratedByPipe())) { if (rootDisks2DataDirsMapForLoad.containsKey(fileDirRoot)) { + // if there is an overlap between firDirRoot and data directories' disk roots, try to get + // targetFile in the same disk targetFile = fsFactory.getFile( rootDisks2DataDirsMapForLoad.get(fileDirRoot), @@ -3099,11 +3105,12 @@ private boolean loadTsFileToUnSequence( + filePartitionId + File.separator + tsFileResource.getTsFile().getName()); - needDownGradeToSequence = false; + + needDownGradeToSequenceStrategy = false; } } - if (needDownGradeToSequence) { + if (needDownGradeToSequenceStrategy) { targetFile = fsFactory.getFile( TierManager.getInstance().getNextFolderForTsFile(0, false), From 79ee4e594d5fad6f4e8935aabbd1a7fe37280f48 Mon Sep 17 00:00:00 2001 From: Peng Junzhi <201250214@smail.nju.edu.cn> Date: Tue, 25 Mar 2025 10:16:45 +0800 Subject: [PATCH 06/15] fix import --- .../main/java/org/apache/iotdb/commons/utils/PathUtils.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/utils/PathUtils.java b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/utils/PathUtils.java index a6cc235a51b87..4364ead80d58d 100644 --- a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/utils/PathUtils.java +++ b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/utils/PathUtils.java @@ -33,6 +33,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Scanner; public class PathUtils { @@ -234,7 +235,7 @@ public static String getMountPoint(String path) throws IOException, InterruptedE Process process = Runtime.getRuntime().exec("df " + path); process.waitFor(); - try (java.util.Scanner scanner = new java.util.Scanner(process.getInputStream())) { + try (Scanner scanner = new java.util.Scanner(process.getInputStream())) { if (scanner.hasNextLine()) { scanner.nextLine(); String line = scanner.nextLine().trim(); From 522d6577a90ca4b17308d5f95c8cce979ed3de8c Mon Sep 17 00:00:00 2001 From: Peng Junzhi <201250214@smail.nju.edu.cn> Date: Wed, 26 Mar 2025 14:16:26 +0800 Subject: [PATCH 07/15] add test code --- .../iotdb/metrics/utils/FileStoreUtils.java | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/iotdb-core/metrics/interface/src/main/java/org/apache/iotdb/metrics/utils/FileStoreUtils.java b/iotdb-core/metrics/interface/src/main/java/org/apache/iotdb/metrics/utils/FileStoreUtils.java index 1698f7d0ac100..abf396126d8e8 100644 --- a/iotdb-core/metrics/interface/src/main/java/org/apache/iotdb/metrics/utils/FileStoreUtils.java +++ b/iotdb-core/metrics/interface/src/main/java/org/apache/iotdb/metrics/utils/FileStoreUtils.java @@ -62,4 +62,27 @@ public static FileStore getFileStore(String dir) { } return fileStore; } + + public static void main(String[] args) { + printFile("/Applications"); + printFile("/Users"); + printFile("/Users/root"); + } + + public static void printFile(String path) { + try { + // 获取文件存储对象(FileStore) + FileStore fileStore = FileStoreUtils.getFileStore(path); + + // 输出文件所在磁盘的详细信息 + System.out.println("文件所在的磁盘: " + fileStore); + System.out.println("文件系统类型: " + fileStore.type()); + System.out.println("可用空间: " + fileStore.getUsableSpace()); + System.out.println("总空间: " + fileStore.getTotalSpace()); + System.out.println("是否只读: " + fileStore.isReadOnly()); + } catch (IOException e) { + e.printStackTrace(); + } + } + } From 704a6ca549929e05782a97378c30b17d17b2119b Mon Sep 17 00:00:00 2001 From: Peng Junzhi <201250214@smail.nju.edu.cn> Date: Wed, 26 Mar 2025 15:26:33 +0800 Subject: [PATCH 08/15] use file store --- .../storageengine/dataregion/DataRegion.java | 29 +++++++++++-------- .../iotdb/metrics/utils/FileStoreUtils.java | 25 +--------------- .../apache/iotdb/commons/utils/PathUtils.java | 21 -------------- 3 files changed, 18 insertions(+), 57 deletions(-) diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/DataRegion.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/DataRegion.java index 9b37e0820d5bf..b52111042d042 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/DataRegion.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/DataRegion.java @@ -35,7 +35,6 @@ import org.apache.iotdb.commons.service.metric.enums.Metric; import org.apache.iotdb.commons.service.metric.enums.Tag; import org.apache.iotdb.commons.utils.CommonDateTimeUtils; -import org.apache.iotdb.commons.utils.PathUtils; import org.apache.iotdb.commons.utils.RetryUtils; import org.apache.iotdb.commons.utils.TestOnly; import org.apache.iotdb.commons.utils.TimePartitionUtils; @@ -137,6 +136,7 @@ import org.apache.iotdb.db.utils.CommonUtils; import org.apache.iotdb.db.utils.DateTimeUtils; import org.apache.iotdb.db.utils.ModificationUtils; +import org.apache.iotdb.metrics.utils.FileStoreUtils; import org.apache.iotdb.metrics.utils.MetricLevel; import org.apache.iotdb.rpc.RpcUtils; import org.apache.iotdb.rpc.TSStatusCode; @@ -156,6 +156,7 @@ import java.io.File; import java.io.IOException; +import java.nio.file.FileStore; import java.nio.file.Files; import java.nio.file.Paths; import java.util.ArrayList; @@ -401,14 +402,18 @@ public DataRegion( dataDirPath -> { File dataDirFile = new File(dataDirPath); try { - String mountPoint = PathUtils.getMountPoint(dataDirFile.getCanonicalPath()); - this.rootDisks2DataDirsMapForLoad.put(mountPoint, dataDirPath); - logger.info("Add {}'s mount point {}", dataDirPath, mountPoint); + FileStore fileStore = FileStoreUtils.getFileStore(dataDirFile.getCanonicalPath()); + if (fileStore != null) { + String mountPoint = fileStore.toString(); + this.rootDisks2DataDirsMapForLoad.put(mountPoint, dataDirPath); + logger.info("Add {}'s mount point {}", dataDirPath, mountPoint); + } else { + logger.info( + "Failed to find mount point {}, skip register it to map", dataDirPath); + } } catch (Exception e) { logger.warn( - "Exception occurs when reading data dir's mount point {}, may because your OS is windows.", - dataDirPath, - e); + "Exception occurs when reading data dir's mount point {}", dataDirPath, e); } }); @@ -3080,12 +3085,12 @@ private boolean loadTsFileToUnSequence( boolean needDownGradeToSequenceStrategy = true; String fileDirRoot = null; try { - fileDirRoot = PathUtils.getMountPoint(tsFileToLoad.getCanonicalPath()); + fileDirRoot = + Optional.ofNullable(FileStoreUtils.getFileStore(tsFileToLoad.getCanonicalPath())) + .map(Object::toString) + .orElse(null); } catch (Exception e) { - logger.warn( - "Exception occurs when reading target file's mount point {}, may because your OS is windows.", - tsFileToLoad, - e); + logger.warn("Exception occurs when reading target file's mount point {}", tsFileToLoad, e); } // only IoTV2 and Pipe will try to enable multi-disks awareness diff --git a/iotdb-core/metrics/interface/src/main/java/org/apache/iotdb/metrics/utils/FileStoreUtils.java b/iotdb-core/metrics/interface/src/main/java/org/apache/iotdb/metrics/utils/FileStoreUtils.java index abf396126d8e8..5b41da6f6737b 100644 --- a/iotdb-core/metrics/interface/src/main/java/org/apache/iotdb/metrics/utils/FileStoreUtils.java +++ b/iotdb-core/metrics/interface/src/main/java/org/apache/iotdb/metrics/utils/FileStoreUtils.java @@ -32,7 +32,7 @@ public class FileStoreUtils { private static final Logger logger = LoggerFactory.getLogger(FileStoreUtils.class); - // get the FileStore of dir .if current dir is not exists, check parent dir. + // get the FileStore of dir. if current dir is not exists, check parent dir. // for example, the dn_wal_dirs default value is data/datanode/wal and system will save the // data in the relative path directory it indicates under the IoTDB folder. // it will check the parent dir until find the existing dir. @@ -62,27 +62,4 @@ public static FileStore getFileStore(String dir) { } return fileStore; } - - public static void main(String[] args) { - printFile("/Applications"); - printFile("/Users"); - printFile("/Users/root"); - } - - public static void printFile(String path) { - try { - // 获取文件存储对象(FileStore) - FileStore fileStore = FileStoreUtils.getFileStore(path); - - // 输出文件所在磁盘的详细信息 - System.out.println("文件所在的磁盘: " + fileStore); - System.out.println("文件系统类型: " + fileStore.type()); - System.out.println("可用空间: " + fileStore.getUsableSpace()); - System.out.println("总空间: " + fileStore.getTotalSpace()); - System.out.println("是否只读: " + fileStore.isReadOnly()); - } catch (IOException e) { - e.printStackTrace(); - } - } - } diff --git a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/utils/PathUtils.java b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/utils/PathUtils.java index 4364ead80d58d..5a2369f72a96e 100644 --- a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/utils/PathUtils.java +++ b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/utils/PathUtils.java @@ -28,12 +28,10 @@ import org.apache.tsfile.read.common.parser.PathNodesGenerator; import org.apache.tsfile.read.common.parser.PathVisitor; -import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Scanner; public class PathUtils { @@ -226,23 +224,4 @@ public static String unQualifyDatabaseName(String databaseName) { public static boolean isTableModelDatabase(final String databaseName) { return !databaseName.startsWith("root."); } - - /** - * Get the mount point of one specific file given its path. NOTE: only can be used in Linux and - * MacOS System. - */ - public static String getMountPoint(String path) throws IOException, InterruptedException { - Process process = Runtime.getRuntime().exec("df " + path); - process.waitFor(); - - try (Scanner scanner = new java.util.Scanner(process.getInputStream())) { - if (scanner.hasNextLine()) { - scanner.nextLine(); - String line = scanner.nextLine().trim(); - String[] parts = line.split("\\s+"); - return parts[parts.length - 1]; - } - } - return null; - } } From 659bf696dc10da48b34b3c0a9c4b0fab08a2afd3 Mon Sep 17 00:00:00 2001 From: Peng Junzhi <201250214@smail.nju.edu.cn> Date: Wed, 26 Mar 2025 22:27:43 +0800 Subject: [PATCH 09/15] add strategy for load disk selector --- .../org/apache/iotdb/db/conf/IoTDBConfig.java | 40 +++--- .../apache/iotdb/db/conf/IoTDBDescriptor.java | 25 ++-- .../storageengine/dataregion/DataRegion.java | 134 ++++++++---------- .../load/disk/ILoadDiskSelector.java | 65 +++++++++ .../load/disk/MinIOSelector.java | 106 ++++++++++++++ .../load/disk/StorageBalanceSelector.java | 56 ++++++++ .../conf/iotdb-system.properties.template | 41 +++--- 7 files changed, 346 insertions(+), 121 deletions(-) create mode 100644 iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/disk/ILoadDiskSelector.java create mode 100644 iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/disk/MinIOSelector.java create mode 100644 iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/disk/StorageBalanceSelector.java diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/conf/IoTDBConfig.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/conf/IoTDBConfig.java index 1e07c259d120e..b4fd0b781170d 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/conf/IoTDBConfig.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/conf/IoTDBConfig.java @@ -1073,7 +1073,6 @@ public class IoTDBConfig { + CONSENSUS_FOLDER_NAME + File.separator + DELETION_FOLDER_NAME; - private boolean enableMultiDisksAwareLoadForIoTV2 = false; /** Load related */ private double maxAllocateMemoryRatioForLoad = 0.8; @@ -1129,12 +1128,14 @@ public class IoTDBConfig { private boolean loadActiveListeningVerifyEnable = true; + private String loadDiskSelectStrategy; + + private String loadDiskSelectStrategyForIoTV2AndPipe; + /** Pipe related */ /** initialized as empty, updated based on the latest `systemDir` during querying */ private String[] pipeReceiverFileDirs = new String[0]; - private boolean enableMultiDisksAwareLoadForPipe = false; - /** Resource control */ private boolean quotaEnable = false; @@ -3852,6 +3853,23 @@ public void setLoadActiveListeningVerifyEnable(boolean loadActiveListeningVerify this.loadActiveListeningVerifyEnable = loadActiveListeningVerifyEnable; } + public String getLoadDiskSelectStrategy() { + return loadDiskSelectStrategy; + } + + public void setLoadDiskSelectStrategy(String loadDiskSelectStrategy) { + this.loadDiskSelectStrategy = loadDiskSelectStrategy; + } + + public String getLoadDiskSelectStrategyForIoTV2AndPipe() { + return loadDiskSelectStrategyForIoTV2AndPipe; + } + + public void setLoadDiskSelectStrategyForIoTV2AndPipe( + String loadDiskSelectStrategyForIoTV2AndPipe) { + this.loadDiskSelectStrategyForIoTV2AndPipe = loadDiskSelectStrategyForIoTV2AndPipe; + } + public long getLoadActiveListeningCheckIntervalSeconds() { return loadActiveListeningCheckIntervalSeconds; } @@ -3915,14 +3933,6 @@ public void setPipeReceiverFileDirs(String[] pipeReceiverFileDirs) { this.pipeReceiverFileDirs = pipeReceiverFileDirs; } - public boolean isEnableMultiDisksAwareLoadForPipe() { - return this.enableMultiDisksAwareLoadForPipe; - } - - public void setEnableMultiDisksAwareLoadForPipe(boolean enableMultiDisksAwareLoadForPipe) { - this.enableMultiDisksAwareLoadForPipe = enableMultiDisksAwareLoadForPipe; - } - public String[] getPipeReceiverFileDirs() { return (Objects.isNull(this.pipeReceiverFileDirs) || this.pipeReceiverFileDirs.length == 0) ? new String[] {systemDir + File.separator + "pipe" + File.separator + "receiver"} @@ -3948,14 +3958,6 @@ public String[] getIotConsensusV2ReceiverFileDirs() { : this.iotConsensusV2ReceiverFileDirs; } - public boolean isEnableMultiDisksAwareLoadForIoTV2() { - return this.enableMultiDisksAwareLoadForIoTV2; - } - - public void setEnableMultiDisksAwareLoadForIoTV2(boolean enableMultiDisksAwareLoadForIoTV2) { - this.enableMultiDisksAwareLoadForIoTV2 = enableMultiDisksAwareLoadForIoTV2; - } - public boolean isQuotaEnable() { return quotaEnable; } diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/conf/IoTDBDescriptor.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/conf/IoTDBDescriptor.java index 1a3eacc8c9406..e834544148565 100755 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/conf/IoTDBDescriptor.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/conf/IoTDBDescriptor.java @@ -2144,7 +2144,7 @@ public void reloadMetricProperties(TrimProperties properties) { } } - private void loadLoadTsFileProps(TrimProperties properties) { + private void loadLoadTsFileProps(TrimProperties properties) throws IOException { conf.setMaxAllocateMemoryRatioForLoad( Double.parseDouble( properties.getProperty( @@ -2247,6 +2247,17 @@ private void loadLoadTsFileProps(TrimProperties properties) { properties.getProperty( "load_active_listening_verify_enable", Boolean.toString(conf.isLoadActiveListeningVerifyEnable())))); + + conf.setLoadDiskSelectStrategy( + properties.getProperty( + "load_disk_select_strategy", + ConfigurationFileUtils.getConfigurationDefaultValue("load_disk_select_strategy"))); + + conf.setLoadDiskSelectStrategyForIoTV2AndPipe( + properties.getProperty( + "load_disk_select_strategy_for_pipe_and_iotv2", + ConfigurationFileUtils.getConfigurationDefaultValue( + "load_disk_select_strategy_for_pipe_and_iotv2"))); } private void loadLoadTsFileHotModifiedProp(TrimProperties properties) throws IOException { @@ -2404,12 +2415,6 @@ private void loadPipeProps(TrimProperties properties) { .filter(dir -> !dir.isEmpty()) .toArray(String[]::new)); - conf.setEnableMultiDisksAwareLoadForPipe( - Boolean.parseBoolean( - properties.getProperty( - "enable_multi_disks_aware_load_for_pipe", - Boolean.toString(conf.isEnableMultiDisksAwareLoadForPipe())))); - conf.setIotConsensusV2ReceiverFileDirs( Arrays.stream( properties @@ -2421,12 +2426,6 @@ private void loadPipeProps(TrimProperties properties) { .filter(dir -> !dir.isEmpty()) .toArray(String[]::new)); - conf.setEnableMultiDisksAwareLoadForIoTV2( - Boolean.parseBoolean( - properties.getProperty( - "enable_multi_disks_aware_load_for_iotv2", - Boolean.toString(conf.isEnableMultiDisksAwareLoadForIoTV2())))); - conf.setIotConsensusV2DeletionFileDir( properties.getProperty( "iot_consensus_v2_deletion_file_dir", conf.getIotConsensusV2DeletionFileDir())); diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/DataRegion.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/DataRegion.java index b52111042d042..84f7e2cd0a269 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/DataRegion.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/DataRegion.java @@ -23,7 +23,6 @@ import org.apache.iotdb.commons.cluster.NodeStatus; import org.apache.iotdb.commons.concurrent.IoTDBThreadPoolFactory; import org.apache.iotdb.commons.conf.CommonDescriptor; -import org.apache.iotdb.commons.conf.IoTDBConstant; import org.apache.iotdb.commons.consensus.DataRegionId; import org.apache.iotdb.commons.exception.MetadataException; import org.apache.iotdb.commons.file.SystemFileFactory; @@ -125,6 +124,9 @@ import org.apache.iotdb.db.storageengine.dataregion.wal.utils.WALMode; import org.apache.iotdb.db.storageengine.dataregion.wal.utils.listener.WALFlushListener; import org.apache.iotdb.db.storageengine.dataregion.wal.utils.listener.WALRecoverListener; +import org.apache.iotdb.db.storageengine.load.disk.ILoadDiskSelector; +import org.apache.iotdb.db.storageengine.load.disk.MinIOSelector; +import org.apache.iotdb.db.storageengine.load.disk.StorageBalanceSelector; import org.apache.iotdb.db.storageengine.load.limiter.LoadTsFileRateLimiter; import org.apache.iotdb.db.storageengine.rescon.disk.TierManager; import org.apache.iotdb.db.storageengine.rescon.memory.SystemInfo; @@ -136,7 +138,6 @@ import org.apache.iotdb.db.utils.CommonUtils; import org.apache.iotdb.db.utils.DateTimeUtils; import org.apache.iotdb.db.utils.ModificationUtils; -import org.apache.iotdb.metrics.utils.FileStoreUtils; import org.apache.iotdb.metrics.utils.MetricLevel; import org.apache.iotdb.rpc.RpcUtils; import org.apache.iotdb.rpc.TSStatusCode; @@ -156,7 +157,6 @@ import java.io.File; import java.io.IOException; -import java.nio.file.FileStore; import java.nio.file.Files; import java.nio.file.Paths; import java.util.ArrayList; @@ -328,7 +328,8 @@ public class DataRegion implements IDataRegionForQuery { private final DataRegionMetrics metrics; - private final Map rootDisks2DataDirsMapForLoad; + private final ILoadDiskSelector ordinaryLoadDiskSelector; + private final ILoadDiskSelector pipeAndIoTV2LoadDiskSelector; /** * Construct a database processor. @@ -393,29 +394,27 @@ public DataRegion( recover(); } - // init data dirs' root disks - this.rootDisks2DataDirsMapForLoad = new HashMap<>(config.getTierDataDirs()[0].length); - Arrays.stream(config.getTierDataDirs()[0]) - .filter(Objects::nonNull) - .map(v -> fsFactory.getFile(v, IoTDBConstant.UNSEQUENCE_FOLDER_NAME).getPath()) - .forEach( - dataDirPath -> { - File dataDirFile = new File(dataDirPath); - try { - FileStore fileStore = FileStoreUtils.getFileStore(dataDirFile.getCanonicalPath()); - if (fileStore != null) { - String mountPoint = fileStore.toString(); - this.rootDisks2DataDirsMapForLoad.put(mountPoint, dataDirPath); - logger.info("Add {}'s mount point {}", dataDirPath, mountPoint); - } else { - logger.info( - "Failed to find mount point {}, skip register it to map", dataDirPath); - } - } catch (Exception e) { - logger.warn( - "Exception occurs when reading data dir's mount point {}", dataDirPath, e); - } - }); + switch (ILoadDiskSelector.LoadDiskSelectorType.fromValue(config.getLoadDiskSelectStrategy())) { + case MIN_IO_FIRST: + ordinaryLoadDiskSelector = new MinIOSelector(); + break; + case DISK_STORAGE_BALANCE_FIRST: + default: + ordinaryLoadDiskSelector = new StorageBalanceSelector(); + } + + switch (ILoadDiskSelector.LoadDiskSelectorType.fromValue( + config.getLoadDiskSelectStrategyForIoTV2AndPipe())) { + case MIN_IO_FIRST: + pipeAndIoTV2LoadDiskSelector = new MinIOSelector(); + break; + case EXTEND_LOAD: + pipeAndIoTV2LoadDiskSelector = ordinaryLoadDiskSelector; + break; + case DISK_STORAGE_BALANCE_FIRST: + default: + pipeAndIoTV2LoadDiskSelector = new StorageBalanceSelector(); + } this.metrics = new DataRegionMetrics(this); MetricService.getInstance().addMetricSet(metrics); @@ -429,8 +428,29 @@ public DataRegion(String databaseName, String id) { this.partitionMaxFileVersions = new HashMap<>(); partitionMaxFileVersions.put(0L, 0L); upgradeModFileThreadPool = null; - this.rootDisks2DataDirsMapForLoad = new HashMap<>(); this.metrics = new DataRegionMetrics(this); + + switch (ILoadDiskSelector.LoadDiskSelectorType.fromValue(config.getLoadDiskSelectStrategy())) { + case MIN_IO_FIRST: + ordinaryLoadDiskSelector = new MinIOSelector(); + break; + case DISK_STORAGE_BALANCE_FIRST: + default: + ordinaryLoadDiskSelector = new StorageBalanceSelector(); + } + + switch (ILoadDiskSelector.LoadDiskSelectorType.fromValue( + config.getLoadDiskSelectStrategyForIoTV2AndPipe())) { + case MIN_IO_FIRST: + pipeAndIoTV2LoadDiskSelector = new MinIOSelector(); + break; + case EXTEND_LOAD: + pipeAndIoTV2LoadDiskSelector = ordinaryLoadDiskSelector; + break; + case DISK_STORAGE_BALANCE_FIRST: + default: + pipeAndIoTV2LoadDiskSelector = new StorageBalanceSelector(); + } } @Override @@ -3082,50 +3102,22 @@ private boolean loadTsFileToUnSequence( boolean isGeneratedByPipe) throws LoadFileException, DiskSpaceInsufficientException { File targetFile = null; - boolean needDownGradeToSequenceStrategy = true; - String fileDirRoot = null; - try { - fileDirRoot = - Optional.ofNullable(FileStoreUtils.getFileStore(tsFileToLoad.getCanonicalPath())) - .map(Object::toString) - .orElse(null); - } catch (Exception e) { - logger.warn("Exception occurs when reading target file's mount point {}", tsFileToLoad, e); - } - - // only IoTV2 and Pipe will try to enable multi-disks awareness - if ((config.isEnableMultiDisksAwareLoadForIoTV2() - && tsFileResource.isGeneratedByPipeConsensus()) - || (config.isEnableMultiDisksAwareLoadForPipe() && tsFileResource.isGeneratedByPipe())) { - if (rootDisks2DataDirsMapForLoad.containsKey(fileDirRoot)) { - // if there is an overlap between firDirRoot and data directories' disk roots, try to get - // targetFile in the same disk - targetFile = - fsFactory.getFile( - rootDisks2DataDirsMapForLoad.get(fileDirRoot), - databaseName - + File.separatorChar - + dataRegionId - + File.separatorChar - + filePartitionId - + File.separator - + tsFileResource.getTsFile().getName()); - - needDownGradeToSequenceStrategy = false; - } - } - - if (needDownGradeToSequenceStrategy) { + if (tsFileResource.isGeneratedByPipeConsensus() || tsFileResource.isGeneratedByPipe()) { targetFile = - fsFactory.getFile( - TierManager.getInstance().getNextFolderForTsFile(0, false), - databaseName - + File.separatorChar - + dataRegionId - + File.separatorChar - + filePartitionId - + File.separator - + tsFileResource.getTsFile().getName()); + pipeAndIoTV2LoadDiskSelector.getTargetFile( + targetFile, + databaseName, + dataRegionId, + filePartitionId, + tsFileResource.getTsFile().getName()); + } else { + targetFile = + ordinaryLoadDiskSelector.getTargetFile( + targetFile, + databaseName, + dataRegionId, + filePartitionId, + tsFileResource.getTsFile().getName()); } // var used in lambda must be final diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/disk/ILoadDiskSelector.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/disk/ILoadDiskSelector.java new file mode 100644 index 0000000000000..438ef784cd23e --- /dev/null +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/disk/ILoadDiskSelector.java @@ -0,0 +1,65 @@ +/* + * 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.storageengine.load.disk; + +import org.apache.iotdb.db.exception.DiskSpaceInsufficientException; + +import java.io.File; + +public interface ILoadDiskSelector { + + File getTargetFile( + File fileToLoad, + String databaseName, + String dataRegionId, + long filePartitionId, + String tsfileName) + throws DiskSpaceInsufficientException; + + enum LoadDiskSelectorType { + MIN_IO_FIRST("MIN_IO_FIRST"), + DISK_STORAGE_BALANCE_FIRST("DISK_STORAGE_BALANCE_FIRST"), + // This type is specially designed for IoTV2 and Pipe, which means IoTV2 and Pipe will follow + // the same strategy as ordinary load. + EXTEND_LOAD("EXTEND_LOAD"); + + private final String value; + + LoadDiskSelectorType(String value) { + this.value = value; + } + + public String getValue() { + return value; + } + + public static LoadDiskSelectorType fromValue(String value) { + if (value.equalsIgnoreCase(MIN_IO_FIRST.getValue())) { + return MIN_IO_FIRST; + } else if (value.equalsIgnoreCase(DISK_STORAGE_BALANCE_FIRST.getValue())) { + return DISK_STORAGE_BALANCE_FIRST; + } else if (value.equalsIgnoreCase(EXTEND_LOAD.getValue())) { + return EXTEND_LOAD; + } + // return DISK_STORAGE_BALANCE_FIRST by default + return DISK_STORAGE_BALANCE_FIRST; + } + } +} diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/disk/MinIOSelector.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/disk/MinIOSelector.java new file mode 100644 index 0000000000000..90e45193e382f --- /dev/null +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/disk/MinIOSelector.java @@ -0,0 +1,106 @@ +/* + * 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.storageengine.load.disk; + +import org.apache.iotdb.commons.conf.IoTDBConstant; +import org.apache.iotdb.db.conf.IoTDBConfig; +import org.apache.iotdb.db.conf.IoTDBDescriptor; +import org.apache.iotdb.db.exception.DiskSpaceInsufficientException; +import org.apache.iotdb.metrics.utils.FileStoreUtils; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.nio.file.FileStore; +import java.util.*; + +public class MinIOSelector extends StorageBalanceSelector { + + private static final Logger logger = LoggerFactory.getLogger(MinIOSelector.class); + private static final IoTDBConfig config = IoTDBDescriptor.getInstance().getConfig(); + private final Map rootDisks2DataDirsMapForLoad; + + public MinIOSelector() { + // init data dirs' root disks + this.rootDisks2DataDirsMapForLoad = new HashMap<>(config.getTierDataDirs()[0].length); + Arrays.stream(config.getTierDataDirs()[0]) + .filter(Objects::nonNull) + .map(v -> fsFactory.getFile(v, IoTDBConstant.UNSEQUENCE_FOLDER_NAME).getPath()) + .forEach( + dataDirPath -> { + File dataDirFile = new File(dataDirPath); + try { + FileStore fileStore = FileStoreUtils.getFileStore(dataDirFile.getCanonicalPath()); + if (fileStore != null) { + String mountPoint = fileStore.toString(); + this.rootDisks2DataDirsMapForLoad.put(mountPoint, dataDirPath); + logger.info("Add {}'s mount point {}", dataDirPath, mountPoint); + } else { + logger.info( + "Failed to find mount point {}, skip register it to map", dataDirPath); + } + } catch (Exception e) { + logger.warn( + "Exception occurs when reading data dir's mount point {}", dataDirPath, e); + } + }); + } + + @Override + public File getTargetFile( + File fileToLoad, + String databaseName, + String dataRegionId, + long filePartitionId, + String tsfileName) + throws DiskSpaceInsufficientException { + File targetFile; + String fileDirRoot = null; + try { + fileDirRoot = + Optional.ofNullable(FileStoreUtils.getFileStore(fileToLoad.getCanonicalPath())) + .map(Object::toString) + .orElse(null); + } catch (Exception e) { + logger.warn("Exception occurs when reading target file's mount point {}", filePartitionId, e); + } + + if (rootDisks2DataDirsMapForLoad.containsKey(fileDirRoot)) { + // if there is an overlap between firDirRoot and data directories' disk roots, try to get + // targetFile in the same disk + targetFile = + fsFactory.getFile( + rootDisks2DataDirsMapForLoad.get(fileDirRoot), + databaseName + + File.separatorChar + + dataRegionId + + File.separatorChar + + filePartitionId + + File.separator + + tsfileName); + + return targetFile; + } + + // if there isn't an overlap, downgrade to storage balance(sequence) strategy. + return super.getTargetFile(fileToLoad, databaseName, dataRegionId, filePartitionId, tsfileName); + } +} diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/disk/StorageBalanceSelector.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/disk/StorageBalanceSelector.java new file mode 100644 index 0000000000000..6929035ce6449 --- /dev/null +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/disk/StorageBalanceSelector.java @@ -0,0 +1,56 @@ +/* + * 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.storageengine.load.disk; + +import org.apache.iotdb.db.exception.DiskSpaceInsufficientException; +import org.apache.iotdb.db.storageengine.rescon.disk.TierManager; + +import org.apache.tsfile.fileSystem.FSFactoryProducer; +import org.apache.tsfile.fileSystem.fsFactory.FSFactory; + +import java.io.File; + +public class StorageBalanceSelector implements ILoadDiskSelector { + + protected final FSFactory fsFactory = FSFactoryProducer.getFSFactory(); + + public StorageBalanceSelector() { + // empty body + } + + @Override + public File getTargetFile( + File fileToLoad, + String databaseName, + String dataRegionId, + long filePartitionId, + String tsfileName) + throws DiskSpaceInsufficientException { + return fsFactory.getFile( + TierManager.getInstance().getNextFolderForTsFile(0, false), + databaseName + + File.separatorChar + + dataRegionId + + File.separatorChar + + filePartitionId + + File.separator + + tsfileName); + } +} diff --git a/iotdb-core/node-commons/src/assembly/resources/conf/iotdb-system.properties.template b/iotdb-core/node-commons/src/assembly/resources/conf/iotdb-system.properties.template index cb4dd96b0bdac..49690939526ec 100644 --- a/iotdb-core/node-commons/src/assembly/resources/conf/iotdb-system.properties.template +++ b/iotdb-core/node-commons/src/assembly/resources/conf/iotdb-system.properties.template @@ -242,6 +242,29 @@ dn_data_dirs=data/datanode/data # Datatype: String dn_multi_dir_strategy=SequenceStrategy +# load_disk_select_strategy +# The strategy is used to choose a proper disk for loading tsfile. +# System provides two strategies to choose from, or user can create his own strategy by extending org.apache.iotdb.db.storageengine.load.disk.ILoadDiskSelector. +# The info of the two strategies are as follows: +# 1. MIN_IO_FIRST: the system will try to choose the same disk as tsFileToLoad for loading. +# 2. DISK_STORAGE_BALANCE_FIRST: the system will make the disk choice that balance storage as much as possible. +# If this property is unset, system will use DISK_STORAGE_BALANCE_FIRST as default strategy because storage-balance is ensured with higher priority. +# effectiveMode: hot_reload +# Datatype: String +load_disk_select_strategy=DISK_STORAGE_BALANCE_FIRST + +# load_disk_select_strategy_for_pipe_and_iotv2 +# The strategy is used to choose a proper disk for loading tsfile. +# System provides two strategies to choose from, or user can create his own strategy by extending org.apache.iotdb.db.storageengine.load.disk.ILoadDiskSelector. +# The info of the two strategies are as follows: +# 1. MIN_IO_FIRST: the system will try to choose the same disk as tsFileToLoad for loading. +# 2. DISK_STORAGE_BALANCE_FIRST: the system will make the disk choice that balance storage as much as possible. +$ 3. EXTEND_LOAD: the system will use the same strategy as load_disk_select_strategy +# If this property is unset, system will use DISK_STORAGE_BALANCE_FIRST as default strategy because storage-balance is ensured with higher priority. +# effectiveMode: hot_reload +# Datatype: String +load_disk_select_strategy_for_pipe_and_iotv2=DISK_STORAGE_BALANCE_FIRST + # consensus dir # If this property is unset, system will save the data in the default relative path directory under the IoTDB folder(i.e., %IOTDB_HOME%/data/datanode). # If it is absolute, system will save the data in the exact location it points to. @@ -319,15 +342,6 @@ sort_tmp_dir=data/datanode/tmp # If its prefix is "/", then the path is absolute. Otherwise, it is relative. dn_pipe_receiver_file_dirs=data/datanode/system/pipe/receiver -# enable_multi_disks_aware_load_for_pipe -# Whether to enable multi-disks aware load for pipe. -# The load process will try to move tsFile within the same disk if set true. -# Recommend set to true if amount of pipe receiver disks is equal to data disks' to ensure io-balance and storage-balance at the same time. -# Notice: Default is false because storage-balance is ensured with higher priority. -# effectiveMode: restart -# Datatype: Boolean -enable_multi_disks_aware_load_for_pipe=false - # iot_consensus_v2_receiver_file_dirs # If this property is unset, system will save the data in the default relative path directory under the IoTDB folder(i.e., %IOTDB_HOME%/${dn_system_dir}/pipe/consensus/receiver). # If it is absolute, system will save the data in the exact location it points to. @@ -355,15 +369,6 @@ iot_consensus_v2_receiver_file_dirs=data/datanode/system/pipe/consensus/receiver # If its prefix is "/", then the path is absolute. Otherwise, it is relative. iot_consensus_v2_deletion_file_dir=data/datanode/system/pipe/consensus/deletion -# enable_multi_disks_aware_load_for_iotv2 -# Whether to enable multi-disks aware load for iot consensus v2. -# The load process will try to move tsFile within the same disk if set true. -# Recommend set to true if amount of iotv2 receiver disks is equal to data disks' to ensure io-balance and storage-balance at the same time. -# Notice: Default is false because storage-balance is ensured with higher priority. -# effectiveMode: restart -# Datatype: Boolean -enable_multi_disks_aware_load_for_iotv2=false - #################### ### Metric Configuration #################### From ceb3cd71d4f0e775f2a34ce56ff61aace1abdb6a Mon Sep 17 00:00:00 2001 From: Peng Junzhi <201250214@smail.nju.edu.cn> Date: Wed, 26 Mar 2025 22:33:34 +0800 Subject: [PATCH 10/15] fix description --- .../resources/conf/iotdb-system.properties.template | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/iotdb-core/node-commons/src/assembly/resources/conf/iotdb-system.properties.template b/iotdb-core/node-commons/src/assembly/resources/conf/iotdb-system.properties.template index 49690939526ec..eac23d9558c31 100644 --- a/iotdb-core/node-commons/src/assembly/resources/conf/iotdb-system.properties.template +++ b/iotdb-core/node-commons/src/assembly/resources/conf/iotdb-system.properties.template @@ -244,24 +244,22 @@ dn_multi_dir_strategy=SequenceStrategy # load_disk_select_strategy # The strategy is used to choose a proper disk for loading tsfile. -# System provides two strategies to choose from, or user can create his own strategy by extending org.apache.iotdb.db.storageengine.load.disk.ILoadDiskSelector. # The info of the two strategies are as follows: # 1. MIN_IO_FIRST: the system will try to choose the same disk as tsFileToLoad for loading. # 2. DISK_STORAGE_BALANCE_FIRST: the system will make the disk choice that balance storage as much as possible. # If this property is unset, system will use DISK_STORAGE_BALANCE_FIRST as default strategy because storage-balance is ensured with higher priority. -# effectiveMode: hot_reload +# effectiveMode: restart # Datatype: String load_disk_select_strategy=DISK_STORAGE_BALANCE_FIRST # load_disk_select_strategy_for_pipe_and_iotv2 # The strategy is used to choose a proper disk for loading tsfile. -# System provides two strategies to choose from, or user can create his own strategy by extending org.apache.iotdb.db.storageengine.load.disk.ILoadDiskSelector. -# The info of the two strategies are as follows: +# The info of the three strategies are as follows: # 1. MIN_IO_FIRST: the system will try to choose the same disk as tsFileToLoad for loading. # 2. DISK_STORAGE_BALANCE_FIRST: the system will make the disk choice that balance storage as much as possible. $ 3. EXTEND_LOAD: the system will use the same strategy as load_disk_select_strategy # If this property is unset, system will use DISK_STORAGE_BALANCE_FIRST as default strategy because storage-balance is ensured with higher priority. -# effectiveMode: hot_reload +# effectiveMode: restart # Datatype: String load_disk_select_strategy_for_pipe_and_iotv2=DISK_STORAGE_BALANCE_FIRST From 50166baf712c79ff4e7739381d298fee2398bcb8 Mon Sep 17 00:00:00 2001 From: Peng Junzhi <201250214@smail.nju.edu.cn> Date: Thu, 27 Mar 2025 11:30:16 +0800 Subject: [PATCH 11/15] fix review --- .../apache/iotdb/db/conf/IoTDBDescriptor.java | 10 +-- .../storageengine/dataregion/DataRegion.java | 78 +++++++------------ .../load/disk/ILoadDiskSelector.java | 6 +- .../conf/iotdb-system.properties.template | 2 +- 4 files changed, 38 insertions(+), 58 deletions(-) diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/conf/IoTDBDescriptor.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/conf/IoTDBDescriptor.java index e834544148565..7c4b7bbb5f741 100755 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/conf/IoTDBDescriptor.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/conf/IoTDBDescriptor.java @@ -32,6 +32,7 @@ import org.apache.iotdb.confignode.rpc.thrift.TCQConfig; import org.apache.iotdb.confignode.rpc.thrift.TGlobalConfig; import org.apache.iotdb.confignode.rpc.thrift.TRatisConfig; +import org.apache.iotdb.consensus.config.PipeConsensusConfig; import org.apache.iotdb.db.consensus.DataRegionConsensusImpl; import org.apache.iotdb.db.exception.query.QueryProcessException; import org.apache.iotdb.db.service.metrics.IoTDBInternalLocalReporter; @@ -47,6 +48,7 @@ import org.apache.iotdb.db.storageengine.dataregion.compaction.selector.constant.InnerUnsequenceCompactionSelector; import org.apache.iotdb.db.storageengine.dataregion.wal.WALManager; import org.apache.iotdb.db.storageengine.dataregion.wal.utils.WALMode; +import org.apache.iotdb.db.storageengine.load.disk.ILoadDiskSelector; import org.apache.iotdb.db.storageengine.rescon.disk.TierManager; import org.apache.iotdb.db.storageengine.rescon.memory.SystemInfo; import org.apache.iotdb.db.utils.DateTimeUtils; @@ -1152,8 +1154,7 @@ private void loadIoTConsensusV2Props(TrimProperties properties) throws IOExcepti } conf.setIotConsensusV2Mode( properties.getProperty( - "iot_consensus_v2_mode", - ConfigurationFileUtils.getConfigurationDefaultValue("iot_consensus_v2_mode"))); + "iot_consensus_v2_mode", PipeConsensusConfig.ReplicateMode.BATCH.getValue())); int deletionAheadLogBufferQueueCapacity = Integer.parseInt( properties.getProperty( @@ -2251,13 +2252,12 @@ private void loadLoadTsFileProps(TrimProperties properties) throws IOException { conf.setLoadDiskSelectStrategy( properties.getProperty( "load_disk_select_strategy", - ConfigurationFileUtils.getConfigurationDefaultValue("load_disk_select_strategy"))); + ILoadDiskSelector.LoadDiskSelectorType.MIN_IO_FIRST.getValue())); conf.setLoadDiskSelectStrategyForIoTV2AndPipe( properties.getProperty( "load_disk_select_strategy_for_pipe_and_iotv2", - ConfigurationFileUtils.getConfigurationDefaultValue( - "load_disk_select_strategy_for_pipe_and_iotv2"))); + ILoadDiskSelector.LoadDiskSelectorType.INHERIT_LOAD.getValue())); } private void loadLoadTsFileHotModifiedProp(TrimProperties properties) throws IOException { diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/DataRegion.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/DataRegion.java index 84f7e2cd0a269..e0f3b6fe2c925 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/DataRegion.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/DataRegion.java @@ -328,8 +328,8 @@ public class DataRegion implements IDataRegionForQuery { private final DataRegionMetrics metrics; - private final ILoadDiskSelector ordinaryLoadDiskSelector; - private final ILoadDiskSelector pipeAndIoTV2LoadDiskSelector; + private ILoadDiskSelector ordinaryLoadDiskSelector; + private ILoadDiskSelector pipeAndIoTV2LoadDiskSelector; /** * Construct a database processor. @@ -394,27 +394,7 @@ public DataRegion( recover(); } - switch (ILoadDiskSelector.LoadDiskSelectorType.fromValue(config.getLoadDiskSelectStrategy())) { - case MIN_IO_FIRST: - ordinaryLoadDiskSelector = new MinIOSelector(); - break; - case DISK_STORAGE_BALANCE_FIRST: - default: - ordinaryLoadDiskSelector = new StorageBalanceSelector(); - } - - switch (ILoadDiskSelector.LoadDiskSelectorType.fromValue( - config.getLoadDiskSelectStrategyForIoTV2AndPipe())) { - case MIN_IO_FIRST: - pipeAndIoTV2LoadDiskSelector = new MinIOSelector(); - break; - case EXTEND_LOAD: - pipeAndIoTV2LoadDiskSelector = ordinaryLoadDiskSelector; - break; - case DISK_STORAGE_BALANCE_FIRST: - default: - pipeAndIoTV2LoadDiskSelector = new StorageBalanceSelector(); - } + initDiskSelector(); this.metrics = new DataRegionMetrics(this); MetricService.getInstance().addMetricSet(metrics); @@ -430,13 +410,17 @@ public DataRegion(String databaseName, String id) { upgradeModFileThreadPool = null; this.metrics = new DataRegionMetrics(this); + initDiskSelector(); + } + + private void initDiskSelector() { switch (ILoadDiskSelector.LoadDiskSelectorType.fromValue(config.getLoadDiskSelectStrategy())) { - case MIN_IO_FIRST: - ordinaryLoadDiskSelector = new MinIOSelector(); - break; case DISK_STORAGE_BALANCE_FIRST: - default: ordinaryLoadDiskSelector = new StorageBalanceSelector(); + break; + case MIN_IO_FIRST: + default: + ordinaryLoadDiskSelector = new MinIOSelector(); } switch (ILoadDiskSelector.LoadDiskSelectorType.fromValue( @@ -444,12 +428,12 @@ public DataRegion(String databaseName, String id) { case MIN_IO_FIRST: pipeAndIoTV2LoadDiskSelector = new MinIOSelector(); break; - case EXTEND_LOAD: - pipeAndIoTV2LoadDiskSelector = ordinaryLoadDiskSelector; - break; case DISK_STORAGE_BALANCE_FIRST: - default: pipeAndIoTV2LoadDiskSelector = new StorageBalanceSelector(); + break; + case INHERIT_LOAD: + default: + pipeAndIoTV2LoadDiskSelector = ordinaryLoadDiskSelector; } } @@ -3101,24 +3085,20 @@ private boolean loadTsFileToUnSequence( final boolean deleteOriginFile, boolean isGeneratedByPipe) throws LoadFileException, DiskSpaceInsufficientException { - File targetFile = null; - if (tsFileResource.isGeneratedByPipeConsensus() || tsFileResource.isGeneratedByPipe()) { - targetFile = - pipeAndIoTV2LoadDiskSelector.getTargetFile( - targetFile, - databaseName, - dataRegionId, - filePartitionId, - tsFileResource.getTsFile().getName()); - } else { - targetFile = - ordinaryLoadDiskSelector.getTargetFile( - targetFile, - databaseName, - dataRegionId, - filePartitionId, - tsFileResource.getTsFile().getName()); - } + final File targetFile = + (tsFileResource.isGeneratedByPipeConsensus() || tsFileResource.isGeneratedByPipe()) + ? pipeAndIoTV2LoadDiskSelector.getTargetFile( + tsFileToLoad, + databaseName, + dataRegionId, + filePartitionId, + tsFileResource.getTsFile().getName()) + : ordinaryLoadDiskSelector.getTargetFile( + tsFileToLoad, + databaseName, + dataRegionId, + filePartitionId, + tsFileResource.getTsFile().getName()); // var used in lambda must be final final File finalTargetFile = targetFile; diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/disk/ILoadDiskSelector.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/disk/ILoadDiskSelector.java index 438ef784cd23e..95ba8aef04b1d 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/disk/ILoadDiskSelector.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/disk/ILoadDiskSelector.java @@ -38,7 +38,7 @@ enum LoadDiskSelectorType { DISK_STORAGE_BALANCE_FIRST("DISK_STORAGE_BALANCE_FIRST"), // This type is specially designed for IoTV2 and Pipe, which means IoTV2 and Pipe will follow // the same strategy as ordinary load. - EXTEND_LOAD("EXTEND_LOAD"); + INHERIT_LOAD("INHERIT_LOAD"); private final String value; @@ -55,8 +55,8 @@ public static LoadDiskSelectorType fromValue(String value) { return MIN_IO_FIRST; } else if (value.equalsIgnoreCase(DISK_STORAGE_BALANCE_FIRST.getValue())) { return DISK_STORAGE_BALANCE_FIRST; - } else if (value.equalsIgnoreCase(EXTEND_LOAD.getValue())) { - return EXTEND_LOAD; + } else if (value.equalsIgnoreCase(INHERIT_LOAD.getValue())) { + return INHERIT_LOAD; } // return DISK_STORAGE_BALANCE_FIRST by default return DISK_STORAGE_BALANCE_FIRST; diff --git a/iotdb-core/node-commons/src/assembly/resources/conf/iotdb-system.properties.template b/iotdb-core/node-commons/src/assembly/resources/conf/iotdb-system.properties.template index eac23d9558c31..77371b226a2f8 100644 --- a/iotdb-core/node-commons/src/assembly/resources/conf/iotdb-system.properties.template +++ b/iotdb-core/node-commons/src/assembly/resources/conf/iotdb-system.properties.template @@ -257,7 +257,7 @@ load_disk_select_strategy=DISK_STORAGE_BALANCE_FIRST # The info of the three strategies are as follows: # 1. MIN_IO_FIRST: the system will try to choose the same disk as tsFileToLoad for loading. # 2. DISK_STORAGE_BALANCE_FIRST: the system will make the disk choice that balance storage as much as possible. -$ 3. EXTEND_LOAD: the system will use the same strategy as load_disk_select_strategy +$ 3. INHERIT_LOAD: the system will use the same strategy as load_disk_select_strategy # If this property is unset, system will use DISK_STORAGE_BALANCE_FIRST as default strategy because storage-balance is ensured with higher priority. # effectiveMode: restart # Datatype: String From 008260fa7e927af5e5b84422134d415ee926ba9d Mon Sep 17 00:00:00 2001 From: Peng Junzhi <201250214@smail.nju.edu.cn> Date: Thu, 27 Mar 2025 11:32:23 +0800 Subject: [PATCH 12/15] fix default --- .../resources/conf/iotdb-system.properties.template | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/iotdb-core/node-commons/src/assembly/resources/conf/iotdb-system.properties.template b/iotdb-core/node-commons/src/assembly/resources/conf/iotdb-system.properties.template index 77371b226a2f8..1e4e7a13aa9a0 100644 --- a/iotdb-core/node-commons/src/assembly/resources/conf/iotdb-system.properties.template +++ b/iotdb-core/node-commons/src/assembly/resources/conf/iotdb-system.properties.template @@ -247,10 +247,10 @@ dn_multi_dir_strategy=SequenceStrategy # The info of the two strategies are as follows: # 1. MIN_IO_FIRST: the system will try to choose the same disk as tsFileToLoad for loading. # 2. DISK_STORAGE_BALANCE_FIRST: the system will make the disk choice that balance storage as much as possible. -# If this property is unset, system will use DISK_STORAGE_BALANCE_FIRST as default strategy because storage-balance is ensured with higher priority. +# If this property is unset, system will use MIN_IO_FIRST as default strategy because storage-balance is ensured with higher priority. # effectiveMode: restart # Datatype: String -load_disk_select_strategy=DISK_STORAGE_BALANCE_FIRST +load_disk_select_strategy=MIN_IO_FIRST # load_disk_select_strategy_for_pipe_and_iotv2 # The strategy is used to choose a proper disk for loading tsfile. @@ -258,10 +258,10 @@ load_disk_select_strategy=DISK_STORAGE_BALANCE_FIRST # 1. MIN_IO_FIRST: the system will try to choose the same disk as tsFileToLoad for loading. # 2. DISK_STORAGE_BALANCE_FIRST: the system will make the disk choice that balance storage as much as possible. $ 3. INHERIT_LOAD: the system will use the same strategy as load_disk_select_strategy -# If this property is unset, system will use DISK_STORAGE_BALANCE_FIRST as default strategy because storage-balance is ensured with higher priority. +# If this property is unset, system will use INHERIT_LOAD as default strategy because storage-balance is ensured with higher priority. # effectiveMode: restart # Datatype: String -load_disk_select_strategy_for_pipe_and_iotv2=DISK_STORAGE_BALANCE_FIRST +load_disk_select_strategy_for_pipe_and_iotv2=INHERIT_LOAD # consensus dir # If this property is unset, system will save the data in the default relative path directory under the IoTDB folder(i.e., %IOTDB_HOME%/data/datanode). From 198ae9104b0c386eee031915ba9afde80559b9af Mon Sep 17 00:00:00 2001 From: Peng Junzhi <201250214@smail.nju.edu.cn> Date: Thu, 27 Mar 2025 11:38:29 +0800 Subject: [PATCH 13/15] spotless --- .../iotdb/db/storageengine/load/disk/MinIOSelector.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/disk/MinIOSelector.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/disk/MinIOSelector.java index 90e45193e382f..8bb81a6768fa4 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/disk/MinIOSelector.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/disk/MinIOSelector.java @@ -30,7 +30,11 @@ import java.io.File; import java.nio.file.FileStore; -import java.util.*; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; public class MinIOSelector extends StorageBalanceSelector { From f7b9e40793c137e5632184323f59a4ffa51bef08 Mon Sep 17 00:00:00 2001 From: Peng Junzhi <201250214@smail.nju.edu.cn> Date: Thu, 27 Mar 2025 14:35:38 +0800 Subject: [PATCH 14/15] fix review --- .../storageengine/dataregion/DataRegion.java | 18 ++++++++---------- .../load/disk/ILoadDiskSelector.java | 10 +++++----- ...heritSystemMultiDisksStrategySelector.java} | 5 +++-- .../storageengine/load/disk/MinIOSelector.java | 2 +- .../conf/iotdb-system.properties.template | 10 +++++----- 5 files changed, 22 insertions(+), 23 deletions(-) rename iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/disk/{StorageBalanceSelector.java => InheritSystemMultiDisksStrategySelector.java} (88%) diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/DataRegion.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/DataRegion.java index e0f3b6fe2c925..79af5140eeb12 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/DataRegion.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/DataRegion.java @@ -125,8 +125,8 @@ import org.apache.iotdb.db.storageengine.dataregion.wal.utils.listener.WALFlushListener; import org.apache.iotdb.db.storageengine.dataregion.wal.utils.listener.WALRecoverListener; import org.apache.iotdb.db.storageengine.load.disk.ILoadDiskSelector; +import org.apache.iotdb.db.storageengine.load.disk.InheritSystemMultiDisksStrategySelector; import org.apache.iotdb.db.storageengine.load.disk.MinIOSelector; -import org.apache.iotdb.db.storageengine.load.disk.StorageBalanceSelector; import org.apache.iotdb.db.storageengine.load.limiter.LoadTsFileRateLimiter; import org.apache.iotdb.db.storageengine.rescon.disk.TierManager; import org.apache.iotdb.db.storageengine.rescon.memory.SystemInfo; @@ -415,8 +415,8 @@ public DataRegion(String databaseName, String id) { private void initDiskSelector() { switch (ILoadDiskSelector.LoadDiskSelectorType.fromValue(config.getLoadDiskSelectStrategy())) { - case DISK_STORAGE_BALANCE_FIRST: - ordinaryLoadDiskSelector = new StorageBalanceSelector(); + case INHERIT_SYSTEM_MULTI_DISKS_SELECT_STRATEGY: + ordinaryLoadDiskSelector = new InheritSystemMultiDisksStrategySelector(); break; case MIN_IO_FIRST: default: @@ -428,8 +428,8 @@ private void initDiskSelector() { case MIN_IO_FIRST: pipeAndIoTV2LoadDiskSelector = new MinIOSelector(); break; - case DISK_STORAGE_BALANCE_FIRST: - pipeAndIoTV2LoadDiskSelector = new StorageBalanceSelector(); + case INHERIT_SYSTEM_MULTI_DISKS_SELECT_STRATEGY: + pipeAndIoTV2LoadDiskSelector = new InheritSystemMultiDisksStrategySelector(); break; case INHERIT_LOAD: default: @@ -3100,9 +3100,7 @@ private boolean loadTsFileToUnSequence( filePartitionId, tsFileResource.getTsFile().getName()); - // var used in lambda must be final - final File finalTargetFile = targetFile; - tsFileResource.setFile(finalTargetFile); + tsFileResource.setFile(targetFile); if (tsFileManager.contains(tsFileResource, false)) { logger.warn("The file {} has already been loaded in unsequence list", tsFileResource); return false; @@ -3123,13 +3121,13 @@ private boolean loadTsFileToUnSequence( if (deleteOriginFile) { RetryUtils.retryOnException( () -> { - FileUtils.moveFile(tsFileToLoad, finalTargetFile); + FileUtils.moveFile(tsFileToLoad, targetFile); return null; }); } else { RetryUtils.retryOnException( () -> { - Files.copy(tsFileToLoad.toPath(), finalTargetFile.toPath()); + Files.copy(tsFileToLoad.toPath(), targetFile.toPath()); return null; }); } diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/disk/ILoadDiskSelector.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/disk/ILoadDiskSelector.java index 95ba8aef04b1d..95b72bce196c0 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/disk/ILoadDiskSelector.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/disk/ILoadDiskSelector.java @@ -35,7 +35,7 @@ File getTargetFile( enum LoadDiskSelectorType { MIN_IO_FIRST("MIN_IO_FIRST"), - DISK_STORAGE_BALANCE_FIRST("DISK_STORAGE_BALANCE_FIRST"), + INHERIT_SYSTEM_MULTI_DISKS_SELECT_STRATEGY("INHERIT_SYSTEM_MULTI_DISKS_SELECT_STRATEGY"), // This type is specially designed for IoTV2 and Pipe, which means IoTV2 and Pipe will follow // the same strategy as ordinary load. INHERIT_LOAD("INHERIT_LOAD"); @@ -53,13 +53,13 @@ public String getValue() { public static LoadDiskSelectorType fromValue(String value) { if (value.equalsIgnoreCase(MIN_IO_FIRST.getValue())) { return MIN_IO_FIRST; - } else if (value.equalsIgnoreCase(DISK_STORAGE_BALANCE_FIRST.getValue())) { - return DISK_STORAGE_BALANCE_FIRST; + } else if (value.equalsIgnoreCase(INHERIT_SYSTEM_MULTI_DISKS_SELECT_STRATEGY.getValue())) { + return INHERIT_SYSTEM_MULTI_DISKS_SELECT_STRATEGY; } else if (value.equalsIgnoreCase(INHERIT_LOAD.getValue())) { return INHERIT_LOAD; } - // return DISK_STORAGE_BALANCE_FIRST by default - return DISK_STORAGE_BALANCE_FIRST; + // return MIN_IO_FIRST by default + return MIN_IO_FIRST; } } } diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/disk/StorageBalanceSelector.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/disk/InheritSystemMultiDisksStrategySelector.java similarity index 88% rename from iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/disk/StorageBalanceSelector.java rename to iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/disk/InheritSystemMultiDisksStrategySelector.java index 6929035ce6449..9f7fba9c0596f 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/disk/StorageBalanceSelector.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/disk/InheritSystemMultiDisksStrategySelector.java @@ -27,11 +27,11 @@ import java.io.File; -public class StorageBalanceSelector implements ILoadDiskSelector { +public class InheritSystemMultiDisksStrategySelector implements ILoadDiskSelector { protected final FSFactory fsFactory = FSFactoryProducer.getFSFactory(); - public StorageBalanceSelector() { + public InheritSystemMultiDisksStrategySelector() { // empty body } @@ -43,6 +43,7 @@ public File getTargetFile( long filePartitionId, String tsfileName) throws DiskSpaceInsufficientException { + // inherit system multi-disks select strategy, see configuration `dn_multi_dir_strategy` return fsFactory.getFile( TierManager.getInstance().getNextFolderForTsFile(0, false), databaseName diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/disk/MinIOSelector.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/disk/MinIOSelector.java index 8bb81a6768fa4..55af937b2b970 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/disk/MinIOSelector.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/disk/MinIOSelector.java @@ -36,7 +36,7 @@ import java.util.Objects; import java.util.Optional; -public class MinIOSelector extends StorageBalanceSelector { +public class MinIOSelector extends InheritSystemMultiDisksStrategySelector { private static final Logger logger = LoggerFactory.getLogger(MinIOSelector.class); private static final IoTDBConfig config = IoTDBDescriptor.getInstance().getConfig(); diff --git a/iotdb-core/node-commons/src/assembly/resources/conf/iotdb-system.properties.template b/iotdb-core/node-commons/src/assembly/resources/conf/iotdb-system.properties.template index 1e4e7a13aa9a0..4318cf128aa75 100644 --- a/iotdb-core/node-commons/src/assembly/resources/conf/iotdb-system.properties.template +++ b/iotdb-core/node-commons/src/assembly/resources/conf/iotdb-system.properties.template @@ -246,8 +246,8 @@ dn_multi_dir_strategy=SequenceStrategy # The strategy is used to choose a proper disk for loading tsfile. # The info of the two strategies are as follows: # 1. MIN_IO_FIRST: the system will try to choose the same disk as tsFileToLoad for loading. -# 2. DISK_STORAGE_BALANCE_FIRST: the system will make the disk choice that balance storage as much as possible. -# If this property is unset, system will use MIN_IO_FIRST as default strategy because storage-balance is ensured with higher priority. +# 2. INHERIT_SYSTEM_MULTI_DISKS_SELECT_STRATEGY: the system will choose one disk according to dn_multi_dir_strategy. +# If this property is unset, system will use MIN_IO_FIRST as default strategy. # effectiveMode: restart # Datatype: String load_disk_select_strategy=MIN_IO_FIRST @@ -256,9 +256,9 @@ load_disk_select_strategy=MIN_IO_FIRST # The strategy is used to choose a proper disk for loading tsfile. # The info of the three strategies are as follows: # 1. MIN_IO_FIRST: the system will try to choose the same disk as tsFileToLoad for loading. -# 2. DISK_STORAGE_BALANCE_FIRST: the system will make the disk choice that balance storage as much as possible. -$ 3. INHERIT_LOAD: the system will use the same strategy as load_disk_select_strategy -# If this property is unset, system will use INHERIT_LOAD as default strategy because storage-balance is ensured with higher priority. +# 2. INHERIT_SYSTEM_MULTI_DISKS_SELECT_STRATEGY: the system will choose one disk according to dn_multi_dir_strategy. +$ 3. INHERIT_LOAD: the system will use the same strategy as load_disk_select_strategy. +# If this property is unset, system will use INHERIT_LOAD as default strategy. # effectiveMode: restart # Datatype: String load_disk_select_strategy_for_pipe_and_iotv2=INHERIT_LOAD From 7195ebbeb1cdfc7540d0cda010789ca2d39c2d9e Mon Sep 17 00:00:00 2001 From: Peng Junzhi <201250214@smail.nju.edu.cn> Date: Thu, 27 Mar 2025 15:22:10 +0800 Subject: [PATCH 15/15] adopt to multi-layer storage --- .../iotdb/db/storageengine/dataregion/DataRegion.java | 7 +++++-- .../db/storageengine/load/disk/ILoadDiskSelector.java | 3 ++- .../load/disk/InheritSystemMultiDisksStrategySelector.java | 5 +++-- .../iotdb/db/storageengine/load/disk/MinIOSelector.java | 6 ++++-- 4 files changed, 14 insertions(+), 7 deletions(-) diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/DataRegion.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/DataRegion.java index 79af5140eeb12..a162e3ad1a200 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/DataRegion.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/DataRegion.java @@ -3085,6 +3085,7 @@ private boolean loadTsFileToUnSequence( final boolean deleteOriginFile, boolean isGeneratedByPipe) throws LoadFileException, DiskSpaceInsufficientException { + final int targetTierLevel = 0; final File targetFile = (tsFileResource.isGeneratedByPipeConsensus() || tsFileResource.isGeneratedByPipe()) ? pipeAndIoTV2LoadDiskSelector.getTargetFile( @@ -3092,13 +3093,15 @@ private boolean loadTsFileToUnSequence( databaseName, dataRegionId, filePartitionId, - tsFileResource.getTsFile().getName()) + tsFileResource.getTsFile().getName(), + targetTierLevel) : ordinaryLoadDiskSelector.getTargetFile( tsFileToLoad, databaseName, dataRegionId, filePartitionId, - tsFileResource.getTsFile().getName()); + tsFileResource.getTsFile().getName(), + targetTierLevel); tsFileResource.setFile(targetFile); if (tsFileManager.contains(tsFileResource, false)) { diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/disk/ILoadDiskSelector.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/disk/ILoadDiskSelector.java index 95b72bce196c0..b14f0c4b5df4b 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/disk/ILoadDiskSelector.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/disk/ILoadDiskSelector.java @@ -30,7 +30,8 @@ File getTargetFile( String databaseName, String dataRegionId, long filePartitionId, - String tsfileName) + String tsfileName, + int tierLevel) throws DiskSpaceInsufficientException; enum LoadDiskSelectorType { diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/disk/InheritSystemMultiDisksStrategySelector.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/disk/InheritSystemMultiDisksStrategySelector.java index 9f7fba9c0596f..16e420c5e2f72 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/disk/InheritSystemMultiDisksStrategySelector.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/disk/InheritSystemMultiDisksStrategySelector.java @@ -41,11 +41,12 @@ public File getTargetFile( String databaseName, String dataRegionId, long filePartitionId, - String tsfileName) + String tsfileName, + int tierLevel) throws DiskSpaceInsufficientException { // inherit system multi-disks select strategy, see configuration `dn_multi_dir_strategy` return fsFactory.getFile( - TierManager.getInstance().getNextFolderForTsFile(0, false), + TierManager.getInstance().getNextFolderForTsFile(tierLevel, false), databaseName + File.separatorChar + dataRegionId diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/disk/MinIOSelector.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/disk/MinIOSelector.java index 55af937b2b970..f6fac586700d8 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/disk/MinIOSelector.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/disk/MinIOSelector.java @@ -74,7 +74,8 @@ public File getTargetFile( String databaseName, String dataRegionId, long filePartitionId, - String tsfileName) + String tsfileName, + int tierLevel) throws DiskSpaceInsufficientException { File targetFile; String fileDirRoot = null; @@ -105,6 +106,7 @@ public File getTargetFile( } // if there isn't an overlap, downgrade to storage balance(sequence) strategy. - return super.getTargetFile(fileToLoad, databaseName, dataRegionId, filePartitionId, tsfileName); + return super.getTargetFile( + fileToLoad, databaseName, dataRegionId, filePartitionId, tsfileName, tierLevel); } }