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