001/**
002 *
003 * Licensed to the Apache Software Foundation (ASF) under one
004 * or more contributor license agreements.  See the NOTICE file
005 * distributed with this work for additional information
006 * regarding copyright ownership.  The ASF licenses this file
007 * to you under the Apache License, Version 2.0 (the
008 * "License"); you may not use this file except in compliance
009 * with the License.  You may obtain a copy of the License at
010 *
011 *     http://www.apache.org/licenses/LICENSE-2.0
012 *
013 * Unless required by applicable law or agreed to in writing, software
014 * distributed under the License is distributed on an "AS IS" BASIS,
015 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
016 * See the License for the specific language governing permissions and
017 * limitations under the License.
018 */
019package org.apache.hadoop.hbase.master;
020
021import java.util.Map;
022import java.util.concurrent.ExecutorService;
023import java.util.concurrent.TimeUnit;
024
025import org.apache.hadoop.hbase.ScheduledChore;
026import org.apache.hadoop.hbase.TableDescriptors;
027import org.apache.yetus.audience.InterfaceAudience;
028import org.slf4j.Logger;
029import org.slf4j.LoggerFactory;
030import org.apache.hadoop.hbase.client.ColumnFamilyDescriptor;
031import org.apache.hadoop.hbase.client.TableDescriptor;
032import org.apache.hadoop.hbase.client.TableState;
033import org.apache.hadoop.hbase.master.locking.LockManager;
034import org.apache.hadoop.hbase.mob.MobUtils;
035import org.apache.hadoop.hbase.procedure2.LockType;
036
037/**
038 * The Class MobCompactChore for running compaction regularly to merge small mob files.
039 */
040@InterfaceAudience.Private
041public class MobCompactionChore extends ScheduledChore {
042
043  private static final Logger LOG = LoggerFactory.getLogger(MobCompactionChore.class);
044  private HMaster master;
045  private ExecutorService pool;
046
047  public MobCompactionChore(HMaster master, int period) {
048    // use the period as initial delay.
049    super(master.getServerName() + "-MobCompactionChore", master, period, period, TimeUnit.SECONDS);
050    this.master = master;
051    this.pool = MobUtils.createMobCompactorThreadPool(master.getConfiguration());
052  }
053
054  @Override
055  protected void chore() {
056    try {
057      TableDescriptors htds = master.getTableDescriptors();
058      Map<String, TableDescriptor> map = htds.getAll();
059      for (TableDescriptor htd : map.values()) {
060        if (!master.getTableStateManager().isTableState(htd.getTableName(),
061          TableState.State.ENABLED)) {
062          continue;
063        }
064        boolean reported = false;
065        try {
066          final LockManager.MasterLock lock = master.getLockManager().createMasterLock(
067              MobUtils.getTableLockName(htd.getTableName()), LockType.EXCLUSIVE,
068              this.getClass().getName() + ": mob compaction");
069          for (ColumnFamilyDescriptor hcd : htd.getColumnFamilies()) {
070            if (!hcd.isMobEnabled()) {
071              continue;
072            }
073            if (!reported) {
074              master.reportMobCompactionStart(htd.getTableName());
075              reported = true;
076            }
077            MobUtils.doMobCompaction(master.getConfiguration(), master.getFileSystem(),
078                htd.getTableName(), hcd, pool, false, lock);
079          }
080        } finally {
081          if (reported) {
082            master.reportMobCompactionEnd(htd.getTableName());
083          }
084        }
085      }
086    } catch (Exception e) {
087      LOG.error("Failed to compact mob files", e);
088    }
089  }
090
091  @Override
092  protected synchronized void cleanup() {
093    super.cleanup();
094    pool.shutdown();
095  }
096}