View Javadoc

1   /**
2    *
3    * Licensed to the Apache Software Foundation (ASF) under one
4    * or more contributor license agreements.  See the NOTICE file
5    * distributed with this work for additional information
6    * regarding copyright ownership.  The ASF licenses this file
7    * to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance
9    * with the License.  You may obtain a copy of the License at
10   *
11   *     http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing, software
14   * distributed under the License is distributed on an "AS IS" BASIS,
15   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   * See the License for the specific language governing permissions and
17   * limitations under the License.
18   */
19  package org.apache.hadoop.hbase.client;
20  
21  import static org.junit.Assert.assertEquals;
22  import static org.junit.Assert.fail;
23  
24  import org.apache.commons.logging.Log;
25  import org.apache.commons.logging.LogFactory;
26  import org.apache.hadoop.conf.Configuration;
27  import org.apache.hadoop.hbase.HBaseTestingUtility;
28  import org.apache.hadoop.hbase.HConstants;
29  import org.apache.hadoop.hbase.testclassification.LargeTests;
30  import org.apache.hadoop.hbase.MetaTableAccessor;
31  import org.apache.hadoop.hbase.TableName;
32  import org.apache.hadoop.hbase.regionserver.HRegionServer;
33  import org.apache.hadoop.hbase.util.Bytes;
34  import org.junit.AfterClass;
35  import org.junit.Before;
36  import org.junit.BeforeClass;
37  import org.junit.Test;
38  import org.junit.experimental.categories.Category;
39  
40  /**
41   * Test various scanner timeout issues.
42   */
43  @Category(LargeTests.class)
44  public class TestScannerTimeout {
45  
46    private final static HBaseTestingUtility
47        TEST_UTIL = new HBaseTestingUtility();
48  
49    private static final Log LOG = LogFactory.getLog(TestScannerTimeout.class);
50    private final static byte[] SOME_BYTES = Bytes.toBytes("f");
51    private final static TableName TABLE_NAME = TableName.valueOf("t");
52    private final static int NB_ROWS = 10;
53    // Be careful w/ what you set this timer to... it can get in the way of
54    // the mini cluster coming up -- the verification in particular.
55    private final static int THREAD_WAKE_FREQUENCY = 1000;
56    private final static int SCANNER_TIMEOUT = 15000;
57    private final static int SCANNER_CACHING = 5;
58  
59     /**
60     * @throws java.lang.Exception
61     */
62    @BeforeClass
63    public static void setUpBeforeClass() throws Exception {
64      Configuration c = TEST_UTIL.getConfiguration();
65      c.setInt(HConstants.HBASE_CLIENT_SCANNER_TIMEOUT_PERIOD, SCANNER_TIMEOUT);
66      c.setInt(HConstants.THREAD_WAKE_FREQUENCY, THREAD_WAKE_FREQUENCY);
67      // Put meta on master to avoid meta server shutdown handling
68      c.set("hbase.balancer.tablesOnMaster", "hbase:meta");
69      // We need more than one region server for this test
70      TEST_UTIL.startMiniCluster(2);
71      Table table = TEST_UTIL.createTable(TABLE_NAME, SOME_BYTES);
72       for (int i = 0; i < NB_ROWS; i++) {
73        Put put = new Put(Bytes.toBytes(i));
74        put.add(SOME_BYTES, SOME_BYTES, SOME_BYTES);
75        table.put(put);
76      }
77      table.close();
78    }
79  
80    /**
81     * @throws java.lang.Exception
82     */
83    @AfterClass
84    public static void tearDownAfterClass() throws Exception {
85      TEST_UTIL.shutdownMiniCluster();
86    }
87  
88    /**
89     * @throws java.lang.Exception
90     */
91    @Before
92    public void setUp() throws Exception {
93      TEST_UTIL.ensureSomeNonStoppedRegionServersAvailable(2);
94    }
95  
96    /**
97     * Test that scanner can continue even if the region server it was reading
98     * from failed. Before 2772, it reused the same scanner id.
99     * @throws Exception
100    */
101   @Test(timeout=300000)
102   public void test2772() throws Exception {
103     LOG.info("START************ test2772");
104     HRegionServer rs = TEST_UTIL.getRSForFirstRegionInTable(TABLE_NAME);
105     Scan scan = new Scan();
106     // Set a very high timeout, we want to test what happens when a RS
107     // fails but the region is recovered before the lease times out.
108     // Since the RS is already created, this conf is client-side only for
109     // this new table
110     Configuration conf = new Configuration(TEST_UTIL.getConfiguration());
111     conf.setInt(HConstants.HBASE_CLIENT_SCANNER_TIMEOUT_PERIOD, SCANNER_TIMEOUT * 100);
112     Table higherScanTimeoutTable = new HTable(conf, TABLE_NAME);
113     ResultScanner r = higherScanTimeoutTable.getScanner(scan);
114     // This takes way less than SCANNER_TIMEOUT*100
115     rs.abort("die!");
116     Result[] results = r.next(NB_ROWS);
117     assertEquals(NB_ROWS, results.length);
118     r.close();
119     higherScanTimeoutTable.close();
120     LOG.info("END ************ test2772");
121 
122   }
123 
124   /**
125    * Test that scanner won't miss any rows if the region server it was reading
126    * from failed. Before 3686, it would skip rows in the scan.
127    * @throws Exception
128    */
129   @Test(timeout=300000)
130   public void test3686a() throws Exception {
131     LOG.info("START ************ TEST3686A---1");
132     HRegionServer rs = TEST_UTIL.getRSForFirstRegionInTable(TABLE_NAME);
133     LOG.info("START ************ TEST3686A---1111");
134 
135     Scan scan = new Scan();
136     scan.setCaching(SCANNER_CACHING);
137     LOG.info("************ TEST3686A");
138     MetaTableAccessor.fullScanMetaAndPrint(TEST_UTIL.getHBaseAdmin().getConnection());
139     // Set a very high timeout, we want to test what happens when a RS
140     // fails but the region is recovered before the lease times out.
141     // Since the RS is already created, this conf is client-side only for
142     // this new table
143     Configuration conf = new Configuration(TEST_UTIL.getConfiguration());
144     conf.setInt(
145         HConstants.HBASE_CLIENT_SCANNER_TIMEOUT_PERIOD, SCANNER_TIMEOUT*100);
146     Table table = new HTable(conf, TABLE_NAME);
147     LOG.info("START ************ TEST3686A---22");
148 
149     ResultScanner r = table.getScanner(scan);
150     LOG.info("START ************ TEST3686A---33");
151 
152     int count = 1;
153     r.next();
154     LOG.info("START ************ TEST3686A---44");
155 
156     // Kill after one call to next(), which got 5 rows.
157     rs.abort("die!");
158     while(r.next() != null) {
159       count ++;
160     }
161     assertEquals(NB_ROWS, count);
162     r.close();
163     table.close();
164     LOG.info("************ END TEST3686A");
165   }
166 
167   /**
168    * Make sure that no rows are lost if the scanner timeout is longer on the
169    * client than the server, and the scan times out on the server but not the
170    * client.
171    * @throws Exception
172    */
173   @Test(timeout=300000)
174   public void test3686b() throws Exception {
175     LOG.info("START ************ test3686b");
176     HRegionServer rs = TEST_UTIL.getRSForFirstRegionInTable(TABLE_NAME);
177     Scan scan = new Scan();
178     scan.setCaching(SCANNER_CACHING);
179     // Set a very high timeout, we want to test what happens when a RS
180     // fails but the region is recovered before the lease times out.
181     // Since the RS is already created, this conf is client-side only for
182     // this new table
183     Configuration conf = new Configuration(TEST_UTIL.getConfiguration());
184     conf.setInt(HConstants.HBASE_CLIENT_SCANNER_TIMEOUT_PERIOD, SCANNER_TIMEOUT * 100);
185     Table higherScanTimeoutTable = new HTable(conf, TABLE_NAME);
186     ResultScanner r = higherScanTimeoutTable.getScanner(scan);
187     int count = 1;
188     r.next();
189     // Sleep, allowing the scan to timeout on the server but not on the client.
190     Thread.sleep(SCANNER_TIMEOUT+2000);
191     while(r.next() != null) {
192       count ++;
193     }
194     assertEquals(NB_ROWS, count);
195     r.close();
196     higherScanTimeoutTable.close();
197     LOG.info("END ************ END test3686b");
198 
199   }
200 
201 }
202