001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.apache.hadoop.hbase.quotas; 019 020import static org.apache.hadoop.hbase.quotas.ThrottleQuotaTestUtil.doGets; 021import static org.apache.hadoop.hbase.quotas.ThrottleQuotaTestUtil.doPuts; 022import static org.apache.hadoop.hbase.quotas.ThrottleQuotaTestUtil.triggerExceedThrottleQuotaCacheRefresh; 023import static org.apache.hadoop.hbase.quotas.ThrottleQuotaTestUtil.triggerNamespaceCacheRefresh; 024import static org.apache.hadoop.hbase.quotas.ThrottleQuotaTestUtil.triggerRegionServerCacheRefresh; 025import static org.apache.hadoop.hbase.quotas.ThrottleQuotaTestUtil.triggerTableCacheRefresh; 026import static org.apache.hadoop.hbase.quotas.ThrottleQuotaTestUtil.triggerUserCacheRefresh; 027import static org.apache.hadoop.hbase.quotas.ThrottleQuotaTestUtil.waitMinuteQuota; 028import static org.junit.jupiter.api.Assertions.assertEquals; 029import static org.junit.jupiter.api.Assertions.assertTrue; 030 031import java.io.IOException; 032import java.util.List; 033import java.util.concurrent.TimeUnit; 034import org.apache.hadoop.hbase.HBaseTestingUtil; 035import org.apache.hadoop.hbase.HConstants; 036import org.apache.hadoop.hbase.TableName; 037import org.apache.hadoop.hbase.client.Admin; 038import org.apache.hadoop.hbase.client.Get; 039import org.apache.hadoop.hbase.client.Table; 040import org.apache.hadoop.hbase.security.User; 041import org.apache.hadoop.hbase.testclassification.MediumTests; 042import org.apache.hadoop.hbase.testclassification.RegionServerTests; 043import org.apache.hadoop.hbase.util.Bytes; 044import org.apache.hadoop.hbase.util.EnvironmentEdgeManager; 045import org.junit.jupiter.api.AfterAll; 046import org.junit.jupiter.api.AfterEach; 047import org.junit.jupiter.api.BeforeAll; 048import org.junit.jupiter.api.Disabled; 049import org.junit.jupiter.api.Tag; 050import org.junit.jupiter.api.Test; 051import org.slf4j.Logger; 052import org.slf4j.LoggerFactory; 053 054// This tests breaks monotonic WAL numbering after HBASE-20746 because of how it 055// manipulates the EnvironmentEdge. 056@Disabled("See HBASE-27243") 057@Tag(RegionServerTests.TAG) 058@Tag(MediumTests.TAG) 059public class TestQuotaThrottle { 060 061 private final static Logger LOG = LoggerFactory.getLogger(TestQuotaThrottle.class); 062 063 private final static int REFRESH_TIME = 30 * 60000; 064 065 private final static HBaseTestingUtil TEST_UTIL = new HBaseTestingUtil(); 066 private final static byte[] FAMILY = Bytes.toBytes("cf"); 067 private final static byte[] QUALIFIER = Bytes.toBytes("q"); 068 069 private final static TableName[] TABLE_NAMES = 070 new TableName[] { TableName.valueOf("TestQuotaAdmin0"), TableName.valueOf("TestQuotaAdmin1"), 071 TableName.valueOf("TestQuotaAdmin2") }; 072 073 private static Table[] tables; 074 075 @BeforeAll 076 public static void setUpBeforeClass() throws Exception { 077 TEST_UTIL.getConfiguration().setBoolean(QuotaUtil.QUOTA_CONF_KEY, true); 078 TEST_UTIL.getConfiguration().setInt(QuotaCache.REFRESH_CONF_KEY, REFRESH_TIME); 079 TEST_UTIL.getConfiguration().setInt("hbase.hstore.compactionThreshold", 10); 080 TEST_UTIL.getConfiguration().setInt("hbase.regionserver.msginterval", 100); 081 TEST_UTIL.getConfiguration().setInt("hbase.client.pause", 250); 082 TEST_UTIL.getConfiguration().setInt(HConstants.HBASE_CLIENT_RETRIES_NUMBER, 6); 083 TEST_UTIL.getConfiguration().setBoolean("hbase.master.enabletable.roundrobin", true); 084 TEST_UTIL.startMiniCluster(1); 085 TEST_UTIL.waitTableAvailable(QuotaTableUtil.QUOTA_TABLE_NAME); 086 087 tables = new Table[TABLE_NAMES.length]; 088 for (int i = 0; i < TABLE_NAMES.length; ++i) { 089 tables[i] = TEST_UTIL.createTable(TABLE_NAMES[i], FAMILY); 090 } 091 } 092 093 @AfterAll 094 public static void tearDownAfterClass() throws Exception { 095 EnvironmentEdgeManager.reset(); 096 for (int i = 0; i < tables.length; ++i) { 097 if (tables[i] != null) { 098 tables[i].close(); 099 TEST_UTIL.deleteTable(TABLE_NAMES[i]); 100 } 101 } 102 103 TEST_UTIL.shutdownMiniCluster(); 104 } 105 106 @AfterEach 107 public void tearDown() throws Exception { 108 ThrottleQuotaTestUtil.clearQuotaCache(TEST_UTIL); 109 } 110 111 @Test 112 public void testUserGlobalThrottle() throws Exception { 113 final Admin admin = TEST_UTIL.getAdmin(); 114 final String userName = User.getCurrent().getShortName(); 115 116 // Add 6req/min limit 117 admin.setQuota(QuotaSettingsFactory.throttleUser(userName, ThrottleType.REQUEST_NUMBER, 6, 118 TimeUnit.MINUTES)); 119 triggerUserCacheRefresh(TEST_UTIL, false, TABLE_NAMES); 120 121 // should execute at max 6 requests 122 assertEquals(6, doPuts(100, FAMILY, QUALIFIER, tables)); 123 124 // wait a minute and you should get other 6 requests executed 125 waitMinuteQuota(); 126 assertEquals(6, doPuts(100, FAMILY, QUALIFIER, tables)); 127 128 // Remove all the limits 129 admin.setQuota(QuotaSettingsFactory.unthrottleUser(userName)); 130 triggerUserCacheRefresh(TEST_UTIL, true, TABLE_NAMES); 131 assertEquals(60, doPuts(60, FAMILY, QUALIFIER, tables)); 132 assertEquals(60, doGets(60, tables)); 133 } 134 135 @Test 136 public void testUserGlobalReadAndWriteThrottle() throws Exception { 137 final Admin admin = TEST_UTIL.getAdmin(); 138 final String userName = User.getCurrent().getShortName(); 139 140 // Add 6req/min limit for read request 141 admin.setQuota( 142 QuotaSettingsFactory.throttleUser(userName, ThrottleType.READ_NUMBER, 6, TimeUnit.MINUTES)); 143 triggerUserCacheRefresh(TEST_UTIL, false, TABLE_NAMES); 144 145 // not limit for write request and should execute at max 6 read requests 146 assertEquals(60, doPuts(60, FAMILY, QUALIFIER, tables)); 147 assertEquals(6, doGets(100, tables)); 148 149 waitMinuteQuota(); 150 151 // Add 6req/min limit for write request 152 admin.setQuota( 153 QuotaSettingsFactory.throttleUser(userName, ThrottleType.WRITE_NUMBER, 6, TimeUnit.MINUTES)); 154 triggerUserCacheRefresh(TEST_UTIL, false, TABLE_NAMES); 155 156 // should execute at max 6 read requests and at max 6 write write requests 157 assertEquals(6, doGets(100, tables)); 158 assertEquals(6, doPuts(60, FAMILY, QUALIFIER, tables)); 159 160 // Remove all the limits 161 admin.setQuota(QuotaSettingsFactory.unthrottleUser(userName)); 162 triggerUserCacheRefresh(TEST_UTIL, true, TABLE_NAMES); 163 assertEquals(60, doPuts(60, FAMILY, QUALIFIER, tables)); 164 assertEquals(60, doGets(60, tables)); 165 } 166 167 @Test 168 public void testUserTableThrottle() throws Exception { 169 final Admin admin = TEST_UTIL.getAdmin(); 170 final String userName = User.getCurrent().getShortName(); 171 172 // Add 6req/min limit 173 admin.setQuota(QuotaSettingsFactory.throttleUser(userName, TABLE_NAMES[0], 174 ThrottleType.REQUEST_NUMBER, 6, TimeUnit.MINUTES)); 175 triggerUserCacheRefresh(TEST_UTIL, false, TABLE_NAMES[0]); 176 177 // should execute at max 6 requests on tables[0] and have no limit on tables[1] 178 assertEquals(6, doPuts(100, FAMILY, QUALIFIER, tables[0])); 179 assertEquals(30, doPuts(30, FAMILY, QUALIFIER, tables[1])); 180 181 // wait a minute and you should get other 6 requests executed 182 waitMinuteQuota(); 183 assertEquals(6, doPuts(100, FAMILY, QUALIFIER, tables[0])); 184 185 // Remove all the limits 186 admin.setQuota(QuotaSettingsFactory.unthrottleUser(userName, TABLE_NAMES[0])); 187 triggerUserCacheRefresh(TEST_UTIL, true, TABLE_NAMES); 188 assertEquals(60, doPuts(60, FAMILY, QUALIFIER, tables)); 189 assertEquals(60, doGets(60, tables)); 190 } 191 192 @Test 193 public void testUserTableReadAndWriteThrottle() throws Exception { 194 final Admin admin = TEST_UTIL.getAdmin(); 195 final String userName = User.getCurrent().getShortName(); 196 197 // Add 6req/min limit for write request on tables[0] 198 admin.setQuota(QuotaSettingsFactory.throttleUser(userName, TABLE_NAMES[0], 199 ThrottleType.WRITE_NUMBER, 6, TimeUnit.MINUTES)); 200 triggerUserCacheRefresh(TEST_UTIL, false, TABLE_NAMES[0]); 201 202 // should execute at max 6 write requests and have no limit for read request 203 assertEquals(6, doPuts(100, FAMILY, QUALIFIER, tables[0])); 204 assertEquals(60, doGets(60, tables[0])); 205 206 // no limit on tables[1] 207 assertEquals(60, doPuts(60, FAMILY, QUALIFIER, tables[1])); 208 assertEquals(60, doGets(60, tables[1])); 209 210 // wait a minute and you should get other 6 write requests executed 211 waitMinuteQuota(); 212 213 // Add 6req/min limit for read request on tables[0] 214 admin.setQuota(QuotaSettingsFactory.throttleUser(userName, TABLE_NAMES[0], 215 ThrottleType.READ_NUMBER, 6, TimeUnit.MINUTES)); 216 triggerUserCacheRefresh(TEST_UTIL, false, TABLE_NAMES[0]); 217 218 // should execute at max 6 read requests and at max 6 write requests 219 assertEquals(6, doPuts(100, FAMILY, QUALIFIER, tables[0])); 220 assertEquals(6, doGets(60, tables[0])); 221 222 // no limit on tables[1] 223 assertEquals(30, doPuts(30, FAMILY, QUALIFIER, tables[1])); 224 assertEquals(30, doGets(30, tables[1])); 225 226 // Remove all the limits 227 admin.setQuota(QuotaSettingsFactory.unthrottleUser(userName, TABLE_NAMES[0])); 228 triggerUserCacheRefresh(TEST_UTIL, true, TABLE_NAMES); 229 assertEquals(60, doPuts(60, FAMILY, QUALIFIER, tables)); 230 assertEquals(60, doGets(60, tables)); 231 } 232 233 @Test 234 public void testUserNamespaceThrottle() throws Exception { 235 final Admin admin = TEST_UTIL.getAdmin(); 236 final String userName = User.getCurrent().getShortName(); 237 final String NAMESPACE = "default"; 238 239 // Add 6req/min limit 240 admin.setQuota(QuotaSettingsFactory.throttleUser(userName, NAMESPACE, 241 ThrottleType.REQUEST_NUMBER, 6, TimeUnit.MINUTES)); 242 triggerUserCacheRefresh(TEST_UTIL, false, TABLE_NAMES[0]); 243 244 // should execute at max 6 requests on tables[0] and have no limit on tables[1] 245 assertEquals(6, doPuts(100, FAMILY, QUALIFIER, tables[0])); 246 247 // wait a minute and you should get other 6 requests executed 248 waitMinuteQuota(); 249 assertEquals(6, doPuts(100, FAMILY, QUALIFIER, tables[1])); 250 251 // Remove all the limits 252 admin.setQuota(QuotaSettingsFactory.unthrottleUser(userName, NAMESPACE)); 253 triggerUserCacheRefresh(TEST_UTIL, true, TABLE_NAMES); 254 assertEquals(60, doPuts(60, FAMILY, QUALIFIER, tables)); 255 assertEquals(60, doGets(60, tables)); 256 } 257 258 @Test 259 public void testUserNamespaceReadAndWriteThrottle() throws Exception { 260 final Admin admin = TEST_UTIL.getAdmin(); 261 final String userName = User.getCurrent().getShortName(); 262 final String NAMESPACE = "default"; 263 264 // Add 6req/min limit for read request 265 admin.setQuota(QuotaSettingsFactory.throttleUser(userName, NAMESPACE, ThrottleType.READ_NUMBER, 266 6, TimeUnit.MINUTES)); 267 triggerUserCacheRefresh(TEST_UTIL, false, TABLE_NAMES[0]); 268 269 // should execute at max 6 read requests and have no limit for write request 270 assertEquals(6, doGets(60, tables[0])); 271 assertEquals(60, doPuts(60, FAMILY, QUALIFIER, tables[0])); 272 273 waitMinuteQuota(); 274 275 // Add 6req/min limit for write request, too 276 admin.setQuota(QuotaSettingsFactory.throttleUser(userName, NAMESPACE, ThrottleType.WRITE_NUMBER, 277 6, TimeUnit.MINUTES)); 278 triggerUserCacheRefresh(TEST_UTIL, false, TABLE_NAMES[0]); 279 280 // should execute at max 6 read requests and at max 6 write requests 281 assertEquals(6, doGets(60, tables[0])); 282 assertEquals(6, doPuts(60, FAMILY, QUALIFIER, tables[0])); 283 284 // Remove all the limits 285 admin.setQuota(QuotaSettingsFactory.unthrottleUser(userName, NAMESPACE)); 286 triggerUserCacheRefresh(TEST_UTIL, true, TABLE_NAMES); 287 assertEquals(60, doPuts(60, FAMILY, QUALIFIER, tables)); 288 assertEquals(60, doGets(60, tables)); 289 } 290 291 @Test 292 public void testTableGlobalThrottle() throws Exception { 293 final Admin admin = TEST_UTIL.getAdmin(); 294 295 // Add 6req/min limit 296 admin.setQuota(QuotaSettingsFactory.throttleTable(TABLE_NAMES[0], ThrottleType.REQUEST_NUMBER, 297 6, TimeUnit.MINUTES)); 298 triggerTableCacheRefresh(TEST_UTIL, false, TABLE_NAMES[0]); 299 300 // should execute at max 6 requests 301 assertEquals(6, doPuts(100, FAMILY, QUALIFIER, tables[0])); 302 // should have no limits 303 assertEquals(30, doPuts(30, FAMILY, QUALIFIER, tables[1])); 304 305 // wait a minute and you should get other 6 requests executed 306 waitMinuteQuota(); 307 assertEquals(6, doPuts(100, FAMILY, QUALIFIER, tables[0])); 308 309 // Remove all the limits 310 admin.setQuota(QuotaSettingsFactory.unthrottleTable(TABLE_NAMES[0])); 311 triggerTableCacheRefresh(TEST_UTIL, true, TABLE_NAMES[0]); 312 assertEquals(80, doGets(80, tables[0], tables[1])); 313 } 314 315 @Test 316 public void testTableGlobalReadAndWriteThrottle() throws Exception { 317 final Admin admin = TEST_UTIL.getAdmin(); 318 319 // Add 6req/min limit for read request 320 admin.setQuota(QuotaSettingsFactory.throttleTable(TABLE_NAMES[0], ThrottleType.READ_NUMBER, 6, 321 TimeUnit.MINUTES)); 322 triggerTableCacheRefresh(TEST_UTIL, false, TABLE_NAMES[0]); 323 324 // should execute at max 6 read requests and have no limit for write request 325 assertEquals(6, doGets(100, tables[0])); 326 assertEquals(100, doPuts(100, FAMILY, QUALIFIER, tables[0])); 327 // should have no limits on tables[1] 328 assertEquals(30, doPuts(30, FAMILY, QUALIFIER, tables[1])); 329 assertEquals(30, doGets(30, tables[1])); 330 331 // wait a minute and you should get other 6 requests executed 332 waitMinuteQuota(); 333 334 // Add 6req/min limit for write request, too 335 admin.setQuota(QuotaSettingsFactory.throttleTable(TABLE_NAMES[0], ThrottleType.WRITE_NUMBER, 6, 336 TimeUnit.MINUTES)); 337 triggerTableCacheRefresh(TEST_UTIL, false, TABLE_NAMES[0]); 338 339 // should execute at max 6 read requests and at max 6 write requests 340 assertEquals(6, doGets(100, tables[0])); 341 assertEquals(6, doPuts(100, FAMILY, QUALIFIER, tables[0])); 342 // should have no limits on tables[1] 343 assertEquals(30, doPuts(30, FAMILY, QUALIFIER, tables[1])); 344 assertEquals(30, doGets(30, tables[1])); 345 346 // Remove all the limits 347 admin.setQuota(QuotaSettingsFactory.unthrottleTable(TABLE_NAMES[0])); 348 triggerTableCacheRefresh(TEST_UTIL, true, TABLE_NAMES[0]); 349 assertEquals(80, doGets(80, tables[0], tables[1])); 350 } 351 352 @Test 353 public void testNamespaceGlobalThrottle() throws Exception { 354 final Admin admin = TEST_UTIL.getAdmin(); 355 final String NAMESPACE = "default"; 356 357 // Add 6req/min limit 358 admin.setQuota(QuotaSettingsFactory.throttleNamespace(NAMESPACE, ThrottleType.REQUEST_NUMBER, 6, 359 TimeUnit.MINUTES)); 360 triggerNamespaceCacheRefresh(TEST_UTIL, false, TABLE_NAMES[0]); 361 362 // should execute at max 6 requests 363 assertEquals(6, doPuts(100, FAMILY, QUALIFIER, tables[0])); 364 365 // wait a minute and you should get other 6 requests executed 366 waitMinuteQuota(); 367 assertEquals(6, doPuts(100, FAMILY, QUALIFIER, tables[1])); 368 369 admin.setQuota(QuotaSettingsFactory.unthrottleNamespace(NAMESPACE)); 370 triggerNamespaceCacheRefresh(TEST_UTIL, true, TABLE_NAMES[0]); 371 assertEquals(40, doPuts(40, FAMILY, QUALIFIER, tables[0])); 372 } 373 374 @Test 375 public void testNamespaceGlobalReadAndWriteThrottle() throws Exception { 376 final Admin admin = TEST_UTIL.getAdmin(); 377 final String NAMESPACE = "default"; 378 379 // Add 6req/min limit for write request 380 admin.setQuota(QuotaSettingsFactory.throttleNamespace(NAMESPACE, ThrottleType.WRITE_NUMBER, 6, 381 TimeUnit.MINUTES)); 382 triggerNamespaceCacheRefresh(TEST_UTIL, false, TABLE_NAMES[0]); 383 384 // should execute at max 6 write requests and no limit for read request 385 assertEquals(6, doPuts(100, FAMILY, QUALIFIER, tables[0])); 386 assertEquals(100, doGets(100, tables[0])); 387 388 // wait a minute and you should get other 6 requests executed 389 waitMinuteQuota(); 390 391 // Add 6req/min limit for read request, too 392 admin.setQuota(QuotaSettingsFactory.throttleNamespace(NAMESPACE, ThrottleType.READ_NUMBER, 6, 393 TimeUnit.MINUTES)); 394 triggerNamespaceCacheRefresh(TEST_UTIL, false, TABLE_NAMES[0]); 395 396 // should execute at max 6 write requests and at max 6 read requests 397 assertEquals(6, doPuts(100, FAMILY, QUALIFIER, tables[0])); 398 assertEquals(6, doGets(100, tables[0])); 399 400 admin.setQuota(QuotaSettingsFactory.unthrottleNamespace(NAMESPACE)); 401 triggerNamespaceCacheRefresh(TEST_UTIL, true, TABLE_NAMES[0]); 402 assertEquals(40, doPuts(40, FAMILY, QUALIFIER, tables[0])); 403 } 404 405 @Test 406 public void testUserAndTableThrottle() throws Exception { 407 final Admin admin = TEST_UTIL.getAdmin(); 408 final String userName = User.getCurrent().getShortName(); 409 410 // Add 6req/min limit for the user on tables[0] 411 admin.setQuota(QuotaSettingsFactory.throttleUser(userName, TABLE_NAMES[0], 412 ThrottleType.REQUEST_NUMBER, 6, TimeUnit.MINUTES)); 413 triggerUserCacheRefresh(TEST_UTIL, false, TABLE_NAMES[0]); 414 // Add 12req/min limit for the user 415 admin.setQuota(QuotaSettingsFactory.throttleUser(userName, ThrottleType.REQUEST_NUMBER, 12, 416 TimeUnit.MINUTES)); 417 triggerUserCacheRefresh(TEST_UTIL, false, TABLE_NAMES[1], TABLE_NAMES[2]); 418 // Add 8req/min limit for the tables[1] 419 admin.setQuota(QuotaSettingsFactory.throttleTable(TABLE_NAMES[1], ThrottleType.REQUEST_NUMBER, 420 8, TimeUnit.MINUTES)); 421 triggerTableCacheRefresh(TEST_UTIL, false, TABLE_NAMES[1]); 422 // Add a lower table level throttle on tables[0] 423 admin.setQuota(QuotaSettingsFactory.throttleTable(TABLE_NAMES[0], ThrottleType.REQUEST_NUMBER, 424 3, TimeUnit.MINUTES)); 425 triggerTableCacheRefresh(TEST_UTIL, false, TABLE_NAMES[0]); 426 427 // should execute at max 12 requests 428 assertEquals(12, doGets(100, tables[2])); 429 430 // should execute at max 8 requests 431 waitMinuteQuota(); 432 assertEquals(8, doGets(100, tables[1])); 433 434 // should execute at max 3 requests 435 waitMinuteQuota(); 436 assertEquals(3, doPuts(100, FAMILY, QUALIFIER, tables[0])); 437 438 // Remove all the throttling rules 439 admin.setQuota(QuotaSettingsFactory.unthrottleUser(userName, TABLE_NAMES[0])); 440 admin.setQuota(QuotaSettingsFactory.unthrottleUser(userName)); 441 triggerUserCacheRefresh(TEST_UTIL, true, TABLE_NAMES[0], TABLE_NAMES[1]); 442 443 admin.setQuota(QuotaSettingsFactory.unthrottleTable(TABLE_NAMES[1])); 444 triggerTableCacheRefresh(TEST_UTIL, true, TABLE_NAMES[1]); 445 waitMinuteQuota(); 446 assertEquals(40, doGets(40, tables[1])); 447 448 admin.setQuota(QuotaSettingsFactory.unthrottleTable(TABLE_NAMES[0])); 449 triggerTableCacheRefresh(TEST_UTIL, true, TABLE_NAMES[0]); 450 waitMinuteQuota(); 451 assertEquals(40, doGets(40, tables[0])); 452 } 453 454 @Test 455 public void testUserGlobalBypassThrottle() throws Exception { 456 final Admin admin = TEST_UTIL.getAdmin(); 457 final String userName = User.getCurrent().getShortName(); 458 final String NAMESPACE = "default"; 459 460 // Add 6req/min limit for tables[0] 461 admin.setQuota(QuotaSettingsFactory.throttleTable(TABLE_NAMES[0], ThrottleType.REQUEST_NUMBER, 462 6, TimeUnit.MINUTES)); 463 triggerTableCacheRefresh(TEST_UTIL, false, TABLE_NAMES[0]); 464 // Add 13req/min limit for the user 465 admin.setQuota(QuotaSettingsFactory.throttleNamespace(NAMESPACE, ThrottleType.REQUEST_NUMBER, 466 13, TimeUnit.MINUTES)); 467 triggerNamespaceCacheRefresh(TEST_UTIL, false, TABLE_NAMES[1]); 468 469 // should execute at max 6 requests on table[0] and (13 - 6) on table[1] 470 assertEquals(6, doPuts(100, FAMILY, QUALIFIER, tables[0])); 471 assertEquals(7, doGets(100, tables[1])); 472 waitMinuteQuota(); 473 474 // Set the global bypass for the user 475 admin.setQuota(QuotaSettingsFactory.bypassGlobals(userName, true)); 476 admin.setQuota(QuotaSettingsFactory.throttleUser(userName, TABLE_NAMES[2], 477 ThrottleType.REQUEST_NUMBER, 6, TimeUnit.MINUTES)); 478 triggerUserCacheRefresh(TEST_UTIL, false, TABLE_NAMES[2]); 479 assertEquals(30, doGets(30, tables[0])); 480 assertEquals(30, doGets(30, tables[1])); 481 waitMinuteQuota(); 482 483 // Remove the global bypass 484 // should execute at max 6 requests on table[0] and (13 - 6) on table[1] 485 admin.setQuota(QuotaSettingsFactory.bypassGlobals(userName, false)); 486 admin.setQuota(QuotaSettingsFactory.unthrottleUser(userName, TABLE_NAMES[2])); 487 triggerUserCacheRefresh(TEST_UTIL, true, TABLE_NAMES[2]); 488 assertEquals(6, doPuts(100, FAMILY, QUALIFIER, tables[0])); 489 assertEquals(7, doGets(100, tables[1])); 490 491 // unset throttle 492 admin.setQuota(QuotaSettingsFactory.unthrottleTable(TABLE_NAMES[0])); 493 admin.setQuota(QuotaSettingsFactory.unthrottleNamespace(NAMESPACE)); 494 waitMinuteQuota(); 495 triggerTableCacheRefresh(TEST_UTIL, true, TABLE_NAMES[0]); 496 triggerNamespaceCacheRefresh(TEST_UTIL, true, TABLE_NAMES[1]); 497 assertEquals(30, doGets(30, tables[0])); 498 assertEquals(30, doGets(30, tables[1])); 499 } 500 501 @Test 502 public void testTableWriteCapacityUnitThrottle() throws Exception { 503 final Admin admin = TEST_UTIL.getAdmin(); 504 505 // Add 6CU/min limit 506 admin.setQuota(QuotaSettingsFactory.throttleTable(TABLE_NAMES[0], 507 ThrottleType.WRITE_CAPACITY_UNIT, 6, TimeUnit.MINUTES)); 508 triggerTableCacheRefresh(TEST_UTIL, false, TABLE_NAMES[0]); 509 510 // should execute at max 6 capacity units because each put size is 1 capacity unit 511 assertEquals(6, doPuts(20, 10, FAMILY, QUALIFIER, tables[0])); 512 513 // wait a minute and you should execute at max 3 capacity units because each put size is 2 514 // capacity unit 515 waitMinuteQuota(); 516 assertEquals(3, doPuts(20, 1025, FAMILY, QUALIFIER, tables[0])); 517 518 admin.setQuota(QuotaSettingsFactory.unthrottleTable(TABLE_NAMES[0])); 519 triggerTableCacheRefresh(TEST_UTIL, true, TABLE_NAMES[0]); 520 } 521 522 @Test 523 public void testTableReadCapacityUnitThrottle() throws Exception { 524 final Admin admin = TEST_UTIL.getAdmin(); 525 526 // Add 6CU/min limit 527 admin.setQuota(QuotaSettingsFactory.throttleTable(TABLE_NAMES[0], 528 ThrottleType.READ_CAPACITY_UNIT, 6, TimeUnit.MINUTES)); 529 triggerTableCacheRefresh(TEST_UTIL, false, TABLE_NAMES[0]); 530 531 assertEquals(20, doPuts(20, 10, FAMILY, QUALIFIER, tables[0])); 532 // should execute at max 6 capacity units because each get size is 1 capacity unit 533 assertEquals(6, doGets(20, tables[0])); 534 535 assertEquals(20, doPuts(20, 2015, FAMILY, QUALIFIER, tables[0])); 536 // wait a minute and you should execute at max 3 capacity units because each get size is 2 537 // capacity unit on tables[0] 538 waitMinuteQuota(); 539 assertEquals(3, doGets(20, tables[0])); 540 541 admin.setQuota(QuotaSettingsFactory.unthrottleTable(TABLE_NAMES[0])); 542 triggerTableCacheRefresh(TEST_UTIL, true, TABLE_NAMES[0]); 543 } 544 545 @Test 546 public void testTableExistsGetThrottle() throws Exception { 547 final Admin admin = TEST_UTIL.getAdmin(); 548 549 // Add throttle quota 550 admin.setQuota(QuotaSettingsFactory.throttleTable(TABLE_NAMES[0], ThrottleType.REQUEST_NUMBER, 551 100, TimeUnit.MINUTES)); 552 triggerTableCacheRefresh(TEST_UTIL, false, TABLE_NAMES[0]); 553 554 Table table = TEST_UTIL.getConnection().getTable(TABLE_NAMES[0]); 555 // An exists call when having throttle quota 556 table.exists(new Get(Bytes.toBytes("abc"))); 557 558 admin.setQuota(QuotaSettingsFactory.unthrottleTable(TABLE_NAMES[0])); 559 triggerTableCacheRefresh(TEST_UTIL, true, TABLE_NAMES[0]); 560 } 561 562 @Test 563 public void testRegionServerThrottle() throws Exception { 564 final Admin admin = TEST_UTIL.getAdmin(); 565 admin.setQuota(QuotaSettingsFactory.throttleTable(TABLE_NAMES[0], ThrottleType.WRITE_NUMBER, 5, 566 TimeUnit.MINUTES)); 567 568 // requests are throttled by table quota 569 admin.setQuota(QuotaSettingsFactory.throttleRegionServer( 570 QuotaTableUtil.QUOTA_REGION_SERVER_ROW_KEY, ThrottleType.WRITE_NUMBER, 7, TimeUnit.MINUTES)); 571 triggerTableCacheRefresh(TEST_UTIL, false, TABLE_NAMES[0]); 572 triggerRegionServerCacheRefresh(TEST_UTIL, false); 573 assertEquals(5, doPuts(10, FAMILY, QUALIFIER, tables[0])); 574 triggerRegionServerCacheRefresh(TEST_UTIL, false); 575 assertEquals(5, doPuts(10, FAMILY, QUALIFIER, tables[0])); 576 577 // requests are throttled by region server quota 578 admin.setQuota(QuotaSettingsFactory.throttleRegionServer( 579 QuotaTableUtil.QUOTA_REGION_SERVER_ROW_KEY, ThrottleType.WRITE_NUMBER, 4, TimeUnit.MINUTES)); 580 triggerRegionServerCacheRefresh(TEST_UTIL, false); 581 assertEquals(4, doPuts(10, FAMILY, QUALIFIER, tables[0])); 582 triggerRegionServerCacheRefresh(TEST_UTIL, false); 583 assertEquals(4, doPuts(10, FAMILY, QUALIFIER, tables[0])); 584 585 // unthrottle 586 admin.setQuota( 587 QuotaSettingsFactory.unthrottleRegionServer(QuotaTableUtil.QUOTA_REGION_SERVER_ROW_KEY)); 588 triggerRegionServerCacheRefresh(TEST_UTIL, true); 589 admin.setQuota(QuotaSettingsFactory.unthrottleTable(TABLE_NAMES[0])); 590 triggerTableCacheRefresh(TEST_UTIL, true, TABLE_NAMES[0]); 591 triggerRegionServerCacheRefresh(TEST_UTIL, true); 592 } 593 594 @Test 595 public void testExceedThrottleQuota() throws Exception { 596 final Admin admin = TEST_UTIL.getAdmin(); 597 admin.setQuota(QuotaSettingsFactory.throttleTable(TABLE_NAMES[0], ThrottleType.WRITE_NUMBER, 5, 598 TimeUnit.MINUTES)); 599 triggerTableCacheRefresh(TEST_UTIL, false, TABLE_NAMES[0]); 600 admin.setQuota(QuotaSettingsFactory.throttleRegionServer( 601 QuotaTableUtil.QUOTA_REGION_SERVER_ROW_KEY, ThrottleType.WRITE_NUMBER, 20, TimeUnit.SECONDS)); 602 admin.setQuota(QuotaSettingsFactory.throttleRegionServer( 603 QuotaTableUtil.QUOTA_REGION_SERVER_ROW_KEY, ThrottleType.READ_NUMBER, 10, TimeUnit.SECONDS)); 604 triggerRegionServerCacheRefresh(TEST_UTIL, false); 605 606 // enable exceed throttle quota 607 admin.exceedThrottleQuotaSwitch(true); 608 // exceed table limit and allowed by region server limit 609 triggerExceedThrottleQuotaCacheRefresh(TEST_UTIL, true); 610 waitMinuteQuota(); 611 assertEquals(10, doPuts(10, FAMILY, QUALIFIER, tables[0])); 612 // exceed table limit and throttled by region server limit 613 waitMinuteQuota(); 614 assertEquals(20, doPuts(25, FAMILY, QUALIFIER, tables[0])); 615 616 // set region server limiter is lower than table limiter 617 admin.setQuota(QuotaSettingsFactory.throttleRegionServer( 618 QuotaTableUtil.QUOTA_REGION_SERVER_ROW_KEY, ThrottleType.WRITE_NUMBER, 2, TimeUnit.SECONDS)); 619 triggerRegionServerCacheRefresh(TEST_UTIL, false); 620 // throttled by region server limiter 621 waitMinuteQuota(); 622 assertEquals(2, doPuts(10, FAMILY, QUALIFIER, tables[0])); 623 admin.setQuota(QuotaSettingsFactory.throttleRegionServer( 624 QuotaTableUtil.QUOTA_REGION_SERVER_ROW_KEY, ThrottleType.WRITE_NUMBER, 20, TimeUnit.SECONDS)); 625 triggerRegionServerCacheRefresh(TEST_UTIL, false); 626 627 // disable exceed throttle quota 628 admin.exceedThrottleQuotaSwitch(false); 629 triggerExceedThrottleQuotaCacheRefresh(TEST_UTIL, false); 630 waitMinuteQuota(); 631 // throttled by table limit 632 assertEquals(5, doPuts(10, FAMILY, QUALIFIER, tables[0])); 633 634 // enable exceed throttle quota and unthrottle region server 635 admin.exceedThrottleQuotaSwitch(true); 636 triggerExceedThrottleQuotaCacheRefresh(TEST_UTIL, true); 637 waitMinuteQuota(); 638 admin.setQuota( 639 QuotaSettingsFactory.unthrottleRegionServer(QuotaTableUtil.QUOTA_REGION_SERVER_ROW_KEY)); 640 triggerRegionServerCacheRefresh(TEST_UTIL, true); 641 waitMinuteQuota(); 642 // throttled by table limit 643 assertEquals(5, doPuts(10, FAMILY, QUALIFIER, tables[0])); 644 645 // disable exceed throttle quota 646 admin.exceedThrottleQuotaSwitch(false); 647 triggerExceedThrottleQuotaCacheRefresh(TEST_UTIL, false); 648 // unthrottle table 649 admin.setQuota(QuotaSettingsFactory.unthrottleTable(TABLE_NAMES[0])); 650 triggerTableCacheRefresh(TEST_UTIL, true, TABLE_NAMES[0]); 651 } 652 653 @Test 654 public void testSetAndGetAllThrottleTypes() throws Exception { 655 for (ThrottleType throttleType : ThrottleType.values()) { 656 canSetAndGetUserThrottle(throttleType); 657 } 658 } 659 660 private void canSetAndGetUserThrottle(ThrottleType throttleType) throws IOException { 661 final Admin admin = TEST_UTIL.getAdmin(); 662 final String userName = User.getCurrent().getShortName(); 663 664 QuotaSettings setQuota = 665 QuotaSettingsFactory.throttleUser(userName, throttleType, 123, TimeUnit.SECONDS); 666 admin.setQuota(setQuota); 667 668 boolean found = false; 669 List<QuotaSettings> quotaSettings = admin.getQuota(new QuotaFilter().setUserFilter(userName)); 670 for (QuotaSettings settings : quotaSettings) { 671 if (settings instanceof ThrottleSettings) { 672 ThrottleSettings throttle = (ThrottleSettings) settings; 673 if ( 674 userName.equals(throttle.getUserName()) && throttle.getThrottleType() == throttleType 675 && throttle.getSoftLimit() == 123 && throttle.getTimeUnit() == TimeUnit.SECONDS 676 ) { 677 found = true; 678 break; 679 } 680 } 681 } 682 683 assertTrue(found, "Expected to find " + throttleType.name() + " quota for user " + userName); 684 admin.setQuota(QuotaSettingsFactory.unthrottleUserByThrottleType(userName, throttleType)); 685 } 686 687}