HDDS-15925. Remove redundant InfoBucket RPC from OFS getFileStatus by validating bucket layout server-side - #11226
HDDS-15925. Remove redundant InfoBucket RPC from OFS getFileStatus by validating bucket layout server-side#11226yandrey321 wants to merge 4 commits into
Conversation
|
@jojochuang please check this PR based on #10792, we need to decide if we want to go with server side approach vs client side cache: #11176 |
Thanks for including that detail here. I think this would need a version gate, and it should be fairly simple. The client is already aware of the server version as it gets it on the first RPC / handshake so we can just do: I haven't been involved in this and I haven't looked at the code here beyond the description, but I would tend to prefer a solution that doesn't have a client side cache, as caching always proves more tricky than it first seems! |
implemented version check on the client side. |
What changes were proposed in this pull request?
OFS
getFileStatuson a non-snapshot path used to issue two OM RPCs per call:an
InfoBucketRPC (only so the client could read the bucket layout and rejectOBJECT_STORE buckets, which have no file system semantics) followed by the actual
getFileStatusRPC. On a namespace-walk / listing-heavy workload this doubles theOM read-RPC volume for no functional gain.
This PR removes the redundant
InfoBucketRPC by moving the layout check to wherethe authoritative bucket metadata already lives — the OM:
BasicRootedOzoneClientAdapterImpl) — the non-snapshotgetFileStatuspath now calls
proxy.getOzoneFileStatus(...)directly instead of first fetchingthe bucket. Mutating OFS operations still resolve and validate layout through
getBucket(...), and snapshot paths are unchanged.OmMetadataReader.getFileStatus) — validates the bucket layout andrejects OBJECT_STORE buckets. The
IllegalArgumentExceptionfromOzoneFSUtils.validateBucketLayoutis wrapped asOMException(NOT_SUPPORTED_OPERATION)so it is returned as a normal(non-retryable) RPC response instead of escaping the read handler's
IOExceptioncatch and triggering a client-side retry storm.
NOT_SUPPORTED_OPERATIONthe adapter re-throwsIllegalArgumentException(preserving the pre-existing OFS behavior and message),keyed on the
ResultCoderather than on the message text so the two sides are notcoupled through a string.
negotiated OM version is new enough to perform the server-side check; against an
older OM the client falls back to the pre-HDDS-15925 path (see the compatibility
note below).
getTrashRootsskips OBJECT_STORE buckets —getTrashRoots(allUsers=true)iterates every volume/bucket and probes each bucket's trash path with
exists().OBJECT_STORE buckets have no file system semantics (hence no trash root), and
getFileStatuson them now surfacesIllegalArgumentException, whichexists()does not swallow and which would abort the whole scan. The scan now skips
OBJECT_STORE buckets up front (reusing the
OzoneBucketalready listed, no extraRPC). This also hardens the trash emptier against clusters that contain OBS
buckets, which previously could throw out of
getTrashRoots.No protobuf/wire change: RPC signatures and the
GetFileStatusmessages areunchanged, and
NOT_SUPPORTED_OPERATIONis a pre-existing result code.Compatibility note
The OBS-rejection check moves from the client to the OM. In a rolling upgrade, a
new OFS client talking to an old OM would otherwise stop rejecting
getFileStatuson an OBJECT_STORE bucket, because the old OM has no server-sidecheck and the new client no longer performs the
InfoBucket-based one.This is now handled with a version gate on the already-negotiated OM version:
OzoneManagerVersion.GET_FILE_STATUS_REJECTS_OBSmarks the server versionthat performs the OBS rejection. This is an additive Java enum constant carried
over the existing
OMVersionint inServiceInfo— no protobuf/wire change;unknown values still map to
FUTURE_VERSION.ClientProtocol.getOmVersion()exposes the negotiated version (in HA this is theminimum across all OMs, so a single old OM forces the safe path), implemented
by
RpcClientfrom the version it already captures during handshake.BasicRootedOzoneClientAdapterImpl.getFileStatusForKeyOrSnapshotgates on it:when the OM is
>= GET_FILE_STATUS_REJECTS_OBSit issues the directgetOzoneFileStatuscall and relies on the server-side rejection; otherwise itfalls back to fetching the bucket and validating its layout client-side — the
exact pre-HDDS-15925 behavior, including rejecting OBS with
IllegalArgumentException.New-client/new-OM takes the optimized single-RPC path; new-client/old-OM keeps the
old two-RPC behavior with the client-side check; old-client/* is unaffected.
Generated-by: Claude Code (Claude Opus 4.8)
What is the link to the Apache JIRA
https://issues.apache.org/jira/browse/HDDS-15925
How was this patch tested?
clean CI run: https://github.com/yandrey321/ozone/actions/runs/34513864283
TestOMMetadataReader(server-side rejection returnsOMException(NOT_SUPPORTED_OPERATION),keyManager.getFileStatusnot called forOBS),
TestBasicRootedOzoneClientAdapterHeadOp(8/8).TestOFS#testGetFileStatusRejectsObsBucket— verifies OBSgetFileStatusis rejected over RPC asIllegalArgumentExceptionwith 0InfoBucket RPCs; the OFS getFileStatus suite in
AbstractRootedOzoneFileSystemTest.TestOfsGetFileStatusCacheBenchmark(taggedbenchmark), numbers above.checkstyle.shclean; affected modules build.Benchmark
Measured with
TestOfsGetFileStatusCacheBenchmark(200 buckets × 10 accesses =2000 getFileStatus calls), same base and machine, against baseline and the
client-side cache alternative (PR #11176):
The
getFileStatusRPC count is identical everywhere — the change removes only theredundant
InfoBucketRPC. This PR removes it entirely (0), giving the lowest RPCcount and the best latency tail with no client-side cache state or new config.