|
34 | 34 | import static org.apache.hadoop.hdfs.DFSConfigKeys.DFS_BLOCK_SIZE_KEY; |
35 | 35 | import static org.apache.hadoop.hdfs.DFSConfigKeys.DFS_NAMENODE_AUDIT_LOG_WITH_REMOTE_PORT_DEFAULT; |
36 | 36 | 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; |
37 | 39 | import static org.apache.hadoop.hdfs.DFSConfigKeys.DFS_STORAGE_POLICY_ENABLED_DEFAULT; |
38 | 40 | import static org.apache.hadoop.hdfs.DFSConfigKeys.DFS_STORAGE_POLICY_PERMISSIONS_SUPERUSER_ONLY_DEFAULT; |
39 | 41 | import static org.apache.hadoop.hdfs.DFSConfigKeys.DFS_STORAGE_POLICY_PERMISSIONS_SUPERUSER_ONLY_KEY; |
|
96 | 98 | import static org.apache.hadoop.hdfs.DFSConfigKeys.DFS_NAMENODE_SNAPSHOT_DIFF_LISTING_LIMIT_DEFAULT; |
97 | 99 | import static org.apache.hadoop.hdfs.DFSUtil.isParentEntry; |
98 | 100 |
|
| 101 | +import java.lang.reflect.Constructor; |
99 | 102 | import java.nio.charset.StandardCharsets; |
100 | 103 | import java.util.concurrent.atomic.AtomicLong; |
101 | 104 |
|
|
114 | 117 | import org.apache.hadoop.hdfs.protocol.ErasureCodingPolicyInfo; |
115 | 118 |
|
116 | 119 | import org.apache.hadoop.hdfs.server.blockmanagement.BlockInfoStriped; |
| 120 | +import org.apache.hadoop.hdfs.server.namenode.fgl.FSNamesystemLockMode; |
117 | 121 | import org.apache.hadoop.thirdparty.com.google.common.collect.Maps; |
118 | 122 | import org.apache.hadoop.hdfs.server.namenode.snapshot.SnapshotDeletionGc; |
119 | 123 | import org.apache.hadoop.thirdparty.protobuf.ByteString; |
|
274 | 278 | import org.apache.hadoop.hdfs.server.common.Storage.StorageDirType; |
275 | 279 | import org.apache.hadoop.hdfs.server.common.Storage.StorageDirectory; |
276 | 280 | import org.apache.hadoop.hdfs.server.common.Util; |
| 281 | +import org.apache.hadoop.hdfs.server.namenode.fgl.FSNamesystemLock; |
277 | 282 | import org.apache.hadoop.hdfs.server.namenode.FSDirEncryptionZoneOp.EncryptionKeyInfo; |
278 | 283 | import org.apache.hadoop.hdfs.server.namenode.FSDirectory.DirOp; |
279 | 284 | import org.apache.hadoop.hdfs.server.namenode.FsImageProto.SecretManagerSection; |
@@ -871,7 +876,10 @@ static FSNamesystem loadFromDisk(Configuration conf) throws IOException { |
871 | 876 | this.contextFieldSeparator = |
872 | 877 | conf.get(HADOOP_CALLER_CONTEXT_SEPARATOR_KEY, |
873 | 878 | 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); |
875 | 883 | cpLock = new ReentrantLock(); |
876 | 884 |
|
877 | 885 | this.fsImage = fsImage; |
@@ -1077,6 +1085,18 @@ static FSNamesystem loadFromDisk(Configuration conf) throws IOException { |
1077 | 1085 | } |
1078 | 1086 | } |
1079 | 1087 |
|
| 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 | + |
1080 | 1100 | private static void checkForAsyncLogEnabledByOldConfigs(Configuration conf) { |
1081 | 1101 | // dfs.namenode.audit.log.async is no longer in use. Use log4j properties instead. |
1082 | 1102 | if (conf.getBoolean("dfs.namenode.audit.log.async", false)) { |
@@ -1783,70 +1803,74 @@ public static List<URI> getSharedEditsDirs(Configuration conf) { |
1783 | 1803 | } |
1784 | 1804 |
|
1785 | 1805 | @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); |
1793 | 1808 | } |
1794 | 1809 |
|
1795 | 1810 | @Override |
1796 | | - public void readUnlock() { |
1797 | | - this.fsLock.readUnlock(); |
| 1811 | + public void readLockInterruptibly(FSNamesystemLockMode lockMode) throws InterruptedException { |
| 1812 | + this.fsLock.readLockInterruptibly(lockMode); |
1798 | 1813 | } |
1799 | 1814 |
|
1800 | 1815 | @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); |
1803 | 1818 | } |
1804 | 1819 |
|
1805 | 1820 | public void readUnlock(String opName, |
1806 | 1821 | Supplier<String> lockReportInfoSupplier) { |
1807 | | - this.fsLock.readUnlock(opName, lockReportInfoSupplier); |
| 1822 | + readUnlock(FSNamesystemLockMode.GLOBAL, opName, lockReportInfoSupplier); |
1808 | 1823 | } |
1809 | 1824 |
|
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); |
1813 | 1828 | } |
1814 | 1829 |
|
1815 | 1830 | @Override |
1816 | | - public void writeLockInterruptibly() throws InterruptedException { |
1817 | | - this.fsLock.writeLockInterruptibly(); |
| 1831 | + public void writeLock(FSNamesystemLockMode lockMode) { |
| 1832 | + this.fsLock.writeLock(lockMode); |
1818 | 1833 | } |
1819 | 1834 |
|
1820 | 1835 | @Override |
1821 | | - public void writeUnlock() { |
1822 | | - this.fsLock.writeUnlock(); |
| 1836 | + public void writeLockInterruptibly(FSNamesystemLockMode lockMode) throws InterruptedException { |
| 1837 | + this.fsLock.writeLockInterruptibly(lockMode); |
1823 | 1838 | } |
1824 | 1839 |
|
1825 | 1840 | @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); |
1828 | 1843 | } |
1829 | 1844 |
|
1830 | 1845 | 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); |
1832 | 1856 | } |
1833 | 1857 |
|
1834 | | - public void writeUnlock(String opName, |
| 1858 | + public void writeUnlock(FSNamesystemLockMode lockMode, String opName, |
1835 | 1859 | Supplier<String> lockReportInfoSupplier) { |
1836 | | - this.fsLock.writeUnlock(opName, lockReportInfoSupplier); |
| 1860 | + this.fsLock.writeUnlock(lockMode, opName, lockReportInfoSupplier); |
1837 | 1861 | } |
1838 | 1862 |
|
1839 | 1863 | @Override |
1840 | | - public boolean hasWriteLock() { |
1841 | | - return this.fsLock.isWriteLockedByCurrentThread(); |
| 1864 | + public boolean hasWriteLock(FSNamesystemLockMode lockMode) { |
| 1865 | + return this.fsLock.hasWriteLock(lockMode); |
1842 | 1866 | } |
1843 | 1867 | @Override |
1844 | | - public boolean hasReadLock() { |
1845 | | - return this.fsLock.getReadHoldCount() > 0 || hasWriteLock(); |
| 1868 | + public boolean hasReadLock(FSNamesystemLockMode lockMode) { |
| 1869 | + return this.fsLock.hasReadLock(lockMode); |
1846 | 1870 | } |
1847 | 1871 |
|
1848 | 1872 | public int getReadHoldCount() { |
1849 | | - return this.fsLock.getReadHoldCount(); |
| 1873 | + return this.fsLock.getReadHoldCount(FSNamesystemLockMode.GLOBAL); |
1850 | 1874 | } |
1851 | 1875 |
|
1852 | 1876 | /** Lock the checkpoint lock */ |
@@ -4927,21 +4951,21 @@ public float getReconstructionQueuesInitProgress() { |
4927 | 4951 | @Metric({"LockQueueLength", "Number of threads waiting to " + |
4928 | 4952 | "acquire FSNameSystemLock"}) |
4929 | 4953 | public int getFsLockQueueLength() { |
4930 | | - return fsLock.getQueueLength(); |
| 4954 | + return fsLock.getQueueLength(FSNamesystemLockMode.FS); |
4931 | 4955 | } |
4932 | 4956 |
|
4933 | 4957 | @Metric(value = {"ReadLockLongHoldCount", "The number of time " + |
4934 | 4958 | "the read lock has been held for longer than the threshold"}, |
4935 | 4959 | type = Metric.Type.COUNTER) |
4936 | 4960 | public long getNumOfReadLockLongHold() { |
4937 | | - return fsLock.getNumOfReadLockLongHold(); |
| 4961 | + return fsLock.getNumOfReadLockLongHold(FSNamesystemLockMode.FS); |
4938 | 4962 | } |
4939 | 4963 |
|
4940 | 4964 | @Metric(value = {"WriteLockLongHoldCount", "The number of time " + |
4941 | 4965 | "the write lock has been held for longer than the threshold"}, |
4942 | 4966 | type = Metric.Type.COUNTER) |
4943 | 4967 | public long getNumOfWriteLockLongHold() { |
4944 | | - return fsLock.getNumOfWriteLockLongHold(); |
| 4968 | + return fsLock.getNumOfWriteLockLongHold(FSNamesystemLockMode.FS); |
4945 | 4969 | } |
4946 | 4970 |
|
4947 | 4971 | int getNumberOfDatanodes(DatanodeReportType type) { |
@@ -7094,12 +7118,12 @@ public void setEditLogTailerForTests(EditLogTailer tailer) { |
7094 | 7118 |
|
7095 | 7119 | @VisibleForTesting |
7096 | 7120 | void setFsLockForTests(ReentrantReadWriteLock lock) { |
7097 | | - this.fsLock.coarseLock = lock; |
| 7121 | + this.fsLock.setLockForTests(lock); |
7098 | 7122 | } |
7099 | 7123 |
|
7100 | 7124 | @VisibleForTesting |
7101 | 7125 | public ReentrantReadWriteLock getFsLockForTests() { |
7102 | | - return fsLock.coarseLock; |
| 7126 | + return fsLock.getLockForTests(); |
7103 | 7127 | } |
7104 | 7128 |
|
7105 | 7129 | @VisibleForTesting |
|
0 commit comments