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.master.region;
019
020import java.io.IOException;
021import java.util.concurrent.TimeUnit;
022import org.apache.hadoop.conf.Configuration;
023import org.apache.hadoop.hbase.HBaseConfiguration;
024import org.apache.hadoop.hbase.HConstants;
025import org.apache.hadoop.hbase.TableName;
026import org.apache.hadoop.hbase.client.ColumnFamilyDescriptorBuilder;
027import org.apache.hadoop.hbase.client.TableDescriptor;
028import org.apache.hadoop.hbase.client.TableDescriptorBuilder;
029import org.apache.hadoop.hbase.io.encoding.DataBlockEncoding;
030import org.apache.hadoop.hbase.master.MasterServices;
031import org.apache.hadoop.hbase.regionserver.BloomType;
032import org.apache.hadoop.hbase.regionserver.storefiletracker.StoreFileTracker;
033import org.apache.hadoop.hbase.regionserver.storefiletracker.StoreFileTrackerFactory;
034import org.apache.hadoop.hbase.util.Bytes;
035import org.apache.hadoop.hbase.util.ReflectionUtils;
036import org.apache.yetus.audience.InterfaceAudience;
037
038import org.apache.hbase.thirdparty.com.google.common.base.Strings;
039
040/**
041 * The factory class for creating a {@link MasterRegion}.
042 */
043@InterfaceAudience.Private
044public final class MasterRegionFactory {
045
046  // Use the character $ to let the log cleaner know that this is not the normal wal file.
047  public static final String ARCHIVED_WAL_SUFFIX = "$masterlocalwal$";
048
049  // this is a bit trick that in StoreFileInfo.validateStoreFileName, we just test if the file name
050  // contains '-' to determine if it is a valid store file, so here we have to add '-'in the file
051  // name to avoid being processed by normal TimeToLiveHFileCleaner.
052  public static final String ARCHIVED_HFILE_SUFFIX = "$-masterlocalhfile-$";
053
054  private static final String MAX_WALS_KEY = "hbase.master.store.region.maxwals";
055
056  private static final int DEFAULT_MAX_WALS = 10;
057
058  public static final String USE_HSYNC_KEY = "hbase.master.store.region.wal.hsync";
059
060  // Default master data dir
061  private static final String MASTER_REGION_DIR_NAME_DEFAULT = "MasterData";
062
063  public static final String MASTER_REGION_DIR_NAME;
064  static {
065    Configuration conf = HBaseConfiguration.create();
066    MASTER_REGION_DIR_NAME = initMasterRegionDirName(conf);
067  }
068
069  public static String initMasterRegionDirName(Configuration conf) {
070    String suffix = conf.get(HConstants.HBASE_META_TABLE_SUFFIX,
071      HConstants.HBASE_META_TABLE_SUFFIX_DEFAULT_VALUE);
072    if (Strings.isNullOrEmpty(suffix)) {
073      return MASTER_REGION_DIR_NAME_DEFAULT;
074    } else {
075      return MASTER_REGION_DIR_NAME_DEFAULT + "_" + suffix;
076    }
077  }
078
079  private static final String FLUSH_SIZE_KEY = "hbase.master.store.region.flush.size";
080
081  private static final long DEFAULT_FLUSH_SIZE = TableDescriptorBuilder.DEFAULT_MEMSTORE_FLUSH_SIZE;
082
083  private static final String FLUSH_PER_CHANGES_KEY = "hbase.master.store.region.flush.per.changes";
084
085  private static final long DEFAULT_FLUSH_PER_CHANGES = 1_000_000;
086
087  private static final String FLUSH_INTERVAL_MS_KEY = "hbase.master.store.region.flush.interval.ms";
088
089  // default to flush every 15 minutes, for safety
090  private static final long DEFAULT_FLUSH_INTERVAL_MS = TimeUnit.MINUTES.toMillis(15);
091
092  private static final String COMPACT_MIN_KEY = "hbase.master.store.region.compact.min";
093
094  private static final int DEFAULT_COMPACT_MIN = 4;
095
096  private static final String ROLL_PERIOD_MS_KEY = "hbase.master.store.region.walroll.period.ms";
097
098  private static final long DEFAULT_ROLL_PERIOD_MS = TimeUnit.MINUTES.toMillis(15);
099
100  private static final String RING_BUFFER_SLOT_COUNT = "hbase.master.store.ringbuffer.slot.count";
101
102  private static final int DEFAULT_RING_BUFFER_SLOT_COUNT = 128;
103
104  public static final String TRACKER_IMPL = "hbase.master.store.region.file-tracker.impl";
105
106  public static final TableName TABLE_NAME = TableName.valueOf("master:store");
107
108  public static final byte[] PROC_FAMILY = Bytes.toBytes("proc");
109
110  public static final byte[] REGION_SERVER_FAMILY = Bytes.toBytes("rs");
111
112  public static final byte[] STATE_FAMILY = Bytes.toBytes("state");
113
114  private static final TableDescriptor TABLE_DESC = TableDescriptorBuilder.newBuilder(TABLE_NAME)
115    .setColumnFamily(ColumnFamilyDescriptorBuilder.newBuilder(HConstants.CATALOG_FAMILY)
116      .setMaxVersions(HConstants.DEFAULT_HBASE_META_VERSIONS).setInMemory(true)
117      .setBlocksize(HConstants.DEFAULT_HBASE_META_BLOCK_SIZE).setBloomFilterType(BloomType.ROWCOL)
118      .setDataBlockEncoding(DataBlockEncoding.ROW_INDEX_V1).build())
119    .setColumnFamily(ColumnFamilyDescriptorBuilder.of(PROC_FAMILY))
120    .setColumnFamily(ColumnFamilyDescriptorBuilder.of(REGION_SERVER_FAMILY))
121    .setColumnFamily(ColumnFamilyDescriptorBuilder.of(STATE_FAMILY)).build();
122
123  private static TableDescriptor withTrackerConfigs(Configuration conf) {
124    String trackerImpl = conf.get(TRACKER_IMPL, conf.get(StoreFileTrackerFactory.TRACKER_IMPL,
125      StoreFileTrackerFactory.Trackers.DEFAULT.name()));
126    Class<? extends StoreFileTracker> trackerClass =
127      StoreFileTrackerFactory.getTrackerClass(trackerImpl);
128    if (StoreFileTrackerFactory.isMigration(trackerClass)) {
129      throw new IllegalArgumentException("Should not set store file tracker to "
130        + StoreFileTrackerFactory.Trackers.MIGRATION.name() + " for master local region");
131    }
132    StoreFileTracker tracker = ReflectionUtils.newInstance(trackerClass, conf, true, null);
133    return tracker.updateWithTrackerConfigs(TableDescriptorBuilder.newBuilder(TABLE_DESC)).build();
134  }
135
136  public static MasterRegion create(MasterServices server) throws IOException {
137    Configuration conf = server.getConfiguration();
138    MasterRegionParams params = new MasterRegionParams().server(server)
139      .regionDirName(getMasterRegionDirName()).tableDescriptor(withTrackerConfigs(conf));
140    long flushSize = conf.getLong(FLUSH_SIZE_KEY, DEFAULT_FLUSH_SIZE);
141    long flushPerChanges = conf.getLong(FLUSH_PER_CHANGES_KEY, DEFAULT_FLUSH_PER_CHANGES);
142    long flushIntervalMs = conf.getLong(FLUSH_INTERVAL_MS_KEY, DEFAULT_FLUSH_INTERVAL_MS);
143    int compactMin = conf.getInt(COMPACT_MIN_KEY, DEFAULT_COMPACT_MIN);
144    params.flushSize(flushSize).flushPerChanges(flushPerChanges).flushIntervalMs(flushIntervalMs)
145      .compactMin(compactMin);
146    int maxWals = conf.getInt(MAX_WALS_KEY, DEFAULT_MAX_WALS);
147    params.maxWals(maxWals);
148    if (conf.get(USE_HSYNC_KEY) != null) {
149      params.useHsync(conf.getBoolean(USE_HSYNC_KEY, false));
150    }
151    params.ringBufferSlotCount(conf.getInt(RING_BUFFER_SLOT_COUNT, DEFAULT_RING_BUFFER_SLOT_COUNT));
152    long rollPeriodMs = conf.getLong(ROLL_PERIOD_MS_KEY, DEFAULT_ROLL_PERIOD_MS);
153    params.rollPeriodMs(rollPeriodMs).archivedWalSuffix(ARCHIVED_WAL_SUFFIX)
154      .archivedHFileSuffix(ARCHIVED_HFILE_SUFFIX);
155    return MasterRegion.create(params);
156  }
157
158  public static String getMasterRegionDirName() {
159    return MASTER_REGION_DIR_NAME;
160  }
161}