Skip to content

Commit a81fb5e

Browse files
committed
HDFS-17387. [FGL] Abstract selectable locking mode
1 parent b2bf27b commit a81fb5e

File tree

13 files changed

+2318
-46
lines changed

13 files changed

+2318
-46
lines changed

hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/DFSConfigKeys.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@
2929
import org.apache.hadoop.hdfs.server.common.HdfsServerConstants;
3030
import org.apache.hadoop.hdfs.server.datanode.fsdataset.impl.RamDiskReplicaLruTracker;
3131
import org.apache.hadoop.hdfs.server.datanode.fsdataset.impl.ReservedSpaceCalculator;
32+
import org.apache.hadoop.hdfs.server.namenode.fgl.FSNamesystemLock;
33+
import org.apache.hadoop.hdfs.server.namenode.fgl.FineGrainedFSNamesystemLock;
34+
import org.apache.hadoop.hdfs.server.namenode.fgl.GlobalFSNamesystemLock;
3235
import org.apache.hadoop.hdfs.web.URLConnectionFactory;
3336
import org.apache.hadoop.http.HttpConfig;
3437

@@ -1051,6 +1054,8 @@ public class DFSConfigKeys extends CommonConfigurationKeys {
10511054
public static final String DFS_NAMENODE_INODE_ATTRIBUTES_PROVIDER_KEY = "dfs.namenode.inode.attributes.provider.class";
10521055
public static final String DFS_NAMENODE_INODE_ATTRIBUTES_PROVIDER_BYPASS_USERS_KEY = "dfs.namenode.inode.attributes.provider.bypass.users";
10531056
public static final String DFS_NAMENODE_INODE_ATTRIBUTES_PROVIDER_BYPASS_USERS_DEFAULT = "";
1057+
public static final String DFS_NAMENODE_LOCK_MODEL_PROVIDER_KEY = "dfs.namenode.lock.model.provider.class";
1058+
public static final Class<? extends FSNamesystemLock> DFS_NAMENODE_LOCK_MODEL_PROVIDER_DEFAULT = FineGrainedFSNamesystemLock.class;
10541059

10551060
public static final String DFS_DATANODE_BP_READY_TIMEOUT_KEY = "dfs.datanode.bp-ready.timeout";
10561061
public static final long DFS_DATANODE_BP_READY_TIMEOUT_DEFAULT = 20;

hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSNamesystem.java

Lines changed: 59 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@
3434
import static org.apache.hadoop.hdfs.DFSConfigKeys.DFS_BLOCK_SIZE_KEY;
3535
import static org.apache.hadoop.hdfs.DFSConfigKeys.DFS_NAMENODE_AUDIT_LOG_WITH_REMOTE_PORT_DEFAULT;
3636
import static org.apache.hadoop.hdfs.DFSConfigKeys.DFS_NAMENODE_AUDIT_LOG_WITH_REMOTE_PORT_KEY;
37+
import static org.apache.hadoop.hdfs.DFSConfigKeys.DFS_NAMENODE_LOCK_MODEL_PROVIDER_DEFAULT;
38+
import static org.apache.hadoop.hdfs.DFSConfigKeys.DFS_NAMENODE_LOCK_MODEL_PROVIDER_KEY;
3739
import static org.apache.hadoop.hdfs.DFSConfigKeys.DFS_STORAGE_POLICY_ENABLED_DEFAULT;
3840
import static org.apache.hadoop.hdfs.DFSConfigKeys.DFS_STORAGE_POLICY_PERMISSIONS_SUPERUSER_ONLY_DEFAULT;
3941
import static org.apache.hadoop.hdfs.DFSConfigKeys.DFS_STORAGE_POLICY_PERMISSIONS_SUPERUSER_ONLY_KEY;
@@ -96,6 +98,7 @@
9698
import static org.apache.hadoop.hdfs.DFSConfigKeys.DFS_NAMENODE_SNAPSHOT_DIFF_LISTING_LIMIT_DEFAULT;
9799
import static org.apache.hadoop.hdfs.DFSUtil.isParentEntry;
98100

101+
import java.lang.reflect.Constructor;
99102
import java.nio.charset.StandardCharsets;
100103
import java.util.concurrent.atomic.AtomicLong;
101104

@@ -114,6 +117,7 @@
114117
import org.apache.hadoop.hdfs.protocol.ErasureCodingPolicyInfo;
115118

116119
import org.apache.hadoop.hdfs.server.blockmanagement.BlockInfoStriped;
120+
import org.apache.hadoop.hdfs.server.namenode.fgl.FSNamesystemLockMode;
117121
import org.apache.hadoop.thirdparty.com.google.common.collect.Maps;
118122
import org.apache.hadoop.hdfs.server.namenode.snapshot.SnapshotDeletionGc;
119123
import org.apache.hadoop.thirdparty.protobuf.ByteString;
@@ -274,6 +278,7 @@
274278
import org.apache.hadoop.hdfs.server.common.Storage.StorageDirType;
275279
import org.apache.hadoop.hdfs.server.common.Storage.StorageDirectory;
276280
import org.apache.hadoop.hdfs.server.common.Util;
281+
import org.apache.hadoop.hdfs.server.namenode.fgl.FSNamesystemLock;
277282
import org.apache.hadoop.hdfs.server.namenode.FSDirEncryptionZoneOp.EncryptionKeyInfo;
278283
import org.apache.hadoop.hdfs.server.namenode.FSDirectory.DirOp;
279284
import org.apache.hadoop.hdfs.server.namenode.FsImageProto.SecretManagerSection;
@@ -871,7 +876,10 @@ static FSNamesystem loadFromDisk(Configuration conf) throws IOException {
871876
this.contextFieldSeparator =
872877
conf.get(HADOOP_CALLER_CONTEXT_SEPARATOR_KEY,
873878
HADOOP_CALLER_CONTEXT_SEPARATOR_DEFAULT);
874-
fsLock = new FSNamesystemLock(conf, detailedLockHoldTimeMetrics);
879+
Class<? extends FSNamesystemLock> lockKlass = conf.getClass(
880+
DFS_NAMENODE_LOCK_MODEL_PROVIDER_KEY, DFS_NAMENODE_LOCK_MODEL_PROVIDER_DEFAULT,
881+
FSNamesystemLock.class);
882+
fsLock = createLock(lockKlass, conf, detailedLockHoldTimeMetrics);
875883
cpLock = new ReentrantLock();
876884

877885
this.fsImage = fsImage;
@@ -1077,6 +1085,18 @@ static FSNamesystem loadFromDisk(Configuration conf) throws IOException {
10771085
}
10781086
}
10791087

1088+
private <T> T createLock(Class<T> theClass, Configuration conf,
1089+
MutableRatesWithAggregation detailedLockHoldTimeMetrics) {
1090+
try {
1091+
Constructor<T> meth = theClass.getDeclaredConstructor(
1092+
Configuration.class, MutableRatesWithAggregation.class);
1093+
meth.setAccessible(true);
1094+
return meth.newInstance(conf, detailedLockHoldTimeMetrics);
1095+
} catch (Exception e) {
1096+
throw new RuntimeException(e);
1097+
}
1098+
}
1099+
10801100
private static void checkForAsyncLogEnabledByOldConfigs(Configuration conf) {
10811101
// dfs.namenode.audit.log.async is no longer in use. Use log4j properties instead.
10821102
if (conf.getBoolean("dfs.namenode.audit.log.async", false)) {
@@ -1783,70 +1803,74 @@ public static List<URI> getSharedEditsDirs(Configuration conf) {
17831803
}
17841804

17851805
@Override
1786-
public void readLock() {
1787-
this.fsLock.readLock();
1788-
}
1789-
1790-
@Override
1791-
public void readLockInterruptibly() throws InterruptedException {
1792-
this.fsLock.readLockInterruptibly();
1806+
public void readLock(FSNamesystemLockMode lockMode) {
1807+
this.fsLock.readLock(lockMode);
17931808
}
17941809

17951810
@Override
1796-
public void readUnlock() {
1797-
this.fsLock.readUnlock();
1811+
public void readLockInterruptibly(FSNamesystemLockMode lockMode) throws InterruptedException {
1812+
this.fsLock.readLockInterruptibly(lockMode);
17981813
}
17991814

18001815
@Override
1801-
public void readUnlock(String opName) {
1802-
this.fsLock.readUnlock(opName);
1816+
public void readUnlock(FSNamesystemLockMode lockMode, String opName) {
1817+
this.fsLock.readUnlock(lockMode, opName);
18031818
}
18041819

18051820
public void readUnlock(String opName,
18061821
Supplier<String> lockReportInfoSupplier) {
1807-
this.fsLock.readUnlock(opName, lockReportInfoSupplier);
1822+
readUnlock(FSNamesystemLockMode.GLOBAL, opName, lockReportInfoSupplier);
18081823
}
18091824

1810-
@Override
1811-
public void writeLock() {
1812-
this.fsLock.writeLock();
1825+
public void readUnlock(FSNamesystemLockMode lockMode, String opName,
1826+
Supplier<String> lockReportInfoSupplier) {
1827+
this.fsLock.readUnlock(lockMode, opName, lockReportInfoSupplier);
18131828
}
18141829

18151830
@Override
1816-
public void writeLockInterruptibly() throws InterruptedException {
1817-
this.fsLock.writeLockInterruptibly();
1831+
public void writeLock(FSNamesystemLockMode lockMode) {
1832+
this.fsLock.writeLock(lockMode);
18181833
}
18191834

18201835
@Override
1821-
public void writeUnlock() {
1822-
this.fsLock.writeUnlock();
1836+
public void writeLockInterruptibly(FSNamesystemLockMode lockMode) throws InterruptedException {
1837+
this.fsLock.writeLockInterruptibly(lockMode);
18231838
}
18241839

18251840
@Override
1826-
public void writeUnlock(String opName) {
1827-
this.fsLock.writeUnlock(opName);
1841+
public void writeUnlock(FSNamesystemLockMode lockMode, String opName) {
1842+
this.fsLock.writeUnlock(lockMode, opName);
18281843
}
18291844

18301845
public void writeUnlock(String opName, boolean suppressWriteLockReport) {
1831-
this.fsLock.writeUnlock(opName, suppressWriteLockReport);
1846+
writeUnlock(FSNamesystemLockMode.GLOBAL, opName, suppressWriteLockReport);
1847+
}
1848+
1849+
public void writeUnlock(FSNamesystemLockMode lockMode, String opName,
1850+
boolean suppressWriteLockReport) {
1851+
this.fsLock.writeUnlock(lockMode, opName, suppressWriteLockReport);
1852+
}
1853+
1854+
public void writeUnlock(String opName, Supplier<String> lockReportInfoSupplier) {
1855+
writeUnlock(FSNamesystemLockMode.GLOBAL, opName, lockReportInfoSupplier);
18321856
}
18331857

1834-
public void writeUnlock(String opName,
1858+
public void writeUnlock(FSNamesystemLockMode lockMode, String opName,
18351859
Supplier<String> lockReportInfoSupplier) {
1836-
this.fsLock.writeUnlock(opName, lockReportInfoSupplier);
1860+
this.fsLock.writeUnlock(lockMode, opName, lockReportInfoSupplier);
18371861
}
18381862

18391863
@Override
1840-
public boolean hasWriteLock() {
1841-
return this.fsLock.isWriteLockedByCurrentThread();
1864+
public boolean hasWriteLock(FSNamesystemLockMode lockMode) {
1865+
return this.fsLock.hasWriteLock(lockMode);
18421866
}
18431867
@Override
1844-
public boolean hasReadLock() {
1845-
return this.fsLock.getReadHoldCount() > 0 || hasWriteLock();
1868+
public boolean hasReadLock(FSNamesystemLockMode lockMode) {
1869+
return this.fsLock.hasReadLock(lockMode);
18461870
}
18471871

18481872
public int getReadHoldCount() {
1849-
return this.fsLock.getReadHoldCount();
1873+
return this.fsLock.getReadHoldCount(FSNamesystemLockMode.GLOBAL);
18501874
}
18511875

18521876
/** Lock the checkpoint lock */
@@ -4927,21 +4951,21 @@ public float getReconstructionQueuesInitProgress() {
49274951
@Metric({"LockQueueLength", "Number of threads waiting to " +
49284952
"acquire FSNameSystemLock"})
49294953
public int getFsLockQueueLength() {
4930-
return fsLock.getQueueLength();
4954+
return fsLock.getQueueLength(FSNamesystemLockMode.FS);
49314955
}
49324956

49334957
@Metric(value = {"ReadLockLongHoldCount", "The number of time " +
49344958
"the read lock has been held for longer than the threshold"},
49354959
type = Metric.Type.COUNTER)
49364960
public long getNumOfReadLockLongHold() {
4937-
return fsLock.getNumOfReadLockLongHold();
4961+
return fsLock.getNumOfReadLockLongHold(FSNamesystemLockMode.FS);
49384962
}
49394963

49404964
@Metric(value = {"WriteLockLongHoldCount", "The number of time " +
49414965
"the write lock has been held for longer than the threshold"},
49424966
type = Metric.Type.COUNTER)
49434967
public long getNumOfWriteLockLongHold() {
4944-
return fsLock.getNumOfWriteLockLongHold();
4968+
return fsLock.getNumOfWriteLockLongHold(FSNamesystemLockMode.FS);
49454969
}
49464970

49474971
int getNumberOfDatanodes(DatanodeReportType type) {
@@ -7094,12 +7118,12 @@ public void setEditLogTailerForTests(EditLogTailer tailer) {
70947118

70957119
@VisibleForTesting
70967120
void setFsLockForTests(ReentrantReadWriteLock lock) {
7097-
this.fsLock.coarseLock = lock;
7121+
this.fsLock.setLockForTests(lock);
70987122
}
70997123

71007124
@VisibleForTesting
71017125
public ReentrantReadWriteLock getFsLockForTests() {
7102-
return fsLock.coarseLock;
7126+
return fsLock.getLockForTests();
71037127
}
71047128

71057129
@VisibleForTesting

hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSNamesystemLock.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@
6464
* {@link MutableRatesWithAggregation}. However since threads are re-used
6565
* between operations this should not generally be an issue.
6666
*/
67+
@Deprecated
6768
class FSNamesystemLock {
6869
@VisibleForTesting
6970
protected ReentrantReadWriteLock coarseLock;

0 commit comments

Comments
 (0)