HDDS-13798. Implement PoolBasedHierarchicalResourceLockManager for Hierarchical Resource#9160
HDDS-13798. Implement PoolBasedHierarchicalResourceLockManager for Hierarchical Resource#9160jojochuang merged 13 commits intoapache:masterfrom
Conversation
… hierarchical resource locking Change-Id: I433a52feb491b72ea303fa32025540a742555d08
Change-Id: I545cb5fa8ab7a2e2fb902b3559cbf2f48f84ad59
Change-Id: I5ffd4cff6028b50c8d75ea9b3885c1e9818fe968
…erarchical Resource Change-Id: Iabeb0c8a90500ed9f6a57e232470d20f7c7251bf
Change-Id: I9cfe0a545a5d4565b6a5e6fb94ea86f29d0f23ad
Change-Id: I3a88ac8556dc0238e67978944d7800bfb28ff41b
Change-Id: I4900bb92e6ccc3f728f4c61261c7accc7a8d4043
Change-Id: I6953c4f0fab1b0b54e1b4f1fce69025fdd424ac9
Change-Id: I31407994bb2d717f22977730b8b33ebc6eb33eea
Change-Id: I8b0d1657f809bf79cc5c5a64b336b7c6689aee91
There was a problem hiding this comment.
Pull Request Overview
This PR implements a new pool-based hierarchical resource lock manager for Ozone Manager that enables deterministic lock ordering for hierarchical resources, primarily for chain locking during snapshot operations and FSO path locking.
Key changes:
- Introduces
PoolBasedHierarchicalResourceLockManagerusing Apache Commons Pool2 for reusable ReadWriteLock instances - Adds
ReadOnlyHierarchicalResourceLockManagerfor read-only scenarios - Integrates the hierarchical lock manager into the OM metadata manager infrastructure
Reviewed Changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 9 comments.
Show a summary per file
| File | Description |
|---|---|
PoolBasedHierarchicalResourceLockManager.java |
Core implementation using object pooling and ConcurrentHashMap for hierarchical resource locking |
ReadOnlyHierarchicalResourceLockManager.java |
Read-only implementation that returns no-op locks |
TestPoolBasedHierarchicalResourceLockManager.java |
Comprehensive test suite covering basic operations, concurrency, and stress scenarios |
OmMetadataManagerImpl.java |
Integration of hierarchical lock manager into OM metadata management |
OMMetadataManager.java |
Interface addition for hierarchical lock manager access |
OMConfigKeys.java |
Configuration constants for pool size limits |
ozone-default.xml |
Default configuration values for lock pool parameters |
pom.xml |
Added commons-pool2 dependency |
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
| private static final HierarchicalResourceLock EMPTY_LOCK_NOT_ACQUIRED = new HierarchicalResourceLock() { | ||
| @Override | ||
| public boolean isLockAcquired() { | ||
| return true; |
There was a problem hiding this comment.
The EMPTY_LOCK_NOT_ACQUIRED constant incorrectly returns true for isLockAcquired(). This should return false to indicate the lock was not acquired, which is consistent with its name and usage context for write locks in read-only scenarios.
| return true; | |
| return false; |
| import org.apache.hadoop.ozone.om.helpers.OmVolumeArgs; | ||
| import org.apache.hadoop.ozone.om.helpers.RepeatedOmKeyInfo; | ||
| import org.apache.hadoop.ozone.om.helpers.SnapshotInfo; | ||
| import org.apache.hadoop.ozone.om.lock.HierachicalResourceLockManager; |
There was a problem hiding this comment.
Corrected spelling of 'Hierachical' to 'Hierarchical'."
| /** | ||
| * Returns the Hierarchical ResourceLock used on Metadata DB. | ||
| */ | ||
| HierachicalResourceLockManager getHierarchicalLockManager(); |
There was a problem hiding this comment.
Corrected spelling of 'HierachicalResourceLockManager' to 'HierarchicalResourceLockManager'."
| import org.apache.hadoop.ozone.om.helpers.S3SecretValue; | ||
| import org.apache.hadoop.ozone.om.helpers.SnapshotInfo; | ||
| import org.apache.hadoop.ozone.om.helpers.WithMetadata; | ||
| import org.apache.hadoop.ozone.om.lock.HierachicalResourceLockManager; |
There was a problem hiding this comment.
Corrected spelling of 'HierachicalResourceLockManager' to 'HierarchicalResourceLockManager'."
| private DBStore store; | ||
|
|
||
| private final IOzoneManagerLock lock; | ||
| private final HierachicalResourceLockManager hierarchicalLockManager; |
There was a problem hiding this comment.
Corrected spelling of 'HierachicalResourceLockManager' to 'HierarchicalResourceLockManager'."
| } | ||
|
|
||
| @Override | ||
| public HierachicalResourceLockManager getHierarchicalLockManager() { |
There was a problem hiding this comment.
Corrected spelling of 'HierachicalResourceLockManager' to 'HierarchicalResourceLockManager'."
| * lock dependencies, and is typically useful for structures like | ||
| * DAGs (e.g., File System trees or snapshot chains). | ||
| */ | ||
| public class PoolBasedHierarchicalResourceLockManager implements HierachicalResourceLockManager { |
There was a problem hiding this comment.
Corrected spelling of 'HierachicalResourceLockManager' to 'HierarchicalResourceLockManager'."
| public class PoolBasedHierarchicalResourceLockManager implements HierachicalResourceLockManager { | |
| public class PoolBasedHierarchicalResourceLockManager implements HierarchicalResourceLockManager { |
| /** | ||
| * A read only lock manager that does not acquire any lock. | ||
| */ | ||
| public class ReadOnlyHierarchicalResourceLockManager implements HierachicalResourceLockManager { |
There was a problem hiding this comment.
Corrected spelling of 'HierachicalResourceLockManager' to 'HierarchicalResourceLockManager'."
| public class ReadOnlyHierarchicalResourceLockManager implements HierachicalResourceLockManager { | |
| public class ReadOnlyHierarchicalResourceLockManager implements HierarchicalResourceLockManager { |
| import java.util.concurrent.atomic.AtomicInteger; | ||
| import java.util.concurrent.atomic.AtomicReference; | ||
| import org.apache.hadoop.hdds.conf.OzoneConfiguration; | ||
| import org.apache.hadoop.ozone.om.lock.HierachicalResourceLockManager.HierarchicalResourceLock; |
There was a problem hiding this comment.
Corrected spelling of 'HierachicalResourceLockManager' to 'HierarchicalResourceLockManager'."
| import org.apache.hadoop.ozone.om.lock.HierachicalResourceLockManager.HierarchicalResourceLock; | |
| import org.apache.hadoop.ozone.om.lock.HierarchicalResourceLockManager.HierarchicalResourceLock; |
| /** | ||
| * Test different resource types can be locked independently. | ||
| */ | ||
| @ParameterizedTest | ||
| @EnumSource(FlatResource.class) | ||
| public void testDifferentResourceTypes(FlatResource resource) throws Exception { | ||
| String key = "test-key-" + resource.name(); | ||
|
|
||
| try (HierarchicalResourceLock lock = lockManager.acquireWriteLock(resource, key)) { | ||
| assertNotNull(lock); | ||
| assertTrue(lock.isLockAcquired()); | ||
| } | ||
| } |
There was a problem hiding this comment.
this test doesn't seem to do what it supposed to do.
Instead, it should verify:
try (HierarchicalResourceLock lock = lockManager.acquireWriteLock(SNAPSHOT_GC_LOCK, key)) {
assertNotNull(lock);
assertTrue(lock.isLockAcquired());
try (HierarchicalResourceLock lock2 = lockManager.acquireWriteLock(SNAPSHOT_DB_LOCK, key)) {
assertNotNull(lock2);
assertTrue(lock2.isLockAcquired());
}
}
so that it ensures the two locks can be held independently at the same time.
| } | ||
|
|
||
| /** | ||
| * Test configuration parameters are respected. |
There was a problem hiding this comment.
the test implementation itself does not ensure soft limit and hard limit are respected, only that a HierarchicalResourceLock is acquired without exceptions.
There was a problem hiding this comment.
Done updated the tests
| private static final HierarchicalResourceLock EMPTY_LOCK_NOT_ACQUIRED = new HierarchicalResourceLock() { | ||
| @Override | ||
| public boolean isLockAcquired() { | ||
| return true; |
There was a problem hiding this comment.
Nice catch. yeah this was a typo. Fixed it
| import java.io.IOException; | ||
|
|
||
| /** | ||
| * A read only lock manager that does not acquire any lock. |
There was a problem hiding this comment.
i'm curious how this is going to be used because it looks basically like a no-op
There was a problem hiding this comment.
Yeah this would be used when opening checkpoint metadata managers similar to OmReadOnlyLocks. Eventually we might want to use the HierarchicalLock for FSO kinda use case so created this along the same lines to OzoneManagerLock
Change-Id: I39115b2cb142fd36e370c8c5e72d6e58ce1ffb3a
Change-Id: Ie4b4b50c28aa5c62eeae51feec99304fec4b079e
Change-Id: I4625b940c0fd242897d2e1a3ae299c001588be1b
jojochuang
left a comment
There was a problem hiding this comment.
LGTM merge to unblock the rest.
|
@kerneltime @sumitagrawl @errose28 This can be used for FSO locking usecase for path resolution. We are planning to use this thing similarly #9140 for acquiring read locks on specific snapshot while iterating through the chain. |
What changes were proposed in this pull request?
Have PoolBasedHierarchicalResourceLockManager which would implement the class
HierachicalResourceLockManager backed by generic object pool and ConcurrentHashMap enabling acquiring read write locks on resources with a deterministic order which is not possible with a stripe based locking.
This is required for acquiring locks on chain while iterating through the snapshot chain.
FYI this can be reused for FSO path locking while path resolution.(OM leader execution charter)
What is the link to the Apache JIRA
https://issues.apache.org/jira/browse/HDDS-13798
How was this patch tested?
Added unit test