Skip to content

Commit fbc3c1b

Browse files
HDDS-2244. Use new ReadWrite lock in OzoneManager.
1 parent f209722 commit fbc3c1b

28 files changed

+229
-122
lines changed

hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/lock/OzoneManagerLock.java

Lines changed: 103 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@
2121

2222
import java.util.ArrayList;
2323
import java.util.List;
24+
import java.util.function.Consumer;
2425

26+
import org.apache.hadoop.ozone.lock.ActiveLock;
2527
import org.slf4j.Logger;
2628
import org.slf4j.LoggerFactory;
2729

@@ -75,6 +77,9 @@ public class OzoneManagerLock {
7577
private static final Logger LOG =
7678
LoggerFactory.getLogger(OzoneManagerLock.class);
7779

80+
private static final String READ_LOCK = "read";
81+
private static final String WRITE_LOCK = "write";
82+
7883
private final LockManager<String> manager;
7984
private final ThreadLocal<Short> lockSet = ThreadLocal.withInitial(
8085
() -> Short.valueOf((short)0));
@@ -105,15 +110,66 @@ public OzoneManagerLock(Configuration conf) {
105110
* should be bucket name. For remaining all resource only one param should
106111
* be passed.
107112
*/
113+
@Deprecated
108114
public boolean acquireLock(Resource resource, String... resources) {
109115
String resourceName = generateResourceName(resource, resources);
116+
return lock(resource, resourceName, manager::writeLock, WRITE_LOCK);
117+
}
118+
119+
/**
120+
* Acquire read lock on resource.
121+
*
122+
* For S3_BUCKET_LOCK, VOLUME_LOCK, BUCKET_LOCK type resource, same
123+
* thread acquiring lock again is allowed.
124+
*
125+
* For USER_LOCK, PREFIX_LOCK, S3_SECRET_LOCK type resource, same thread
126+
* acquiring lock again is not allowed.
127+
*
128+
* Special Note for USER_LOCK: Single thread can acquire single user lock/
129+
* multi user lock. But not both at the same time.
130+
* @param resource - Type of the resource.
131+
* @param resources - Resource names on which user want to acquire lock.
132+
* For Resource type BUCKET_LOCK, first param should be volume, second param
133+
* should be bucket name. For remaining all resource only one param should
134+
* be passed.
135+
*/
136+
public boolean acquireReadLock(Resource resource, String... resources) {
137+
String resourceName = generateResourceName(resource, resources);
138+
return lock(resource, resourceName, manager::readLock, READ_LOCK);
139+
}
140+
141+
142+
/**
143+
* Acquire write lock on resource.
144+
*
145+
* For S3_BUCKET_LOCK, VOLUME_LOCK, BUCKET_LOCK type resource, same
146+
* thread acquiring lock again is allowed.
147+
*
148+
* For USER_LOCK, PREFIX_LOCK, S3_SECRET_LOCK type resource, same thread
149+
* acquiring lock again is not allowed.
150+
*
151+
* Special Note for USER_LOCK: Single thread can acquire single user lock/
152+
* multi user lock. But not both at the same time.
153+
* @param resource - Type of the resource.
154+
* @param resources - Resource names on which user want to acquire lock.
155+
* For Resource type BUCKET_LOCK, first param should be volume, second param
156+
* should be bucket name. For remaining all resource only one param should
157+
* be passed.
158+
*/
159+
public boolean acquireWriteLock(Resource resource, String... resources) {
160+
String resourceName = generateResourceName(resource, resources);
161+
return lock(resource, resourceName, manager::writeLock, WRITE_LOCK);
162+
}
163+
164+
private boolean lock(Resource resource, String resourceName,
165+
Consumer<String> lockFn, String lockType) {
110166
if (!resource.canLock(lockSet.get())) {
111167
String errorMessage = getErrorMessage(resource);
112168
LOG.error(errorMessage);
113169
throw new RuntimeException(errorMessage);
114170
} else {
115-
manager.lock(resourceName);
116-
LOG.debug("Acquired {} lock on resource {}", resource.name,
171+
lockFn.accept(resourceName);
172+
LOG.debug("Acquired {} {} lock on resource {}", lockType, resource.name,
117173
resourceName);
118174
lockSet.set(resource.setLock(lockSet.get()));
119175
return true;
@@ -197,19 +253,19 @@ public boolean acquireMultiUserLock(String firstUser, String secondUser) {
197253

198254
if (compare == 0) {
199255
// both users are equal.
200-
manager.lock(firstUser);
256+
manager.writeLock(firstUser);
201257
} else {
202-
manager.lock(firstUser);
258+
manager.writeLock(firstUser);
203259
try {
204-
manager.lock(secondUser);
260+
manager.writeLock(secondUser);
205261
} catch (Exception ex) {
206262
// We got an exception acquiring 2nd user lock. Release already
207263
// acquired user lock, and throw exception to the user.
208-
manager.unlock(firstUser);
264+
manager.writeUnlock(firstUser);
209265
throw ex;
210266
}
211267
}
212-
LOG.debug("Acquired {} lock on resource {} and {}", resource.name,
268+
LOG.debug("Acquired Write {} lock on resource {} and {}", resource.name,
213269
firstUser, secondUser);
214270
lockSet.set(resource.setLock(lockSet.get()));
215271
return true;
@@ -240,35 +296,66 @@ public void releaseMultiUserLock(String firstUser, String secondUser) {
240296

241297
if (compare == 0) {
242298
// both users are equal.
243-
manager.unlock(firstUser);
299+
manager.writeUnlock(firstUser);
244300
} else {
245-
manager.unlock(firstUser);
246-
manager.unlock(secondUser);
301+
manager.writeUnlock(firstUser);
302+
manager.writeUnlock(secondUser);
247303
}
248-
LOG.debug("Release {} lock on resource {} and {}", resource.name,
304+
LOG.debug("Release Write {} lock on resource {} and {}", resource.name,
249305
firstUser, secondUser);
250306
lockSet.set(resource.clearLock(lockSet.get()));
251307
}
252308

253309
/**
254-
* Release lock on resource.
310+
* Release write lock on resource.
311+
* @param resource - Type of the resource.
312+
* @param resources - Resource names on which user want to acquire lock.
313+
* For Resource type BUCKET_LOCK, first param should be volume, second param
314+
* should be bucket name. For remaining all resource only one param should
315+
* be passed.
316+
*/
317+
public void releaseWriteLock(Resource resource, String... resources) {
318+
String resourceName = generateResourceName(resource, resources);
319+
unlock(resource, resourceName, manager::writeUnlock, WRITE_LOCK);
320+
}
321+
322+
/**
323+
* Release read lock on resource.
324+
* @param resource - Type of the resource.
325+
* @param resources - Resource names on which user want to acquire lock.
326+
* For Resource type BUCKET_LOCK, first param should be volume, second param
327+
* should be bucket name. For remaining all resource only one param should
328+
* be passed.
329+
*/
330+
public void releaseReadLock(Resource resource, String... resources) {
331+
String resourceName = generateResourceName(resource, resources);
332+
unlock(resource, resourceName, manager::readUnlock, READ_LOCK);
333+
}
334+
335+
/**
336+
* Release write lock on resource.
255337
* @param resource - Type of the resource.
256338
* @param resources - Resource names on which user want to acquire lock.
257339
* For Resource type BUCKET_LOCK, first param should be volume, second param
258340
* should be bucket name. For remaining all resource only one param should
259341
* be passed.
260342
*/
343+
@Deprecated
261344
public void releaseLock(Resource resource, String... resources) {
262345
String resourceName = generateResourceName(resource, resources);
346+
unlock(resource, resourceName, manager::writeUnlock, WRITE_LOCK);
347+
}
348+
349+
private void unlock(Resource resource, String resourceName,
350+
Consumer<String> lockFn, String lockType) {
263351
// TODO: Not checking release of higher order level lock happened while
264352
// releasing lower order level lock, as for that we need counter for
265353
// locks, as some locks support acquiring lock again.
266-
manager.unlock(resourceName);
354+
lockFn.accept(resourceName);
267355
// clear lock
268-
LOG.debug("Release {}, lock on resource {}", resource.name,
269-
resource.name, resourceName);
356+
LOG.debug("Release {} {}, lock on resource {}", lockType, resource.name,
357+
resourceName);
270358
lockSet.set(resource.clearLock(lockSet.get()));
271-
272359
}
273360

274361
/**

hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/BucketManagerImpl.java

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,8 @@ public OmBucketInfo getBucketInfo(String volumeName, String bucketName)
219219
throws IOException {
220220
Preconditions.checkNotNull(volumeName);
221221
Preconditions.checkNotNull(bucketName);
222-
metadataManager.getLock().acquireLock(BUCKET_LOCK, volumeName, bucketName);
222+
metadataManager.getLock().acquireReadLock(BUCKET_LOCK, volumeName,
223+
bucketName);
223224
try {
224225
String bucketKey = metadataManager.getBucketKey(volumeName, bucketName);
225226
OmBucketInfo value = metadataManager.getBucketTable().get(bucketKey);
@@ -237,7 +238,7 @@ public OmBucketInfo getBucketInfo(String volumeName, String bucketName)
237238
}
238239
throw ex;
239240
} finally {
240-
metadataManager.getLock().releaseLock(BUCKET_LOCK, volumeName,
241+
metadataManager.getLock().releaseReadLock(BUCKET_LOCK, volumeName,
241242
bucketName);
242243
}
243244
}
@@ -520,7 +521,7 @@ public List<OzoneAcl> getAcl(OzoneObj obj) throws IOException {
520521
}
521522
String volume = obj.getVolumeName();
522523
String bucket = obj.getBucketName();
523-
metadataManager.getLock().acquireLock(BUCKET_LOCK, volume, bucket);
524+
metadataManager.getLock().acquireReadLock(BUCKET_LOCK, volume, bucket);
524525
try {
525526
String dbBucketKey = metadataManager.getBucketKey(volume, bucket);
526527
OmBucketInfo bucketInfo =
@@ -538,7 +539,7 @@ public List<OzoneAcl> getAcl(OzoneObj obj) throws IOException {
538539
}
539540
throw ex;
540541
} finally {
541-
metadataManager.getLock().releaseLock(BUCKET_LOCK, volume, bucket);
542+
metadataManager.getLock().releaseReadLock(BUCKET_LOCK, volume, bucket);
542543
}
543544
}
544545

@@ -557,7 +558,7 @@ public boolean checkAccess(OzoneObj ozObject, RequestContext context)
557558

558559
String volume = ozObject.getVolumeName();
559560
String bucket = ozObject.getBucketName();
560-
metadataManager.getLock().acquireLock(BUCKET_LOCK, volume, bucket);
561+
metadataManager.getLock().acquireReadLock(BUCKET_LOCK, volume, bucket);
561562
try {
562563
String dbBucketKey = metadataManager.getBucketKey(volume, bucket);
563564
OmBucketInfo bucketInfo =
@@ -581,7 +582,7 @@ public boolean checkAccess(OzoneObj ozObject, RequestContext context)
581582
throw new OMException("Check access operation failed for " +
582583
"bucket:" + bucket, ex, INTERNAL_ERROR);
583584
} finally {
584-
metadataManager.getLock().releaseLock(BUCKET_LOCK, volume, bucket);
585+
metadataManager.getLock().releaseReadLock(BUCKET_LOCK, volume, bucket);
585586
}
586587
}
587588
}

hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/KeyManagerImpl.java

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -622,7 +622,8 @@ public OmKeyInfo lookupKey(OmKeyArgs args, String clientAddress)
622622
String volumeName = args.getVolumeName();
623623
String bucketName = args.getBucketName();
624624
String keyName = args.getKeyName();
625-
metadataManager.getLock().acquireLock(BUCKET_LOCK, volumeName, bucketName);
625+
metadataManager.getLock().acquireReadLock(BUCKET_LOCK, volumeName,
626+
bucketName);
626627
try {
627628
String keyBytes = metadataManager.getOzoneKey(
628629
volumeName, bucketName, keyName);
@@ -682,7 +683,7 @@ public OmKeyInfo lookupKey(OmKeyArgs args, String clientAddress)
682683
throw new OMException(ex.getMessage(),
683684
KEY_NOT_FOUND);
684685
} finally {
685-
metadataManager.getLock().releaseLock(BUCKET_LOCK, volumeName,
686+
metadataManager.getLock().releaseReadLock(BUCKET_LOCK, volumeName,
686687
bucketName);
687688
}
688689
}
@@ -1311,7 +1312,8 @@ public OmMultipartUploadList listMultipartUploads(String volumeName,
13111312
Preconditions.checkNotNull(volumeName);
13121313
Preconditions.checkNotNull(bucketName);
13131314

1314-
metadataManager.getLock().acquireLock(BUCKET_LOCK, volumeName, bucketName);
1315+
metadataManager.getLock().acquireReadLock(BUCKET_LOCK, volumeName,
1316+
bucketName);
13151317
try {
13161318

13171319
List<String> multipartUploadKeys =
@@ -1354,7 +1356,7 @@ public OmMultipartUploadList listMultipartUploads(String volumeName,
13541356
throw new OMException(ex.getMessage(), ResultCodes
13551357
.LIST_MULTIPART_UPLOAD_PARTS_FAILED);
13561358
} finally {
1357-
metadataManager.getLock().releaseLock(BUCKET_LOCK, volumeName,
1359+
metadataManager.getLock().releaseReadLock(BUCKET_LOCK, volumeName,
13581360
bucketName);
13591361
}
13601362
}
@@ -1370,7 +1372,8 @@ public OmMultipartUploadListParts listParts(String volumeName,
13701372
boolean isTruncated = false;
13711373
int nextPartNumberMarker = 0;
13721374

1373-
metadataManager.getLock().acquireLock(BUCKET_LOCK, volumeName, bucketName);
1375+
metadataManager.getLock().acquireReadLock(BUCKET_LOCK, volumeName,
1376+
bucketName);
13741377
try {
13751378
String multipartKey = metadataManager.getMultipartKey(volumeName,
13761379
bucketName, keyName, uploadID);
@@ -1457,7 +1460,7 @@ public OmMultipartUploadListParts listParts(String volumeName,
14571460
throw new OMException(ex.getMessage(), ResultCodes
14581461
.LIST_MULTIPART_UPLOAD_PARTS_FAILED);
14591462
} finally {
1460-
metadataManager.getLock().releaseLock(BUCKET_LOCK, volumeName,
1463+
metadataManager.getLock().releaseReadLock(BUCKET_LOCK, volumeName,
14611464
bucketName);
14621465
}
14631466
}
@@ -1603,7 +1606,7 @@ public List<OzoneAcl> getAcl(OzoneObj obj) throws IOException {
16031606
String bucket = obj.getBucketName();
16041607
String keyName = obj.getKeyName();
16051608

1606-
metadataManager.getLock().acquireLock(BUCKET_LOCK, volume, bucket);
1609+
metadataManager.getLock().acquireReadLock(BUCKET_LOCK, volume, bucket);
16071610
try {
16081611
validateBucket(volume, bucket);
16091612
String objectKey = metadataManager.getOzoneKey(volume, bucket, keyName);
@@ -1620,7 +1623,7 @@ public List<OzoneAcl> getAcl(OzoneObj obj) throws IOException {
16201623
}
16211624
throw ex;
16221625
} finally {
1623-
metadataManager.getLock().releaseLock(BUCKET_LOCK, volume, bucket);
1626+
metadataManager.getLock().releaseReadLock(BUCKET_LOCK, volume, bucket);
16241627
}
16251628
}
16261629

@@ -1648,7 +1651,7 @@ public boolean checkAccess(OzoneObj ozObject, RequestContext context)
16481651
.setKeyName(keyName)
16491652
.build();
16501653

1651-
metadataManager.getLock().acquireLock(BUCKET_LOCK, volume, bucket);
1654+
metadataManager.getLock().acquireReadLock(BUCKET_LOCK, volume, bucket);
16521655
try {
16531656
validateBucket(volume, bucket);
16541657
OmKeyInfo keyInfo = null;
@@ -1687,7 +1690,7 @@ public boolean checkAccess(OzoneObj ozObject, RequestContext context)
16871690
throw new OMException("Check access operation failed for " +
16881691
"key:" + keyName, ex, INTERNAL_ERROR);
16891692
} finally {
1690-
metadataManager.getLock().releaseLock(BUCKET_LOCK, volume, bucket);
1693+
metadataManager.getLock().releaseReadLock(BUCKET_LOCK, volume, bucket);
16911694
}
16921695
}
16931696

@@ -1732,7 +1735,7 @@ public OzoneFileStatus getFileStatus(OmKeyArgs args) throws IOException {
17321735
String bucketName = args.getBucketName();
17331736
String keyName = args.getKeyName();
17341737

1735-
metadataManager.getLock().acquireLock(BUCKET_LOCK, volumeName, bucketName);
1738+
metadataManager.getLock().acquireReadLock(BUCKET_LOCK, volumeName, bucketName);
17361739
try {
17371740
// Check if this is the root of the filesystem.
17381741
if (keyName.length() == 0) {
@@ -1770,7 +1773,7 @@ public OzoneFileStatus getFileStatus(OmKeyArgs args) throws IOException {
17701773
volumeName + " bucket: " + bucketName + " key: " + keyName,
17711774
FILE_NOT_FOUND);
17721775
} finally {
1773-
metadataManager.getLock().releaseLock(BUCKET_LOCK, volumeName,
1776+
metadataManager.getLock().releaseReadLock(BUCKET_LOCK, volumeName,
17741777
bucketName);
17751778
}
17761779
}
@@ -1915,7 +1918,7 @@ public OmKeyInfo lookupFile(OmKeyArgs args, String clientAddress)
19151918
String bucketName = args.getBucketName();
19161919
String keyName = args.getKeyName();
19171920

1918-
metadataManager.getLock().acquireLock(BUCKET_LOCK, volumeName, bucketName);
1921+
metadataManager.getLock().acquireReadLock(BUCKET_LOCK, volumeName, bucketName);
19191922
try {
19201923
OzoneFileStatus fileStatus = getFileStatus(args);
19211924
if (fileStatus.isFile()) {
@@ -1926,7 +1929,7 @@ public OmKeyInfo lookupFile(OmKeyArgs args, String clientAddress)
19261929
}
19271930
//if key is not of type file or if key is not found we throw an exception
19281931
} finally {
1929-
metadataManager.getLock().releaseLock(BUCKET_LOCK, volumeName,
1932+
metadataManager.getLock().releaseReadLock(BUCKET_LOCK, volumeName,
19301933
bucketName);
19311934
}
19321935

@@ -1953,7 +1956,8 @@ public List<OzoneFileStatus> listStatus(OmKeyArgs args, boolean recursive,
19531956
String keyName = args.getKeyName();
19541957

19551958
List<OzoneFileStatus> fileStatusList = new ArrayList<>();
1956-
metadataManager.getLock().acquireLock(BUCKET_LOCK, volumeName, bucketName);
1959+
metadataManager.getLock().acquireReadLock(BUCKET_LOCK, volumeName,
1960+
bucketName);
19571961
try {
19581962
if (Strings.isNullOrEmpty(startKey)) {
19591963
OzoneFileStatus fileStatus = getFileStatus(args);
@@ -2015,7 +2019,7 @@ public List<OzoneFileStatus> listStatus(OmKeyArgs args, boolean recursive,
20152019
}
20162020
}
20172021
} finally {
2018-
metadataManager.getLock().releaseLock(BUCKET_LOCK, volumeName,
2022+
metadataManager.getLock().releaseReadLock(BUCKET_LOCK, volumeName,
20192023
bucketName);
20202024
}
20212025
return fileStatusList;

0 commit comments

Comments
 (0)