rmdmattingly commented on code in PR #6451:
URL: https://github.com/apache/hbase/pull/6451#discussion_r1834626996


##########
hbase-server/src/test/java/org/apache/hadoop/hbase/quotas/TestQuotaUserOverride.java:
##########
@@ -78,39 +78,32 @@ public static void tearDownAfterClass() throws Exception {
   @Test
   public void testUserGlobalThrottleWithCustomOverride() throws Exception {
     final Admin admin = TEST_UTIL.getAdmin();
-    final String userOverrideWithQuota = User.getCurrent().getShortName() + 
"123";
+    final String userOverrideWithQuota = User.getCurrent().getShortName();

Review Comment:
   I made a few small test changes to ensure that refreshes were called 
appropriately. Because of the logic in 
`ThrottleQuotaTestUtil.triggerUserCacheRefresh` assuming that we're waiting on 
throttling for the current user, I also had to change around the procedure of 
this test a bit to ensure that the current user is who we're throttling (rather 
than the current user plus a suffix, like we were before). But the logic is 
still sound



##########
hbase-server/src/main/java/org/apache/hadoop/hbase/quotas/QuotaCache.java:
##########
@@ -395,21 +429,40 @@ private <K, V extends QuotaState> void fetch(final String 
type,
      * over table quota, use [1 / TotalTableRegionNum * MachineTableRegionNum] 
as machine factor.
      */
     private void updateQuotaFactors() {
-      // Update machine quota factor
-      ClusterMetrics clusterMetrics;
-      try {
-        clusterMetrics = rsServices.getConnection().getAdmin()
-          .getClusterMetrics(EnumSet.of(Option.SERVERS_NAME, 
Option.TABLE_TO_REGIONS_COUNT));
-      } catch (IOException e) {
-        LOG.warn("Failed to get cluster metrics needed for updating quotas", 
e);
-        return;
+      boolean hasTableQuotas = !tableQuotaCache.entrySet().isEmpty()
+        || 
userQuotaCache.values().stream().anyMatch(UserQuotaState::hasTableLimiters);
+      if (hasTableQuotas) {
+        updateTableMachineQuotaFactors();
+      } else {
+        updateOnlyMachineQuotaFactors();

Review Comment:
   This check ensures that we only pull down every region state if we actually 
need to. Without table machine quotas, there is no point



##########
hbase-server/src/main/java/org/apache/hadoop/hbase/quotas/QuotaCache.java:
##########
@@ -436,6 +489,52 @@ private void updateQuotaFactors() {
         }
       }
     }
+
+    private void updateMachineQuotaFactors(int rsSize) {
+      if (rsSize != 0) {
+        // TODO if use rs group, the cluster limit should be shared by the rs 
group
+        machineQuotaFactor = 1.0 / rsSize;
+      }
+    }
+  }
+
+  static class RefreshableExpiringValueCache<T> {

Review Comment:
   I made this class because I don't think there's a good keyless equivalent to 
a LoadingCache, and a memoized supplier does not offer all of the functionality 
that I'd like (on-demand refresh, invalidation)



##########
hbase-server/src/main/java/org/apache/hadoop/hbase/quotas/QuotaCache.java:
##########
@@ -140,8 +150,7 @@ public QuotaLimiter getUserLimiter(final 
UserGroupInformation ugi, final TableNa
    */
   public UserQuotaState getUserQuotaState(final UserGroupInformation ugi) {
     return computeIfAbsent(userQuotaCache, getQuotaUserName(ugi),
-      () -> 
QuotaUtil.buildDefaultUserQuotaState(rsServices.getConfiguration(), 0L),
-      this::triggerCacheRefresh);
+      () -> 
QuotaUtil.buildDefaultUserQuotaState(rsServices.getConfiguration(), 0L));

Review Comment:
   The change here, and in getQuotaState, are critical. These changes ensure 
that each cache miss does not trigger an immediate refresh — particularly given 
that cache entries are evicted after 5 refresh periods, this approach is too 
heavy handed.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscr...@hbase.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org

Reply via email to