blob: 8495cd2c818566c4d180f7ab1671ab935789bd08 [file] [log] [blame]
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hadoop.hbase.quotas;
import static org.apache.hadoop.hbase.quotas.ThrottleQuotaTestUtil.doGets;
import static org.apache.hadoop.hbase.quotas.ThrottleQuotaTestUtil.doPuts;
import static org.apache.hadoop.hbase.quotas.ThrottleQuotaTestUtil.triggerExceedThrottleQuotaCacheRefresh;
import static org.apache.hadoop.hbase.quotas.ThrottleQuotaTestUtil.triggerNamespaceCacheRefresh;
import static org.apache.hadoop.hbase.quotas.ThrottleQuotaTestUtil.triggerRegionServerCacheRefresh;
import static org.apache.hadoop.hbase.quotas.ThrottleQuotaTestUtil.triggerTableCacheRefresh;
import static org.apache.hadoop.hbase.quotas.ThrottleQuotaTestUtil.triggerUserCacheRefresh;
import static org.apache.hadoop.hbase.quotas.ThrottleQuotaTestUtil.waitMinuteQuota;
import static org.junit.Assert.assertEquals;
import java.util.concurrent.TimeUnit;
import org.apache.hadoop.hbase.HBaseClassTestRule;
import org.apache.hadoop.hbase.HBaseTestingUtility;
import org.apache.hadoop.hbase.HConstants;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.Admin;
import org.apache.hadoop.hbase.client.Get;
import org.apache.hadoop.hbase.client.Table;
import org.apache.hadoop.hbase.security.User;
import org.apache.hadoop.hbase.testclassification.MediumTests;
import org.apache.hadoop.hbase.testclassification.RegionServerTests;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.ClassRule;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@Ignore // Disabled because flakey. Fails ~30% on a resource constrained GCE though not on Apache.
@Category({RegionServerTests.class, MediumTests.class})
public class TestQuotaThrottle {
@ClassRule
public static final HBaseClassTestRule CLASS_RULE =
HBaseClassTestRule.forClass(TestQuotaThrottle.class);
private final static Logger LOG = LoggerFactory.getLogger(TestQuotaThrottle.class);
private final static int REFRESH_TIME = 30 * 60000;
private final static HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
private final static byte[] FAMILY = Bytes.toBytes("cf");
private final static byte[] QUALIFIER = Bytes.toBytes("q");
private final static TableName[] TABLE_NAMES = new TableName[] {
TableName.valueOf("TestQuotaAdmin0"),
TableName.valueOf("TestQuotaAdmin1"),
TableName.valueOf("TestQuotaAdmin2")
};
private static Table[] tables;
@BeforeClass
public static void setUpBeforeClass() throws Exception {
TEST_UTIL.getConfiguration().setBoolean(QuotaUtil.QUOTA_CONF_KEY, true);
TEST_UTIL.getConfiguration().setInt(QuotaCache.REFRESH_CONF_KEY, REFRESH_TIME);
TEST_UTIL.getConfiguration().setInt("hbase.hstore.compactionThreshold", 10);
TEST_UTIL.getConfiguration().setInt("hbase.regionserver.msginterval", 100);
TEST_UTIL.getConfiguration().setInt("hbase.client.pause", 250);
TEST_UTIL.getConfiguration().setInt(HConstants.HBASE_CLIENT_RETRIES_NUMBER, 6);
TEST_UTIL.getConfiguration().setBoolean("hbase.master.enabletable.roundrobin", true);
TEST_UTIL.startMiniCluster(1);
TEST_UTIL.waitTableAvailable(QuotaTableUtil.QUOTA_TABLE_NAME);
QuotaCache.TEST_FORCE_REFRESH = true;
tables = new Table[TABLE_NAMES.length];
for (int i = 0; i < TABLE_NAMES.length; ++i) {
tables[i] = TEST_UTIL.createTable(TABLE_NAMES[i], FAMILY);
}
}
@AfterClass
public static void tearDownAfterClass() throws Exception {
EnvironmentEdgeManager.reset();
for (int i = 0; i < tables.length; ++i) {
if (tables[i] != null) {
tables[i].close();
TEST_UTIL.deleteTable(TABLE_NAMES[i]);
}
}
TEST_UTIL.shutdownMiniCluster();
}
@After
public void tearDown() throws Exception {
ThrottleQuotaTestUtil.clearQuotaCache(TEST_UTIL);
}
@Test
public void testUserGlobalThrottle() throws Exception {
final Admin admin = TEST_UTIL.getAdmin();
final String userName = User.getCurrent().getShortName();
// Add 6req/min limit
admin.setQuota(QuotaSettingsFactory.throttleUser(userName, ThrottleType.REQUEST_NUMBER, 6,
TimeUnit.MINUTES));
triggerUserCacheRefresh(TEST_UTIL, false, TABLE_NAMES);
// should execute at max 6 requests
assertEquals(6, doPuts(100, FAMILY, QUALIFIER, tables));
// wait a minute and you should get other 6 requests executed
waitMinuteQuota();
assertEquals(6, doPuts(100, FAMILY, QUALIFIER, tables));
// Remove all the limits
admin.setQuota(QuotaSettingsFactory.unthrottleUser(userName));
triggerUserCacheRefresh(TEST_UTIL, true, TABLE_NAMES);
assertEquals(60, doPuts(60, FAMILY, QUALIFIER, tables));
assertEquals(60, doGets(60, tables));
}
@Test
public void testUserGlobalReadAndWriteThrottle() throws Exception {
final Admin admin = TEST_UTIL.getAdmin();
final String userName = User.getCurrent().getShortName();
// Add 6req/min limit for read request
admin.setQuota(
QuotaSettingsFactory.throttleUser(userName, ThrottleType.READ_NUMBER, 6, TimeUnit.MINUTES));
triggerUserCacheRefresh(TEST_UTIL, false, TABLE_NAMES);
// not limit for write request and should execute at max 6 read requests
assertEquals(60, doPuts(60, FAMILY, QUALIFIER, tables));
assertEquals(6, doGets(100, tables));
waitMinuteQuota();
// Add 6req/min limit for write request
admin.setQuota(
QuotaSettingsFactory.throttleUser(userName, ThrottleType.WRITE_NUMBER, 6, TimeUnit.MINUTES));
triggerUserCacheRefresh(TEST_UTIL, false, TABLE_NAMES);
// should execute at max 6 read requests and at max 6 write write requests
assertEquals(6, doGets(100, tables));
assertEquals(6, doPuts(60, FAMILY, QUALIFIER, tables));
// Remove all the limits
admin.setQuota(QuotaSettingsFactory.unthrottleUser(userName));
triggerUserCacheRefresh(TEST_UTIL, true, TABLE_NAMES);
assertEquals(60, doPuts(60, FAMILY, QUALIFIER, tables));
assertEquals(60, doGets(60, tables));
}
@Test
public void testUserTableThrottle() throws Exception {
final Admin admin = TEST_UTIL.getAdmin();
final String userName = User.getCurrent().getShortName();
// Add 6req/min limit
admin.setQuota(QuotaSettingsFactory.throttleUser(userName, TABLE_NAMES[0],
ThrottleType.REQUEST_NUMBER, 6, TimeUnit.MINUTES));
triggerUserCacheRefresh(TEST_UTIL, false, TABLE_NAMES[0]);
// should execute at max 6 requests on tables[0] and have no limit on tables[1]
assertEquals(6, doPuts(100, FAMILY, QUALIFIER, tables[0]));
assertEquals(30, doPuts(30, FAMILY, QUALIFIER, tables[1]));
// wait a minute and you should get other 6 requests executed
waitMinuteQuota();
assertEquals(6, doPuts(100, FAMILY, QUALIFIER, tables[0]));
// Remove all the limits
admin.setQuota(QuotaSettingsFactory.unthrottleUser(userName, TABLE_NAMES[0]));
triggerUserCacheRefresh(TEST_UTIL, true, TABLE_NAMES);
assertEquals(60, doPuts(60, FAMILY, QUALIFIER, tables));
assertEquals(60, doGets(60, tables));
}
@Test
public void testUserTableReadAndWriteThrottle() throws Exception {
final Admin admin = TEST_UTIL.getAdmin();
final String userName = User.getCurrent().getShortName();
// Add 6req/min limit for write request on tables[0]
admin.setQuota(QuotaSettingsFactory.throttleUser(userName, TABLE_NAMES[0],
ThrottleType.WRITE_NUMBER, 6, TimeUnit.MINUTES));
triggerUserCacheRefresh(TEST_UTIL, false, TABLE_NAMES[0]);
// should execute at max 6 write requests and have no limit for read request
assertEquals(6, doPuts(100, FAMILY, QUALIFIER, tables[0]));
assertEquals(60, doGets(60, tables[0]));
// no limit on tables[1]
assertEquals(60, doPuts(60, FAMILY, QUALIFIER, tables[1]));
assertEquals(60, doGets(60, tables[1]));
// wait a minute and you should get other 6 write requests executed
waitMinuteQuota();
// Add 6req/min limit for read request on tables[0]
admin.setQuota(QuotaSettingsFactory.throttleUser(userName, TABLE_NAMES[0],
ThrottleType.READ_NUMBER, 6, TimeUnit.MINUTES));
triggerUserCacheRefresh(TEST_UTIL, false, TABLE_NAMES[0]);
// should execute at max 6 read requests and at max 6 write requests
assertEquals(6, doPuts(100, FAMILY, QUALIFIER, tables[0]));
assertEquals(6, doGets(60, tables[0]));
// no limit on tables[1]
assertEquals(30, doPuts(30, FAMILY, QUALIFIER, tables[1]));
assertEquals(30, doGets(30, tables[1]));
// Remove all the limits
admin.setQuota(QuotaSettingsFactory.unthrottleUser(userName, TABLE_NAMES[0]));
triggerUserCacheRefresh(TEST_UTIL, true, TABLE_NAMES);
assertEquals(60, doPuts(60, FAMILY, QUALIFIER, tables));
assertEquals(60, doGets(60, tables));
}
@Test
public void testUserNamespaceThrottle() throws Exception {
final Admin admin = TEST_UTIL.getAdmin();
final String userName = User.getCurrent().getShortName();
final String NAMESPACE = "default";
// Add 6req/min limit
admin.setQuota(QuotaSettingsFactory.throttleUser(userName, NAMESPACE,
ThrottleType.REQUEST_NUMBER, 6, TimeUnit.MINUTES));
triggerUserCacheRefresh(TEST_UTIL, false, TABLE_NAMES[0]);
// should execute at max 6 requests on tables[0] and have no limit on tables[1]
assertEquals(6, doPuts(100, FAMILY, QUALIFIER, tables[0]));
// wait a minute and you should get other 6 requests executed
waitMinuteQuota();
assertEquals(6, doPuts(100, FAMILY, QUALIFIER, tables[1]));
// Remove all the limits
admin.setQuota(QuotaSettingsFactory.unthrottleUser(userName, NAMESPACE));
triggerUserCacheRefresh(TEST_UTIL, true, TABLE_NAMES);
assertEquals(60, doPuts(60, FAMILY, QUALIFIER, tables));
assertEquals(60, doGets(60, tables));
}
@Test
public void testUserNamespaceReadAndWriteThrottle() throws Exception {
final Admin admin = TEST_UTIL.getAdmin();
final String userName = User.getCurrent().getShortName();
final String NAMESPACE = "default";
// Add 6req/min limit for read request
admin.setQuota(QuotaSettingsFactory.throttleUser(userName, NAMESPACE, ThrottleType.READ_NUMBER,
6, TimeUnit.MINUTES));
triggerUserCacheRefresh(TEST_UTIL, false, TABLE_NAMES[0]);
// should execute at max 6 read requests and have no limit for write request
assertEquals(6, doGets(60, tables[0]));
assertEquals(60, doPuts(60, FAMILY, QUALIFIER, tables[0]));
waitMinuteQuota();
// Add 6req/min limit for write request, too
admin.setQuota(QuotaSettingsFactory.throttleUser(userName, NAMESPACE, ThrottleType.WRITE_NUMBER,
6, TimeUnit.MINUTES));
triggerUserCacheRefresh(TEST_UTIL, false, TABLE_NAMES[0]);
// should execute at max 6 read requests and at max 6 write requests
assertEquals(6, doGets(60, tables[0]));
assertEquals(6, doPuts(60, FAMILY, QUALIFIER, tables[0]));
// Remove all the limits
admin.setQuota(QuotaSettingsFactory.unthrottleUser(userName, NAMESPACE));
triggerUserCacheRefresh(TEST_UTIL, true, TABLE_NAMES);
assertEquals(60, doPuts(60, FAMILY, QUALIFIER, tables));
assertEquals(60, doGets(60, tables));
}
@Test
public void testTableGlobalThrottle() throws Exception {
final Admin admin = TEST_UTIL.getAdmin();
// Add 6req/min limit
admin.setQuota(QuotaSettingsFactory.throttleTable(TABLE_NAMES[0], ThrottleType.REQUEST_NUMBER,
6, TimeUnit.MINUTES));
triggerTableCacheRefresh(TEST_UTIL, false, TABLE_NAMES[0]);
// should execute at max 6 requests
assertEquals(6, doPuts(100, FAMILY, QUALIFIER, tables[0]));
// should have no limits
assertEquals(30, doPuts(30, FAMILY, QUALIFIER, tables[1]));
// wait a minute and you should get other 6 requests executed
waitMinuteQuota();
assertEquals(6, doPuts(100, FAMILY, QUALIFIER, tables[0]));
// Remove all the limits
admin.setQuota(QuotaSettingsFactory.unthrottleTable(TABLE_NAMES[0]));
triggerTableCacheRefresh(TEST_UTIL, true, TABLE_NAMES[0]);
assertEquals(80, doGets(80, tables[0], tables[1]));
}
@Test
public void testTableGlobalReadAndWriteThrottle() throws Exception {
final Admin admin = TEST_UTIL.getAdmin();
// Add 6req/min limit for read request
admin.setQuota(QuotaSettingsFactory.throttleTable(TABLE_NAMES[0], ThrottleType.READ_NUMBER, 6,
TimeUnit.MINUTES));
triggerTableCacheRefresh(TEST_UTIL, false, TABLE_NAMES[0]);
// should execute at max 6 read requests and have no limit for write request
assertEquals(6, doGets(100, tables[0]));
assertEquals(100, doPuts(100, FAMILY, QUALIFIER, tables[0]));
// should have no limits on tables[1]
assertEquals(30, doPuts(30, FAMILY, QUALIFIER, tables[1]));
assertEquals(30, doGets(30, tables[1]));
// wait a minute and you should get other 6 requests executed
waitMinuteQuota();
// Add 6req/min limit for write request, too
admin.setQuota(QuotaSettingsFactory.throttleTable(TABLE_NAMES[0], ThrottleType.WRITE_NUMBER, 6,
TimeUnit.MINUTES));
triggerTableCacheRefresh(TEST_UTIL, false, TABLE_NAMES[0]);
// should execute at max 6 read requests and at max 6 write requests
assertEquals(6, doGets(100, tables[0]));
assertEquals(6, doPuts(100, FAMILY, QUALIFIER, tables[0]));
// should have no limits on tables[1]
assertEquals(30, doPuts(30, FAMILY, QUALIFIER, tables[1]));
assertEquals(30, doGets(30, tables[1]));
// Remove all the limits
admin.setQuota(QuotaSettingsFactory.unthrottleTable(TABLE_NAMES[0]));
triggerTableCacheRefresh(TEST_UTIL, true, TABLE_NAMES[0]);
assertEquals(80, doGets(80, tables[0], tables[1]));
}
@Test
public void testNamespaceGlobalThrottle() throws Exception {
final Admin admin = TEST_UTIL.getAdmin();
final String NAMESPACE = "default";
// Add 6req/min limit
admin.setQuota(QuotaSettingsFactory.throttleNamespace(NAMESPACE, ThrottleType.REQUEST_NUMBER, 6,
TimeUnit.MINUTES));
triggerNamespaceCacheRefresh(TEST_UTIL, false, TABLE_NAMES[0]);
// should execute at max 6 requests
assertEquals(6, doPuts(100, FAMILY, QUALIFIER, tables[0]));
// wait a minute and you should get other 6 requests executed
waitMinuteQuota();
assertEquals(6, doPuts(100, FAMILY, QUALIFIER, tables[1]));
admin.setQuota(QuotaSettingsFactory.unthrottleNamespace(NAMESPACE));
triggerNamespaceCacheRefresh(TEST_UTIL, true, TABLE_NAMES[0]);
assertEquals(40, doPuts(40, FAMILY, QUALIFIER, tables[0]));
}
@Test
public void testNamespaceGlobalReadAndWriteThrottle() throws Exception {
final Admin admin = TEST_UTIL.getAdmin();
final String NAMESPACE = "default";
// Add 6req/min limit for write request
admin.setQuota(QuotaSettingsFactory.throttleNamespace(NAMESPACE, ThrottleType.WRITE_NUMBER, 6,
TimeUnit.MINUTES));
triggerNamespaceCacheRefresh(TEST_UTIL, false, TABLE_NAMES[0]);
// should execute at max 6 write requests and no limit for read request
assertEquals(6, doPuts(100, FAMILY, QUALIFIER, tables[0]));
assertEquals(100, doGets(100, tables[0]));
// wait a minute and you should get other 6 requests executed
waitMinuteQuota();
// Add 6req/min limit for read request, too
admin.setQuota(QuotaSettingsFactory.throttleNamespace(NAMESPACE, ThrottleType.READ_NUMBER, 6,
TimeUnit.MINUTES));
triggerNamespaceCacheRefresh(TEST_UTIL, false, TABLE_NAMES[0]);
// should execute at max 6 write requests and at max 6 read requests
assertEquals(6, doPuts(100, FAMILY, QUALIFIER, tables[0]));
assertEquals(6, doGets(100, tables[0]));
admin.setQuota(QuotaSettingsFactory.unthrottleNamespace(NAMESPACE));
triggerNamespaceCacheRefresh(TEST_UTIL, true, TABLE_NAMES[0]);
assertEquals(40, doPuts(40, FAMILY, QUALIFIER, tables[0]));
}
@Test
public void testUserAndTableThrottle() throws Exception {
final Admin admin = TEST_UTIL.getAdmin();
final String userName = User.getCurrent().getShortName();
// Add 6req/min limit for the user on tables[0]
admin.setQuota(QuotaSettingsFactory.throttleUser(userName, TABLE_NAMES[0],
ThrottleType.REQUEST_NUMBER, 6, TimeUnit.MINUTES));
triggerUserCacheRefresh(TEST_UTIL, false, TABLE_NAMES[0]);
// Add 12req/min limit for the user
admin.setQuota(QuotaSettingsFactory.throttleUser(userName, ThrottleType.REQUEST_NUMBER, 12,
TimeUnit.MINUTES));
triggerUserCacheRefresh(TEST_UTIL, false, TABLE_NAMES[1], TABLE_NAMES[2]);
// Add 8req/min limit for the tables[1]
admin.setQuota(QuotaSettingsFactory.throttleTable(TABLE_NAMES[1], ThrottleType.REQUEST_NUMBER,
8, TimeUnit.MINUTES));
triggerTableCacheRefresh(TEST_UTIL, false, TABLE_NAMES[1]);
// Add a lower table level throttle on tables[0]
admin.setQuota(QuotaSettingsFactory.throttleTable(TABLE_NAMES[0], ThrottleType.REQUEST_NUMBER,
3, TimeUnit.MINUTES));
triggerTableCacheRefresh(TEST_UTIL, false, TABLE_NAMES[0]);
// should execute at max 12 requests
assertEquals(12, doGets(100, tables[2]));
// should execute at max 8 requests
waitMinuteQuota();
assertEquals(8, doGets(100, tables[1]));
// should execute at max 3 requests
waitMinuteQuota();
assertEquals(3, doPuts(100, FAMILY, QUALIFIER, tables[0]));
// Remove all the throttling rules
admin.setQuota(QuotaSettingsFactory.unthrottleUser(userName, TABLE_NAMES[0]));
admin.setQuota(QuotaSettingsFactory.unthrottleUser(userName));
triggerUserCacheRefresh(TEST_UTIL, true, TABLE_NAMES[0], TABLE_NAMES[1]);
admin.setQuota(QuotaSettingsFactory.unthrottleTable(TABLE_NAMES[1]));
triggerTableCacheRefresh(TEST_UTIL, true, TABLE_NAMES[1]);
waitMinuteQuota();
assertEquals(40, doGets(40, tables[1]));
admin.setQuota(QuotaSettingsFactory.unthrottleTable(TABLE_NAMES[0]));
triggerTableCacheRefresh(TEST_UTIL, true, TABLE_NAMES[0]);
waitMinuteQuota();
assertEquals(40, doGets(40, tables[0]));
}
@Test
public void testUserGlobalBypassThrottle() throws Exception {
final Admin admin = TEST_UTIL.getAdmin();
final String userName = User.getCurrent().getShortName();
final String NAMESPACE = "default";
// Add 6req/min limit for tables[0]
admin.setQuota(QuotaSettingsFactory.throttleTable(TABLE_NAMES[0], ThrottleType.REQUEST_NUMBER,
6, TimeUnit.MINUTES));
triggerTableCacheRefresh(TEST_UTIL, false, TABLE_NAMES[0]);
// Add 13req/min limit for the user
admin.setQuota(QuotaSettingsFactory.throttleNamespace(NAMESPACE, ThrottleType.REQUEST_NUMBER,
13, TimeUnit.MINUTES));
triggerNamespaceCacheRefresh(TEST_UTIL, false, TABLE_NAMES[1]);
// should execute at max 6 requests on table[0] and (13 - 6) on table[1]
assertEquals(6, doPuts(100, FAMILY, QUALIFIER, tables[0]));
assertEquals(7, doGets(100, tables[1]));
waitMinuteQuota();
// Set the global bypass for the user
admin.setQuota(QuotaSettingsFactory.bypassGlobals(userName, true));
admin.setQuota(QuotaSettingsFactory.throttleUser(userName, TABLE_NAMES[2],
ThrottleType.REQUEST_NUMBER, 6, TimeUnit.MINUTES));
triggerUserCacheRefresh(TEST_UTIL, false, TABLE_NAMES[2]);
assertEquals(30, doGets(30, tables[0]));
assertEquals(30, doGets(30, tables[1]));
waitMinuteQuota();
// Remove the global bypass
// should execute at max 6 requests on table[0] and (13 - 6) on table[1]
admin.setQuota(QuotaSettingsFactory.bypassGlobals(userName, false));
admin.setQuota(QuotaSettingsFactory.unthrottleUser(userName, TABLE_NAMES[2]));
triggerUserCacheRefresh(TEST_UTIL, true, TABLE_NAMES[2]);
assertEquals(6, doPuts(100, FAMILY, QUALIFIER, tables[0]));
assertEquals(7, doGets(100, tables[1]));
// unset throttle
admin.setQuota(QuotaSettingsFactory.unthrottleTable(TABLE_NAMES[0]));
admin.setQuota(QuotaSettingsFactory.unthrottleNamespace(NAMESPACE));
waitMinuteQuota();
triggerTableCacheRefresh(TEST_UTIL, true, TABLE_NAMES[0]);
triggerNamespaceCacheRefresh(TEST_UTIL, true, TABLE_NAMES[1]);
assertEquals(30, doGets(30, tables[0]));
assertEquals(30, doGets(30, tables[1]));
}
@Test
public void testTableWriteCapacityUnitThrottle() throws Exception {
final Admin admin = TEST_UTIL.getAdmin();
// Add 6CU/min limit
admin.setQuota(QuotaSettingsFactory.throttleTable(TABLE_NAMES[0],
ThrottleType.WRITE_CAPACITY_UNIT, 6, TimeUnit.MINUTES));
triggerTableCacheRefresh(TEST_UTIL, false, TABLE_NAMES[0]);
// should execute at max 6 capacity units because each put size is 1 capacity unit
assertEquals(6, doPuts(20, 10, FAMILY, QUALIFIER, tables[0]));
// wait a minute and you should execute at max 3 capacity units because each put size is 2
// capacity unit
waitMinuteQuota();
assertEquals(3, doPuts(20, 1025, FAMILY, QUALIFIER, tables[0]));
admin.setQuota(QuotaSettingsFactory.unthrottleTable(TABLE_NAMES[0]));
triggerTableCacheRefresh(TEST_UTIL, true, TABLE_NAMES[0]);
}
@Test
public void testTableReadCapacityUnitThrottle() throws Exception {
final Admin admin = TEST_UTIL.getAdmin();
// Add 6CU/min limit
admin.setQuota(QuotaSettingsFactory.throttleTable(TABLE_NAMES[0],
ThrottleType.READ_CAPACITY_UNIT, 6, TimeUnit.MINUTES));
triggerTableCacheRefresh(TEST_UTIL, false, TABLE_NAMES[0]);
assertEquals(20, doPuts(20, 10, FAMILY, QUALIFIER, tables[0]));
// should execute at max 6 capacity units because each get size is 1 capacity unit
assertEquals(6, doGets(20, tables[0]));
assertEquals(20, doPuts(20, 2015, FAMILY, QUALIFIER, tables[0]));
// wait a minute and you should execute at max 3 capacity units because each get size is 2
// capacity unit on tables[0]
waitMinuteQuota();
assertEquals(3, doGets(20, tables[0]));
admin.setQuota(QuotaSettingsFactory.unthrottleTable(TABLE_NAMES[0]));
triggerTableCacheRefresh(TEST_UTIL, true, TABLE_NAMES[0]);
}
@Test
public void testTableExistsGetThrottle() throws Exception {
final Admin admin = TEST_UTIL.getAdmin();
// Add throttle quota
admin.setQuota(QuotaSettingsFactory.throttleTable(TABLE_NAMES[0], ThrottleType.REQUEST_NUMBER,
100, TimeUnit.MINUTES));
triggerTableCacheRefresh(TEST_UTIL, false, TABLE_NAMES[0]);
Table table = TEST_UTIL.getConnection().getTable(TABLE_NAMES[0]);
// An exists call when having throttle quota
table.exists(new Get(Bytes.toBytes("abc")));
admin.setQuota(QuotaSettingsFactory.unthrottleTable(TABLE_NAMES[0]));
triggerTableCacheRefresh(TEST_UTIL, true, TABLE_NAMES[0]);
}
@Test
public void testRegionServerThrottle() throws Exception {
final Admin admin = TEST_UTIL.getAdmin();
admin.setQuota(QuotaSettingsFactory.throttleTable(TABLE_NAMES[0], ThrottleType.WRITE_NUMBER, 5,
TimeUnit.MINUTES));
// requests are throttled by table quota
admin.setQuota(QuotaSettingsFactory.throttleRegionServer(
QuotaTableUtil.QUOTA_REGION_SERVER_ROW_KEY, ThrottleType.WRITE_NUMBER, 7, TimeUnit.MINUTES));
triggerTableCacheRefresh(TEST_UTIL, false, TABLE_NAMES[0]);
triggerRegionServerCacheRefresh(TEST_UTIL, false);
assertEquals(5, doPuts(10, FAMILY, QUALIFIER, tables[0]));
triggerRegionServerCacheRefresh(TEST_UTIL, false);
assertEquals(5, doPuts(10, FAMILY, QUALIFIER, tables[0]));
// requests are throttled by region server quota
admin.setQuota(QuotaSettingsFactory.throttleRegionServer(
QuotaTableUtil.QUOTA_REGION_SERVER_ROW_KEY, ThrottleType.WRITE_NUMBER, 4, TimeUnit.MINUTES));
triggerRegionServerCacheRefresh(TEST_UTIL, false);
assertEquals(4, doPuts(10, FAMILY, QUALIFIER, tables[0]));
triggerRegionServerCacheRefresh(TEST_UTIL, false);
assertEquals(4, doPuts(10, FAMILY, QUALIFIER, tables[0]));
// unthrottle
admin.setQuota(
QuotaSettingsFactory.unthrottleRegionServer(QuotaTableUtil.QUOTA_REGION_SERVER_ROW_KEY));
triggerRegionServerCacheRefresh(TEST_UTIL, true);
admin.setQuota(QuotaSettingsFactory.unthrottleTable(TABLE_NAMES[0]));
triggerTableCacheRefresh(TEST_UTIL, true, TABLE_NAMES[0]);
triggerRegionServerCacheRefresh(TEST_UTIL, true);
}
@Test
public void testExceedThrottleQuota() throws Exception {
final Admin admin = TEST_UTIL.getAdmin();
admin.setQuota(QuotaSettingsFactory.throttleTable(TABLE_NAMES[0], ThrottleType.WRITE_NUMBER, 5,
TimeUnit.MINUTES));
triggerTableCacheRefresh(TEST_UTIL, false, TABLE_NAMES[0]);
admin.setQuota(QuotaSettingsFactory.throttleRegionServer(
QuotaTableUtil.QUOTA_REGION_SERVER_ROW_KEY, ThrottleType.WRITE_NUMBER, 20, TimeUnit.SECONDS));
admin.setQuota(QuotaSettingsFactory.throttleRegionServer(
QuotaTableUtil.QUOTA_REGION_SERVER_ROW_KEY, ThrottleType.READ_NUMBER, 10, TimeUnit.SECONDS));
triggerRegionServerCacheRefresh(TEST_UTIL, false);
// enable exceed throttle quota
admin.exceedThrottleQuotaSwitch(true);
// exceed table limit and allowed by region server limit
triggerExceedThrottleQuotaCacheRefresh(TEST_UTIL, true);
waitMinuteQuota();
assertEquals(10, doPuts(10, FAMILY, QUALIFIER, tables[0]));
// exceed table limit and throttled by region server limit
waitMinuteQuota();
assertEquals(20, doPuts(25, FAMILY, QUALIFIER, tables[0]));
// set region server limiter is lower than table limiter
admin.setQuota(QuotaSettingsFactory.throttleRegionServer(
QuotaTableUtil.QUOTA_REGION_SERVER_ROW_KEY, ThrottleType.WRITE_NUMBER, 2, TimeUnit.SECONDS));
triggerRegionServerCacheRefresh(TEST_UTIL, false);
// throttled by region server limiter
waitMinuteQuota();
assertEquals(2, doPuts(10, FAMILY, QUALIFIER, tables[0]));
admin.setQuota(QuotaSettingsFactory.throttleRegionServer(
QuotaTableUtil.QUOTA_REGION_SERVER_ROW_KEY, ThrottleType.WRITE_NUMBER, 20, TimeUnit.SECONDS));
triggerRegionServerCacheRefresh(TEST_UTIL, false);
// disable exceed throttle quota
admin.exceedThrottleQuotaSwitch(false);
triggerExceedThrottleQuotaCacheRefresh(TEST_UTIL, false);
waitMinuteQuota();
// throttled by table limit
assertEquals(5, doPuts(10, FAMILY, QUALIFIER, tables[0]));
// enable exceed throttle quota and unthrottle region server
admin.exceedThrottleQuotaSwitch(true);
triggerExceedThrottleQuotaCacheRefresh(TEST_UTIL, true);
waitMinuteQuota();
admin.setQuota(
QuotaSettingsFactory.unthrottleRegionServer(QuotaTableUtil.QUOTA_REGION_SERVER_ROW_KEY));
triggerRegionServerCacheRefresh(TEST_UTIL, true);
waitMinuteQuota();
// throttled by table limit
assertEquals(5, doPuts(10, FAMILY, QUALIFIER, tables[0]));
// disable exceed throttle quota
admin.exceedThrottleQuotaSwitch(false);
triggerExceedThrottleQuotaCacheRefresh(TEST_UTIL, false);
// unthrottle table
admin.setQuota(QuotaSettingsFactory.unthrottleTable(TABLE_NAMES[0]));
triggerTableCacheRefresh(TEST_UTIL, true, TABLE_NAMES[0]);
}
}