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.mob;
20  
21  import java.io.IOException;
22  import java.util.Date;
23  
24  import junit.framework.TestCase;
25  
26  import org.apache.commons.logging.Log;
27  import org.apache.commons.logging.LogFactory;
28  import org.apache.hadoop.conf.Configuration;
29  import org.apache.hadoop.fs.FileSystem;
30  import org.apache.hadoop.fs.Path;
31  import org.apache.hadoop.hbase.HBaseConfiguration;
32  import org.apache.hadoop.hbase.HBaseTestingUtility;
33  import org.apache.hadoop.hbase.HColumnDescriptor;
34  import org.apache.hadoop.hbase.HRegionInfo;
35  import org.apache.hadoop.hbase.HTableDescriptor;
36  import org.apache.hadoop.hbase.KeyValue;
37  import org.apache.hadoop.hbase.testclassification.SmallTests;
38  import org.apache.hadoop.hbase.TableName;
39  import org.apache.hadoop.hbase.regionserver.HMobStore;
40  import org.apache.hadoop.hbase.regionserver.HRegion;
41  import org.apache.hadoop.hbase.regionserver.StoreFile;
42  import org.apache.hadoop.hbase.util.Bytes;
43  import org.junit.Test;
44  import org.junit.experimental.categories.Category;
45  
46  @Category(SmallTests.class)
47  public class TestMobFileCache extends TestCase {
48    static final Log LOG = LogFactory.getLog(TestMobFileCache.class);
49    private HBaseTestingUtility UTIL;
50    private HRegion region;
51    private Configuration conf;
52    private MobCacheConfig mobCacheConf;
53    private MobFileCache mobFileCache;
54    private Date currentDate = new Date();
55    private final String TEST_CACHE_SIZE = "2";
56    private final int EXPECTED_CACHE_SIZE_ZERO = 0;
57    private final int EXPECTED_CACHE_SIZE_ONE = 1;
58    private final int EXPECTED_CACHE_SIZE_TWO = 2;
59    private final int EXPECTED_CACHE_SIZE_THREE = 3;
60    private final long EXPECTED_REFERENCE_ONE = 1;
61    private final long EXPECTED_REFERENCE_TWO = 2;
62  
63    private final String TABLE = "tableName";
64    private final String FAMILY1 = "family1";
65    private final String FAMILY2 = "family2";
66    private final String FAMILY3 = "family3";
67  
68    private final byte[] ROW = Bytes.toBytes("row");
69    private final byte[] ROW2 = Bytes.toBytes("row2");
70    private final byte[] VALUE = Bytes.toBytes("value");
71    private final byte[] VALUE2 = Bytes.toBytes("value2");
72    private final byte[] QF1 = Bytes.toBytes("qf1");
73    private final byte[] QF2 = Bytes.toBytes("qf2");
74    private final byte[] QF3 = Bytes.toBytes("qf3");
75  
76    @Override
77    public void setUp() throws Exception {
78      UTIL = HBaseTestingUtility.createLocalHTU();
79      conf = UTIL.getConfiguration();
80      conf.setInt("hfile.format.version", 3);
81      HTableDescriptor htd = UTIL.createTableDescriptor("testMobFileCache");
82      HColumnDescriptor hcd1 = new HColumnDescriptor(FAMILY1);
83      hcd1.setMobEnabled(true);
84      hcd1.setMobThreshold(0);
85      HColumnDescriptor hcd2 = new HColumnDescriptor(FAMILY2);
86      hcd2.setMobEnabled(true);
87      hcd2.setMobThreshold(0);
88      HColumnDescriptor hcd3 = new HColumnDescriptor(FAMILY3);
89      hcd3.setMobEnabled(true);
90      hcd3.setMobThreshold(0);
91      htd.addFamily(hcd1);
92      htd.addFamily(hcd2);
93      htd.addFamily(hcd3);
94      region = UTIL.createLocalHRegion(htd, null, null);
95    }
96  
97    @Override
98    protected void tearDown() throws Exception {
99      region.close();
100     region.getFilesystem().delete(UTIL.getDataTestDir(), true);
101   }
102 
103   /**
104    * Create the mob store file.
105    * @param family
106    */
107   private Path createMobStoreFile(String family) throws IOException {
108     return createMobStoreFile(HBaseConfiguration.create(), family);
109   }
110 
111   /**
112    * Create the mob store file
113    * @param conf
114    * @param family
115    */
116   private Path createMobStoreFile(Configuration conf, String family) throws IOException {
117     HColumnDescriptor hcd = new HColumnDescriptor(family);
118     hcd.setMaxVersions(4);
119     hcd.setMobEnabled(true);
120     mobCacheConf = new MobCacheConfig(conf, hcd);
121     return createMobStoreFile(conf, hcd);
122   }
123 
124   /**
125    * Create the mob store file
126    * @param conf
127    * @param hcd
128    */
129   private Path createMobStoreFile(Configuration conf, HColumnDescriptor hcd)
130       throws IOException {
131     // Setting up a Store
132     HTableDescriptor htd = new HTableDescriptor(TableName.valueOf(TABLE));
133     htd.addFamily(hcd);
134     HMobStore mobStore = (HMobStore) region.getStore(hcd.getName());
135     KeyValue key1 = new KeyValue(ROW, hcd.getName(), QF1, 1, VALUE);
136     KeyValue key2 = new KeyValue(ROW, hcd.getName(), QF2, 1, VALUE);
137     KeyValue key3 = new KeyValue(ROW2, hcd.getName(), QF3, 1, VALUE2);
138     KeyValue[] keys = new KeyValue[] { key1, key2, key3 };
139     int maxKeyCount = keys.length;
140     HRegionInfo regionInfo = new HRegionInfo();
141     StoreFile.Writer mobWriter = mobStore.createWriterInTmp(currentDate,
142         maxKeyCount, hcd.getCompactionCompression(), regionInfo.getStartKey());
143     Path mobFilePath = mobWriter.getPath();
144     String fileName = mobFilePath.getName();
145     mobWriter.append(key1);
146     mobWriter.append(key2);
147     mobWriter.append(key3);
148     mobWriter.close();
149     String targetPathName = MobUtils.formatDate(currentDate);
150     Path targetPath = new Path(mobStore.getPath(), targetPathName);
151     mobStore.commitFile(mobFilePath, targetPath);
152     return new Path(targetPath, fileName);
153   }
154 
155   @Test
156   public void testMobFileCache() throws Exception {
157     FileSystem fs = FileSystem.get(conf);
158     conf.set(MobConstants.MOB_FILE_CACHE_SIZE_KEY, TEST_CACHE_SIZE);
159     mobFileCache = new MobFileCache(conf);
160     Path file1Path = createMobStoreFile(FAMILY1);
161     Path file2Path = createMobStoreFile(FAMILY2);
162     Path file3Path = createMobStoreFile(FAMILY3);
163 
164     // Before open one file by the MobFileCache
165     assertEquals(EXPECTED_CACHE_SIZE_ZERO, mobFileCache.getCacheSize());
166     // Open one file by the MobFileCache
167     CachedMobFile cachedMobFile1 = (CachedMobFile) mobFileCache.openFile(
168         fs, file1Path, mobCacheConf);
169     assertEquals(EXPECTED_CACHE_SIZE_ONE, mobFileCache.getCacheSize());
170     assertNotNull(cachedMobFile1);
171     assertEquals(EXPECTED_REFERENCE_TWO, cachedMobFile1.getReferenceCount());
172 
173     // The evict is also managed by a schedule thread pool.
174     // And its check period is set as 3600 seconds by default.
175     // This evict should get the lock at the most time
176     mobFileCache.evict();  // Cache not full, evict it
177     assertEquals(EXPECTED_CACHE_SIZE_ONE, mobFileCache.getCacheSize());
178     assertEquals(EXPECTED_REFERENCE_TWO, cachedMobFile1.getReferenceCount());
179 
180     mobFileCache.evictFile(file1Path.getName());  // Evict one file
181     assertEquals(EXPECTED_CACHE_SIZE_ZERO, mobFileCache.getCacheSize());
182     assertEquals(EXPECTED_REFERENCE_ONE, cachedMobFile1.getReferenceCount());
183 
184     cachedMobFile1.close();  // Close the cached mob file
185 
186     // Reopen three cached file
187     cachedMobFile1 = (CachedMobFile) mobFileCache.openFile(
188         fs, file1Path, mobCacheConf);
189     assertEquals(EXPECTED_CACHE_SIZE_ONE, mobFileCache.getCacheSize());
190     CachedMobFile cachedMobFile2 = (CachedMobFile) mobFileCache.openFile(
191         fs, file2Path, mobCacheConf);
192     assertEquals(EXPECTED_CACHE_SIZE_TWO, mobFileCache.getCacheSize());
193     CachedMobFile cachedMobFile3 = (CachedMobFile) mobFileCache.openFile(
194         fs, file3Path, mobCacheConf);
195     // Before the evict
196     // Evict the cache, should clost the first file 1
197     assertEquals(EXPECTED_CACHE_SIZE_THREE, mobFileCache.getCacheSize());
198     assertEquals(EXPECTED_REFERENCE_TWO, cachedMobFile1.getReferenceCount());
199     assertEquals(EXPECTED_REFERENCE_TWO, cachedMobFile2.getReferenceCount());
200     assertEquals(EXPECTED_REFERENCE_TWO, cachedMobFile3.getReferenceCount());
201     mobFileCache.evict();
202     assertEquals(EXPECTED_CACHE_SIZE_ONE, mobFileCache.getCacheSize());
203     assertEquals(EXPECTED_REFERENCE_ONE, cachedMobFile1.getReferenceCount());
204     assertEquals(EXPECTED_REFERENCE_ONE, cachedMobFile2.getReferenceCount());
205     assertEquals(EXPECTED_REFERENCE_TWO, cachedMobFile3.getReferenceCount());
206   }
207 }