HDFS-14150. RBF: Quotas of the sub-cluster should be removed when removing the mount point. Contributed by Takanobu Asanuma.

This commit is contained in:
Yiqun Lin 2019-01-09 17:18:43 +08:00 committed by Brahma Reddy Battula
parent 53791b97a3
commit ea3e7b8288
4 changed files with 67 additions and 12 deletions

View File

@ -250,23 +250,25 @@ public class RouterAdminServer extends AbstractService
MountTable mountTable = request.getEntry(); MountTable mountTable = request.getEntry();
if (mountTable != null && router.isQuotaEnabled()) { if (mountTable != null && router.isQuotaEnabled()) {
synchronizeQuota(mountTable); synchronizeQuota(mountTable.getSourcePath(),
mountTable.getQuota().getQuota(),
mountTable.getQuota().getSpaceQuota());
} }
return response; return response;
} }
/** /**
* Synchronize the quota value across mount table and subclusters. * Synchronize the quota value across mount table and subclusters.
* @param mountTable Quota set in given mount table. * @param path Source path in given mount table.
* @param nsQuota Name quota definition in given mount table.
* @param ssQuota Space quota definition in given mount table.
* @throws IOException * @throws IOException
*/ */
private void synchronizeQuota(MountTable mountTable) throws IOException { private void synchronizeQuota(String path, long nsQuota, long ssQuota)
String path = mountTable.getSourcePath(); throws IOException {
long nsQuota = mountTable.getQuota().getQuota(); if (router.isQuotaEnabled() &&
long ssQuota = mountTable.getQuota().getSpaceQuota(); (nsQuota != HdfsConstants.QUOTA_DONT_SET
|| ssQuota != HdfsConstants.QUOTA_DONT_SET)) {
if (nsQuota != HdfsConstants.QUOTA_DONT_SET
|| ssQuota != HdfsConstants.QUOTA_DONT_SET) {
HdfsFileStatus ret = this.router.getRpcServer().getFileInfo(path); HdfsFileStatus ret = this.router.getRpcServer().getFileInfo(path);
if (ret != null) { if (ret != null) {
this.router.getRpcServer().getQuotaModule().setQuota(path, nsQuota, this.router.getRpcServer().getQuotaModule().setQuota(path, nsQuota,
@ -278,6 +280,9 @@ public class RouterAdminServer extends AbstractService
@Override @Override
public RemoveMountTableEntryResponse removeMountTableEntry( public RemoveMountTableEntryResponse removeMountTableEntry(
RemoveMountTableEntryRequest request) throws IOException { RemoveMountTableEntryRequest request) throws IOException {
// clear sub-cluster's quota definition
synchronizeQuota(request.getSrcPath(), HdfsConstants.QUOTA_RESET,
HdfsConstants.QUOTA_RESET);
return getMountTableStore().removeMountTableEntry(request); return getMountTableStore().removeMountTableEntry(request);
} }

View File

@ -447,7 +447,9 @@
<name>dfs.federation.router.quota.enable</name> <name>dfs.federation.router.quota.enable</name>
<value>false</value> <value>false</value>
<description> <description>
Set to true to enable quota system in Router. Set to true to enable quota system in Router. When it's enabled, setting
or clearing sub-cluster's quota directly is not recommended since Router
Admin server will override sub-cluster's quota with global quota.
</description> </description>
</property> </property>

View File

@ -143,6 +143,8 @@ For performance reasons, the Router caches the quota usage and updates it period
will be used for quota-verification during each WRITE RPC call invoked in RouterRPCSever. See [HDFS Quotas Guide](../hadoop-hdfs/HdfsQuotaAdminGuide.html) will be used for quota-verification during each WRITE RPC call invoked in RouterRPCSever. See [HDFS Quotas Guide](../hadoop-hdfs/HdfsQuotaAdminGuide.html)
for the quota detail. for the quota detail.
Note: When global quota is enabled, setting or clearing sub-cluster's quota directly is not recommended since Router Admin server will override sub-cluster's quota with global quota.
### State Store ### State Store
The (logically centralized, but physically distributed) State Store maintains: The (logically centralized, but physically distributed) State Store maintains:
@ -421,7 +423,7 @@ Global quota supported in federation.
| Property | Default | Description| | Property | Default | Description|
|:---- |:---- |:---- | |:---- |:---- |:---- |
| dfs.federation.router.quota.enable | `false` | If `true`, the quota system enabled in the Router. | | dfs.federation.router.quota.enable | `false` | If `true`, the quota system enabled in the Router. In that case, setting or clearing sub-cluster's quota directly is not recommended since Router Admin server will override sub-cluster's quota with global quota.|
| dfs.federation.router.quota-cache.update.interval | 60s | How often the Router updates quota cache. This setting supports multiple time unit suffixes. If no suffix is specified then milliseconds is assumed. | | dfs.federation.router.quota-cache.update.interval | 60s | How often the Router updates quota cache. This setting supports multiple time unit suffixes. If no suffix is specified then milliseconds is assumed. |
Metrics Metrics

View File

@ -605,7 +605,7 @@ public class TestRouterQuota {
@Test @Test
public void testQuotaRefreshWhenDestinationNotPresent() throws Exception { public void testQuotaRefreshWhenDestinationNotPresent() throws Exception {
long nsQuota = 5; long nsQuota = 5;
long ssQuota = 3*BLOCK_SIZE; long ssQuota = 3 * BLOCK_SIZE;
final FileSystem nnFs = nnContext1.getFileSystem(); final FileSystem nnFs = nnContext1.getFileSystem();
// Add three mount tables: // Add three mount tables:
@ -709,4 +709,50 @@ public class TestRouterQuota {
assertEquals(updatedSpace, cacheQuota2.getSpaceConsumed()); assertEquals(updatedSpace, cacheQuota2.getSpaceConsumed());
assertEquals(updatedSpace, mountQuota2.getSpaceConsumed()); assertEquals(updatedSpace, mountQuota2.getSpaceConsumed());
} }
@Test
public void testClearQuotaDefAfterRemovingMountTable() throws Exception {
long nsQuota = 5;
long ssQuota = 3 * BLOCK_SIZE;
final FileSystem nnFs = nnContext1.getFileSystem();
// Add one mount tables:
// /setdir --> ns0---testdir15
// Create destination directory
nnFs.mkdirs(new Path("/testdir15"));
MountTable mountTable = MountTable.newInstance("/setdir",
Collections.singletonMap("ns0", "/testdir15"));
mountTable.setQuota(new RouterQuotaUsage.Builder().quota(nsQuota)
.spaceQuota(ssQuota).build());
addMountTable(mountTable);
// Update router quota
RouterQuotaUpdateService updateService =
routerContext.getRouter().getQuotaCacheUpdateService();
updateService.periodicInvoke();
RouterQuotaManager quotaManager =
routerContext.getRouter().getQuotaManager();
ClientProtocol client = nnContext1.getClient().getNamenode();
QuotaUsage routerQuota = quotaManager.getQuotaUsage("/setdir");
QuotaUsage subClusterQuota = client.getQuotaUsage("/testdir15");
// Verify current quota definitions
assertEquals(nsQuota, routerQuota.getQuota());
assertEquals(ssQuota, routerQuota.getSpaceQuota());
assertEquals(nsQuota, subClusterQuota.getQuota());
assertEquals(ssQuota, subClusterQuota.getSpaceQuota());
// Remove mount table
removeMountTable("/setdir");
updateService.periodicInvoke();
routerQuota = quotaManager.getQuotaUsage("/setdir");
subClusterQuota = client.getQuotaUsage("/testdir15");
// Verify quota definitions are cleared after removing the mount table
assertNull(routerQuota);
assertEquals(HdfsConstants.QUOTA_RESET, subClusterQuota.getQuota());
assertEquals(HdfsConstants.QUOTA_RESET, subClusterQuota.getSpaceQuota());
}
} }