|
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.FSNLockManager; |
| 121 | +import org.apache.hadoop.hdfs.server.namenode.fgl.FSNamesystemLockMode; |
117 | 122 | import org.apache.hadoop.thirdparty.com.google.common.collect.Maps; |
118 | 123 | import org.apache.hadoop.hdfs.server.namenode.snapshot.SnapshotDeletionGc; |
119 | 124 | import org.apache.hadoop.thirdparty.protobuf.ByteString; |
@@ -621,7 +626,7 @@ private boolean isFromProxyUser(CallerContext ctx) { |
621 | 626 | private final int numCommittedAllowed; |
622 | 627 |
|
623 | 628 | /** Lock to protect FSNamesystem. */ |
624 | | - private final FSNamesystemLock fsLock; |
| 629 | + private final FSNLockManager fsLock; |
625 | 630 |
|
626 | 631 | /** |
627 | 632 | * Checkpoint lock to protect FSNamesystem modification on standby NNs. |
@@ -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 FSNLockManager> lockKlass = conf.getClass( |
| 880 | + DFS_NAMENODE_LOCK_MODEL_PROVIDER_KEY, DFS_NAMENODE_LOCK_MODEL_PROVIDER_DEFAULT, |
| 881 | + FSNLockManager.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 mutableRatesMetrics) { |
| 1090 | + try { |
| 1091 | + Constructor<T> meth = theClass.getDeclaredConstructor( |
| 1092 | + Configuration.class, MutableRatesWithAggregation.class); |
| 1093 | + meth.setAccessible(true); |
| 1094 | + return meth.newInstance(conf, mutableRatesMetrics); |
| 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)) { |
@@ -1787,70 +1807,74 @@ public static List<URI> getSharedEditsDirs(Configuration conf) { |
1787 | 1807 | } |
1788 | 1808 |
|
1789 | 1809 | @Override |
1790 | | - public void readLock() { |
1791 | | - this.fsLock.readLock(); |
1792 | | - } |
1793 | | - |
1794 | | - @Override |
1795 | | - public void readLockInterruptibly() throws InterruptedException { |
1796 | | - this.fsLock.readLockInterruptibly(); |
| 1810 | + public void readLock(FSNamesystemLockMode lockMode) { |
| 1811 | + this.fsLock.readLock(lockMode); |
1797 | 1812 | } |
1798 | 1813 |
|
1799 | 1814 | @Override |
1800 | | - public void readUnlock() { |
1801 | | - this.fsLock.readUnlock(); |
| 1815 | + public void readLockInterruptibly(FSNamesystemLockMode lockMode) throws InterruptedException { |
| 1816 | + this.fsLock.readLockInterruptibly(lockMode); |
1802 | 1817 | } |
1803 | 1818 |
|
1804 | 1819 | @Override |
1805 | | - public void readUnlock(String opName) { |
1806 | | - this.fsLock.readUnlock(opName); |
| 1820 | + public void readUnlock(FSNamesystemLockMode lockMode, String opName) { |
| 1821 | + this.fsLock.readUnlock(lockMode, opName); |
1807 | 1822 | } |
1808 | 1823 |
|
1809 | 1824 | public void readUnlock(String opName, |
1810 | 1825 | Supplier<String> lockReportInfoSupplier) { |
1811 | | - this.fsLock.readUnlock(opName, lockReportInfoSupplier); |
| 1826 | + readUnlock(FSNamesystemLockMode.GLOBAL, opName, lockReportInfoSupplier); |
1812 | 1827 | } |
1813 | 1828 |
|
1814 | | - @Override |
1815 | | - public void writeLock() { |
1816 | | - this.fsLock.writeLock(); |
| 1829 | + public void readUnlock(FSNamesystemLockMode lockMode, String opName, |
| 1830 | + Supplier<String> lockReportInfoSupplier) { |
| 1831 | + this.fsLock.readUnlock(lockMode, opName, lockReportInfoSupplier); |
1817 | 1832 | } |
1818 | 1833 |
|
1819 | 1834 | @Override |
1820 | | - public void writeLockInterruptibly() throws InterruptedException { |
1821 | | - this.fsLock.writeLockInterruptibly(); |
| 1835 | + public void writeLock(FSNamesystemLockMode lockMode) { |
| 1836 | + this.fsLock.writeLock(lockMode); |
1822 | 1837 | } |
1823 | 1838 |
|
1824 | 1839 | @Override |
1825 | | - public void writeUnlock() { |
1826 | | - this.fsLock.writeUnlock(); |
| 1840 | + public void writeLockInterruptibly(FSNamesystemLockMode lockMode) throws InterruptedException { |
| 1841 | + this.fsLock.writeLockInterruptibly(lockMode); |
1827 | 1842 | } |
1828 | 1843 |
|
1829 | 1844 | @Override |
1830 | | - public void writeUnlock(String opName) { |
1831 | | - this.fsLock.writeUnlock(opName); |
| 1845 | + public void writeUnlock(FSNamesystemLockMode lockMode, String opName) { |
| 1846 | + this.fsLock.writeUnlock(lockMode, opName); |
1832 | 1847 | } |
1833 | 1848 |
|
1834 | 1849 | public void writeUnlock(String opName, boolean suppressWriteLockReport) { |
1835 | | - this.fsLock.writeUnlock(opName, suppressWriteLockReport); |
| 1850 | + writeUnlock(FSNamesystemLockMode.GLOBAL, opName, suppressWriteLockReport); |
| 1851 | + } |
| 1852 | + |
| 1853 | + public void writeUnlock(FSNamesystemLockMode lockMode, String opName, |
| 1854 | + boolean suppressWriteLockReport) { |
| 1855 | + this.fsLock.writeUnlock(lockMode, opName, suppressWriteLockReport); |
| 1856 | + } |
| 1857 | + |
| 1858 | + public void writeUnlock(String opName, Supplier<String> lockReportInfoSupplier) { |
| 1859 | + writeUnlock(FSNamesystemLockMode.GLOBAL, opName, lockReportInfoSupplier); |
1836 | 1860 | } |
1837 | 1861 |
|
1838 | | - public void writeUnlock(String opName, |
| 1862 | + public void writeUnlock(FSNamesystemLockMode lockMode, String opName, |
1839 | 1863 | Supplier<String> lockReportInfoSupplier) { |
1840 | | - this.fsLock.writeUnlock(opName, lockReportInfoSupplier); |
| 1864 | + this.fsLock.writeUnlock(lockMode, opName, lockReportInfoSupplier); |
1841 | 1865 | } |
1842 | 1866 |
|
1843 | 1867 | @Override |
1844 | | - public boolean hasWriteLock() { |
1845 | | - return this.fsLock.isWriteLockedByCurrentThread(); |
| 1868 | + public boolean hasWriteLock(FSNamesystemLockMode lockMode) { |
| 1869 | + return this.fsLock.hasWriteLock(lockMode); |
1846 | 1870 | } |
1847 | 1871 | @Override |
1848 | | - public boolean hasReadLock() { |
1849 | | - return this.fsLock.getReadHoldCount() > 0 || hasWriteLock(); |
| 1872 | + public boolean hasReadLock(FSNamesystemLockMode lockMode) { |
| 1873 | + return this.fsLock.hasReadLock(lockMode); |
1850 | 1874 | } |
1851 | 1875 |
|
1852 | 1876 | public int getReadHoldCount() { |
1853 | | - return this.fsLock.getReadHoldCount(); |
| 1877 | + return this.fsLock.getReadHoldCount(FSNamesystemLockMode.GLOBAL); |
1854 | 1878 | } |
1855 | 1879 |
|
1856 | 1880 | /** Lock the checkpoint lock */ |
@@ -4931,21 +4955,21 @@ public float getReconstructionQueuesInitProgress() { |
4931 | 4955 | @Metric({"LockQueueLength", "Number of threads waiting to " + |
4932 | 4956 | "acquire FSNameSystemLock"}) |
4933 | 4957 | public int getFsLockQueueLength() { |
4934 | | - return fsLock.getQueueLength(); |
| 4958 | + return fsLock.getQueueLength(FSNamesystemLockMode.FS); |
4935 | 4959 | } |
4936 | 4960 |
|
4937 | 4961 | @Metric(value = {"ReadLockLongHoldCount", "The number of time " + |
4938 | 4962 | "the read lock has been held for longer than the threshold"}, |
4939 | 4963 | type = Metric.Type.COUNTER) |
4940 | 4964 | public long getNumOfReadLockLongHold() { |
4941 | | - return fsLock.getNumOfReadLockLongHold(); |
| 4965 | + return fsLock.getNumOfReadLockLongHold(FSNamesystemLockMode.FS); |
4942 | 4966 | } |
4943 | 4967 |
|
4944 | 4968 | @Metric(value = {"WriteLockLongHoldCount", "The number of time " + |
4945 | 4969 | "the write lock has been held for longer than the threshold"}, |
4946 | 4970 | type = Metric.Type.COUNTER) |
4947 | 4971 | public long getNumOfWriteLockLongHold() { |
4948 | | - return fsLock.getNumOfWriteLockLongHold(); |
| 4972 | + return fsLock.getNumOfWriteLockLongHold(FSNamesystemLockMode.FS); |
4949 | 4973 | } |
4950 | 4974 |
|
4951 | 4975 | int getNumberOfDatanodes(DatanodeReportType type) { |
@@ -7097,12 +7121,12 @@ public void setEditLogTailerForTests(EditLogTailer tailer) { |
7097 | 7121 |
|
7098 | 7122 | @VisibleForTesting |
7099 | 7123 | void setFsLockForTests(ReentrantReadWriteLock lock) { |
7100 | | - this.fsLock.coarseLock = lock; |
| 7124 | + this.fsLock.setLockForTests(lock); |
7101 | 7125 | } |
7102 | 7126 |
|
7103 | 7127 | @VisibleForTesting |
7104 | 7128 | public ReentrantReadWriteLock getFsLockForTests() { |
7105 | | - return fsLock.coarseLock; |
| 7129 | + return fsLock.getLockForTests(); |
7106 | 7130 | } |
7107 | 7131 |
|
7108 | 7132 | @VisibleForTesting |
|
0 commit comments