This is an automated email from the ASF dual-hosted git repository.
smengcl pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ozone.git
The following commit(s) were added to refs/heads/master by this push:
new 07f069b72fc HDDS-16015. Make listStatusLight skip SCM pipeline
refresh. (#10894)
07f069b72fc is described below
commit 07f069b72fc8f2f2534d2ed75ae15ea0f2ee31d9
Author: Aryan Gupta <[email protected]>
AuthorDate: Wed Aug 12 01:33:30 2026 +0530
HDDS-16015. Make listStatusLight skip SCM pipeline refresh. (#10894)
---
.../hadoop/ozone/om/snapshot/OmSnapshotTests.java | 26 ++++++++++
.../org/apache/hadoop/ozone/om/KeyManager.java | 28 +++++++++++
.../org/apache/hadoop/ozone/om/KeyManagerImpl.java | 33 +++++++++----
.../apache/hadoop/ozone/om/OmMetadataReader.java | 37 +++++++++++++--
.../org/apache/hadoop/ozone/om/OmSnapshot.java | 32 +++++++++++--
.../org/apache/hadoop/ozone/om/OzoneManager.java | 11 ++---
.../apache/hadoop/ozone/om/TestKeyManagerUnit.java | 55 +++++++++++++++++++++-
7 files changed, 197 insertions(+), 25 deletions(-)
diff --git
a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/om/snapshot/OmSnapshotTests.java
b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/om/snapshot/OmSnapshotTests.java
index 40dd14d4469..fe8f4b24e7e 100644
---
a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/om/snapshot/OmSnapshotTests.java
+++
b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/om/snapshot/OmSnapshotTests.java
@@ -147,6 +147,7 @@
import org.apache.hadoop.ozone.om.helpers.OmKeyArgs;
import org.apache.hadoop.ozone.om.helpers.OmMultipartInfo;
import org.apache.hadoop.ozone.om.helpers.OzoneFileStatus;
+import org.apache.hadoop.ozone.om.helpers.OzoneFileStatusLight;
import org.apache.hadoop.ozone.om.helpers.SnapshotInfo;
import org.apache.hadoop.ozone.om.protocol.OzoneManagerProtocol;
import org.apache.hadoop.ozone.om.service.SnapshotDiffCleanupService;
@@ -531,6 +532,31 @@ public void checkKey() throws Exception {
snapshotKeyPrefix + key1);
}
+ @Test
+ public void testSnapshotListStatusLightReturnsDenormalizedKeyName()
+ throws Exception {
+ String key = "light-list/" + "key-" + counter.incrementAndGet();
+ createFileKey(ozoneBucket, key);
+
+ String snapshotName = "snap-light-" + counter.incrementAndGet();
+ String snapshotKeyPrefix = createSnapshot(volumeName, bucketName,
+ snapshotName);
+ String snapshotKey = snapshotKeyPrefix + key;
+
+ OmKeyArgs keyArgs = genKeyArgs(snapshotKey);
+
+ List<OzoneFileStatus> fullStatuses =
+ writeClient.listStatus(keyArgs, false, "", 1, false);
+ List<OzoneFileStatusLight> lightStatuses =
+ writeClient.listStatusLight(keyArgs, false, "", 1, false);
+
+ assertEquals(1, fullStatuses.size());
+ assertEquals(1, lightStatuses.size());
+
+ assertEquals(snapshotKey, fullStatuses.get(0).getKeyInfo().getKeyName());
+ assertEquals(snapshotKey, lightStatuses.get(0).getKeyInfo().getKeyName());
+ }
+
@Test
public void testListDeleteKey() throws Exception {
String volume = "vol-" + counter.incrementAndGet();
diff --git
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/KeyManager.java
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/KeyManager.java
index 4077ee088ef..2c959cb4c01 100644
---
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/KeyManager.java
+++
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/KeyManager.java
@@ -38,6 +38,7 @@
import org.apache.hadoop.ozone.om.helpers.OmKeyInfo;
import org.apache.hadoop.ozone.om.helpers.OmMultipartUploadList;
import org.apache.hadoop.ozone.om.helpers.OmMultipartUploadListParts;
+import org.apache.hadoop.ozone.om.helpers.OzoneFileStatus;
import org.apache.hadoop.ozone.om.helpers.RepeatedOmKeyInfo;
import org.apache.hadoop.ozone.om.service.CompactionService;
import org.apache.hadoop.ozone.om.service.DirectoryDeletingService;
@@ -90,6 +91,33 @@ OmKeyInfo lookupKey(OmKeyArgs args, ResolvedBucket
bucketLayout,
OmKeyInfo getKeyInfo(OmKeyArgs args, ResolvedBucket buctket,
String clientAddress) throws IOException;
+ /**
+ * List the status for a file or a directory and its contents.
+ * Optionally skips pipeline refresh for callers that only need metadata.
+ *
+ * @param args Key args
+ * @param recursive For a directory if true all the descendants of a
+ * particular directory are listed
+ * @param startKey Key from which listing needs to start. If startKey
exists
+ * its status is included in the final list.
+ * @param numEntries Number of entries to list from the start key
+ * @param clientAddress a hint to key manager, order the datanode in returned
+ * pipeline by distance between client and datanode.
+ * @param allowPartialPrefixes if partial prefixes should be allowed,
+ * this is needed in context of ListKeys
+ * @param refreshPipelineInfo if true, update pipeline location information
+ * using SCM-backed cache; if false, skip it
+ * @return list of file status
+ * @throws IOException if file or bucket or volume does not exist
+ */
+ default List<OzoneFileStatus> listStatus(OmKeyArgs args, boolean recursive,
+ String startKey, long numEntries, String clientAddress,
+ boolean allowPartialPrefixes, boolean refreshPipelineInfo)
+ throws IOException {
+ return listStatus(args, recursive, startKey, numEntries, clientAddress,
+ allowPartialPrefixes);
+ }
+
/**
* Returns a list of keys represented by {@link OmKeyInfo}
* in the given bucket.
diff --git
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/KeyManagerImpl.java
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/KeyManagerImpl.java
index f24a5c470fb..40ca7c3002a 100644
---
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/KeyManagerImpl.java
+++
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/KeyManagerImpl.java
@@ -1979,6 +1979,16 @@ public List<OzoneFileStatus> listStatus(OmKeyArgs args,
boolean recursive,
public List<OzoneFileStatus> listStatus(OmKeyArgs args, boolean recursive,
String startKey, long numEntries, String clientAddress,
boolean allowPartialPrefixes) throws IOException {
+ return listStatus(args, recursive, startKey, numEntries, clientAddress,
+ allowPartialPrefixes, true);
+ }
+
+ @Override
+ @SuppressWarnings("methodlength")
+ public List<OzoneFileStatus> listStatus(OmKeyArgs args, boolean recursive,
+ String startKey, long numEntries, String clientAddress,
+ boolean allowPartialPrefixes, boolean refreshPipelineInfo)
+ throws IOException {
Objects.requireNonNull(args, "Key args can not be null");
String volumeName = args.getVolumeName();
String bucketName = args.getBucketName();
@@ -1997,7 +2007,8 @@ public List<OzoneFileStatus> listStatus(OmKeyArgs args,
boolean recursive,
Collection<OzoneFileStatus> statuses =
statusHelper.listStatusFSO(args, startKey, numEntries,
clientAddress, allowPartialPrefixes);
- return buildFinalStatusList(statuses, args, clientAddress);
+ return buildFinalStatusList(statuses, args, clientAddress,
+ refreshPipelineInfo);
}
// A map sorted by OmKey to combine results from TableCache and DB.
@@ -2065,7 +2076,9 @@ public List<OzoneFileStatus> listStatus(OmKeyArgs args,
boolean recursive,
slimLocationVersion(keyInfoList.toArray(new OmKeyInfo[0]));
}
- refreshPipelineFromCache(keyInfoList);
+ if (refreshPipelineInfo) {
+ refreshPipelineFromCache(keyInfoList);
+ }
if (args.getSortDatanodes()) {
sortDatanodes(clientAddress, keyInfoList);
@@ -2169,7 +2182,7 @@ private void findKeyInDbWithIterator(boolean recursive,
String startKey,
private List<OzoneFileStatus> buildFinalStatusList(
Collection<OzoneFileStatus> statusesCollection, OmKeyArgs omKeyArgs,
- String clientAddress)
+ String clientAddress, boolean refreshPipelineInfo)
throws IOException {
List<OzoneFileStatus> fileStatusFinalList = new ArrayList<>();
List<OmKeyInfo> keyInfoList = new ArrayList<>();
@@ -2181,19 +2194,21 @@ private List<OzoneFileStatus> buildFinalStatusList(
fileStatusFinalList.add(fileStatus);
}
return sortPipelineInfo(fileStatusFinalList, keyInfoList,
- omKeyArgs, clientAddress);
+ omKeyArgs, clientAddress, refreshPipelineInfo);
}
private List<OzoneFileStatus> sortPipelineInfo(
List<OzoneFileStatus> fileStatusFinalList, List<OmKeyInfo> keyInfoList,
- OmKeyArgs omKeyArgs, String clientAddress) throws IOException {
+ OmKeyArgs omKeyArgs, String clientAddress, boolean refreshPipelineInfo)
+ throws IOException {
if (omKeyArgs.getLatestVersionLocation()) {
slimLocationVersion(keyInfoList.toArray(new OmKeyInfo[0]));
}
- // refreshPipeline flag check has been removed as part of
- // https://issues.apache.org/jira/browse/HDDS-3658.
- // Please refer this jira for more details.
- refreshPipelineFromCache(keyInfoList);
+ if (refreshPipelineInfo) {
+ // listStatusLight callers set this flag to false so that lightweight
+ // listings remain metadata-only and avoid SCM-backed pipeline refresh.
+ refreshPipelineFromCache(keyInfoList);
+ }
if (omKeyArgs.getSortDatanodes()) {
sortDatanodes(clientAddress, keyInfoList);
diff --git
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OmMetadataReader.java
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OmMetadataReader.java
index 64f46089c06..7df37759d1e 100644
---
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OmMetadataReader.java
+++
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OmMetadataReader.java
@@ -259,12 +259,39 @@ public List<OzoneFileStatus> listStatus(OmKeyArgs args,
boolean recursive,
public List<OzoneFileStatusLight> listStatusLight(OmKeyArgs args,
boolean recursive, String startKey, long numEntries,
boolean allowPartialPrefixes) throws IOException {
- List<OzoneFileStatus> ozoneFileStatuses =
- listStatus(args, recursive, startKey, numEntries,
allowPartialPrefixes);
+ long maxListingPageSize = ozoneManager.getConfiguration().getInt(
+ OZONE_FS_LISTING_PAGE_SIZE_MAX,
+ OZONE_FS_LISTING_PAGE_SIZE_DEFAULT);
+ maxListingPageSize = OzoneConfigUtil.limitValue(numEntries,
+ OZONE_FS_LISTING_PAGE_SIZE, OZONE_FS_LISTING_PAGE_SIZE_MAX,
+ maxListingPageSize);
+
+ ResolvedBucket bucket = ozoneManager.resolveBucketLink(args);
+ Map<String, String> auditMap = bucket.audit(args.toAuditMap());
+ OmKeyArgs resolvedArgs = bucket.update(args);
- return ozoneFileStatuses.stream()
- .map(OzoneFileStatusLight::fromOzoneFileStatus)
- .collect(Collectors.toList());
+ try {
+ if (isAclEnabled) {
+ checkAcls(getResourceType(resolvedArgs), StoreType.OZONE, ACLType.READ,
+ bucket, resolvedArgs.getKeyName());
+ }
+ metrics.incNumListStatus();
+ List<OzoneFileStatus> ozoneFileStatuses = keyManager.listStatus(
+ resolvedArgs, recursive,
+ startKey, maxListingPageSize, getClientAddress(),
+ allowPartialPrefixes, false);
+ List<OzoneFileStatusLight> lightStatuses = ozoneFileStatuses.stream()
+ .map(OzoneFileStatusLight::fromOzoneFileStatus)
+ .collect(Collectors.toList());
+ audit.logReadSuccess(buildAuditMessageForSuccess(
+ OMAction.LIST_STATUS, auditMap));
+ return lightStatuses;
+ } catch (Exception ex) {
+ metrics.incNumListStatusFails();
+ audit.logReadFailure(buildAuditMessageForFailure(OMAction.LIST_STATUS,
+ auditMap, ex));
+ throw ex;
+ }
}
@Override
diff --git
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OmSnapshot.java
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OmSnapshot.java
index 5147eafe628..6d3a56f40ed 100644
---
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OmSnapshot.java
+++
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OmSnapshot.java
@@ -133,12 +133,13 @@ recursive, normalizeKeyName(startKey), numEntries,
public List<OzoneFileStatusLight> listStatusLight(OmKeyArgs args,
boolean recursive, String startKey, long numEntries,
boolean allowPartialPrefixes) throws IOException {
-
- List<OzoneFileStatus> ozoneFileStatuses =
- listStatus(args, recursive, startKey, numEntries,
allowPartialPrefixes);
+ List<OzoneFileStatusLight> ozoneFileStatuses = omMetadataReader
+ .listStatusLight(normalizeOmKeyArgs(args),
+ recursive, normalizeKeyName(startKey), numEntries,
+ allowPartialPrefixes);
return ozoneFileStatuses.stream()
- .map(OzoneFileStatusLight::fromOzoneFileStatus)
+ .map(this::denormalizeOzoneFileStatusLight)
.collect(Collectors.toList());
}
@@ -285,6 +286,29 @@ private OzoneFileStatus denormalizeOzoneFileStatus(
omKeyInfo, fileStatus.getBlockSize(), fileStatus.isDirectory());
}
+ private OzoneFileStatusLight denormalizeOzoneFileStatusLight(
+ OzoneFileStatusLight fileStatus) {
+ if (fileStatus == null || fileStatus.getKeyInfo() == null) {
+ return fileStatus;
+ }
+ BasicOmKeyInfo keyInfo = fileStatus.getKeyInfo();
+ BasicOmKeyInfo denormalized = new BasicOmKeyInfo.Builder()
+ .setVolumeName(keyInfo.getVolumeName())
+ .setBucketName(keyInfo.getBucketName())
+ .setKeyName(denormalizeKeyName(keyInfo.getKeyName()))
+ .setDataSize(keyInfo.getDataSize())
+ .setCreationTime(keyInfo.getCreationTime())
+ .setModificationTime(keyInfo.getModificationTime())
+ .setReplicationConfig(keyInfo.getReplicationConfig())
+ .setIsFile(keyInfo.isFile())
+ .setETag(keyInfo.getETag())
+ .setOwnerName(keyInfo.getOwnerName())
+ .setIsEncrypted(keyInfo.isEncrypted())
+ .build();
+ return new OzoneFileStatusLight(
+ denormalized, fileStatus.getBlockSize(), fileStatus.isDirectory());
+ }
+
private KeyInfoWithVolumeContext denormalizeKeyInfoWithVolumeContext(
KeyInfoWithVolumeContext k) {
return new KeyInfoWithVolumeContext.Builder()
diff --git
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OzoneManager.java
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OzoneManager.java
index 225ddeb6c90..e1682e1a048 100644
---
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OzoneManager.java
+++
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OzoneManager.java
@@ -4177,12 +4177,11 @@ public List<OzoneFileStatus> listStatus(OmKeyArgs args,
boolean recursive,
public List<OzoneFileStatusLight> listStatusLight(OmKeyArgs args,
boolean recursive, String startKey, long numEntries,
boolean allowPartialPrefixes) throws IOException {
- List<OzoneFileStatus> ozoneFileStatuses =
- listStatus(args, recursive, startKey, numEntries,
allowPartialPrefixes);
-
- return ozoneFileStatuses.stream()
- .map(OzoneFileStatusLight::fromOzoneFileStatus)
- .collect(Collectors.toList());
+ try (UncheckedAutoCloseableSupplier<IOmMetadataReader> rcReader =
+ getReader(args)) {
+ return rcReader.get().listStatusLight(
+ args, recursive, startKey, numEntries, allowPartialPrefixes);
+ }
}
/**
diff --git
a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/TestKeyManagerUnit.java
b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/TestKeyManagerUnit.java
index be307c06f95..e7df8077cc3 100644
---
a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/TestKeyManagerUnit.java
+++
b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/TestKeyManagerUnit.java
@@ -79,12 +79,14 @@
import org.apache.hadoop.ozone.om.helpers.OmVolumeArgs;
import org.apache.hadoop.ozone.om.helpers.OpenKeySession;
import org.apache.hadoop.ozone.om.helpers.OzoneFileStatus;
+import org.apache.hadoop.ozone.om.helpers.OzoneFileStatusLight;
import org.apache.hadoop.ozone.om.protocol.OzoneManagerProtocol;
import org.apache.hadoop.ozone.om.request.OMRequestTestUtils;
import org.apache.hadoop.security.UserGroupInformation;
import org.apache.hadoop.util.Time;
import org.apache.ozone.test.OzoneTestBase;
import org.apache.ratis.util.ExitUtils;
+import org.apache.ratis.util.function.UncheckedAutoCloseableSupplier;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
@@ -510,7 +512,7 @@ public void testGetKeyInfo() throws IOException {
.build();
ContainerInfo ci = mock(ContainerInfo.class);
- when(ci.getContainerID()).thenReturn(1L);
+ when(ci.getContainerID()).thenReturn(containerID);
// Setup SCM containerClient so that 1st call returns pipeline1 and
// 2nd call returns pipeline2.
@@ -766,4 +768,55 @@ public void listStatus() throws Exception {
null, Long.MAX_VALUE, client);
verify(containerClient, times(1)).getContainerWithPipelineBatch(anySet());
}
+
+ @Test
+ public void listStatusLightDoesNotRefreshPipeline() throws Exception {
+ String volume = volumeName();
+ String bucket = "bucket-light";
+ String keyPrefix = "key-light-";
+
+ OMRequestTestUtils.addVolumeToDB(volume, OzoneConsts.OZONE,
metadataManager);
+ OMRequestTestUtils.addBucketToDB(volume, bucket, metadataManager);
+
+ final Pipeline pipeline = MockPipeline.createPipeline(3);
+ for (long i = 1; i <= 5; i++) {
+ final long containerID = CONTAINER_ID.incrementAndGet();
+ final OmKeyLocationInfo keyLocationInfo = new OmKeyLocationInfo.Builder()
+ .setBlockID(new BlockID(containerID, 1L))
+ .setPipeline(pipeline)
+ .setOffset(0)
+ .setLength(1024)
+ .build();
+
+ OmKeyInfo keyInfo = new OmKeyInfo.Builder()
+ .setVolumeName(volume)
+ .setBucketName(bucket)
+ .setCreationTime(Time.now())
+ .setOmKeyLocationInfos(singletonList(
+ new OmKeyLocationInfoGroup(0, new ArrayList<>())))
+ .setReplicationConfig(RatisReplicationConfig
+ .getInstance(ReplicationFactor.THREE))
+ .setKeyName(keyPrefix + i)
+ .setObjectID(i)
+ .setUpdateID(i)
+ .build();
+ keyInfo.appendNewBlocks(singletonList(keyLocationInfo), false);
+ OMRequestTestUtils.addKeyToOM(metadataManager, keyInfo);
+ }
+
+ OmKeyArgs.Builder builder = new OmKeyArgs.Builder()
+ .setVolumeName(volume)
+ .setBucketName(bucket)
+ .setKeyName("");
+
+ List<OzoneFileStatusLight> fileStatusList;
+ try (UncheckedAutoCloseableSupplier<IOmMetadataReader> rcReader =
+ om.getOmMetadataReader()) {
+ fileStatusList = rcReader.get().listStatusLight(builder.build(), false,
+ null, Long.MAX_VALUE, false);
+ }
+
+ assertEquals(5, fileStatusList.size());
+ verify(containerClient, times(0)).getContainerWithPipelineBatch(anySet());
+ }
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]