Package org.apache.hadoop.hbase.regionserver

Source Code of org.apache.hadoop.hbase.regionserver.IdxRegionMBeanImpl

/*
* Copyright 2010 The Apache Software Foundation
*
* 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.regionserver;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.hbase.HColumnDescriptor;
import org.apache.hadoop.hbase.HRegionInfo;
import org.apache.hadoop.hbase.client.idx.IdxColumnDescriptor;
import org.apache.hadoop.hbase.client.idx.IdxIndexDescriptor;
import org.apache.hadoop.hbase.util.Bytes;

import javax.management.AttributeNotFoundException;
import javax.management.MBeanAttributeInfo;
import javax.management.MBeanException;
import javax.management.MBeanInfo;
import javax.management.MalformedObjectNameException;
import javax.management.NotCompliantMBeanException;
import javax.management.ObjectName;
import javax.management.ReflectionException;
import javax.management.StandardMBean;
import java.io.IOException;
import java.lang.ref.WeakReference;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

/**
* A delegate MBean to get stats / poke an idx region.
*/
public class IdxRegionMBeanImpl extends StandardMBean
  implements IdxRegionMBean {
  static final Log LOG = LogFactory.getLog(IdxRegionMBeanImpl.class);

  private static final HashMap<String, String> ATTRIBUTE_DESCRIPTIONS =
    new HashMap<String, String>() {{
      put("Valid", "Indicates whether the region being exposed by " +
        "this MBean is still alive");
      put("NumberOfIndexedKeys", "The number of keys in the index " +
        "which is equivalent to the number of top-level rows in this region");
      put("IndexesTotalHeapSize", "The total heap size, in bytes, used by " +
        "the indexes and their overhead");
    }};


  /**
   * Instantiate an new IdxRegion MBean. this is a convenience method which
   * allows the caller to avoid catching the
   * {@link javax.management.NotCompliantMBeanException}.
   *
   * @param idxRegion the region to wrap
   * @return a new instance of IdxRegionMBeanImpl
   */
  static IdxRegionMBeanImpl newIdxRegionMBeanImpl(IdxRegion idxRegion) {
    try {
      return new IdxRegionMBeanImpl(idxRegion);
    } catch (NotCompliantMBeanException e) {
      throw new IllegalStateException("Could not instantiate mbean", e);
    }
  }

  /**
   * Generate object name from the hregion info.
   *
   * @param regionInfo the region info to create the object name from.
   * @return an valid object name.
   */
  static ObjectName generateObjectName(HRegionInfo regionInfo) {
    StringBuilder builder =
      new StringBuilder(IdxRegionMBeanImpl.class.getPackage().getName());
    builder.append(':');
    builder.append("table=");
    builder.append(regionInfo.getTableDesc().getNameAsString());
    builder.append(',');

    builder.append("id=");
    builder.append(regionInfo.getRegionId());
    builder.append(',');

    if (regionInfo.getStartKey() != null &&
      regionInfo.getStartKey().length > 0) {
      builder.append("startKey=");
      builder.append(Bytes.toString(regionInfo.getStartKey()));
      builder.append(',');
    }

    if (regionInfo.getEndKey() != null &&
      regionInfo.getEndKey().length > 0) {
      builder.append("endKey=");
      builder.append(Bytes.toString(regionInfo.getEndKey()));
      builder.append(',');
    }

    builder.append("type=IdxRegion");
    try {
      return ObjectName.getInstance(builder.toString());
    } catch (MalformedObjectNameException e) {
      throw new IllegalStateException("Failed to create a legal object name",
        e);
    }
  }

  /**
   * Using a weak reference to the idx region.
   * This way a failure to clear this MBean from the mbean server won't prevent
   * the idx region to be garbage collected.
   */
  private WeakReference<IdxRegion> idxRegionRef;

  private IdxRegionMBeanImpl(IdxRegion idxRegion)
    throws NotCompliantMBeanException {
    super(IdxRegionMBean.class);
    idxRegionRef = new WeakReference<IdxRegion>(idxRegion);
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public int getNumberOfIndexedKeys() {
    IdxRegion region = idxRegionRef.get();
    if (region != null) {
      return region.getNumberOfIndexedKeys();
    } else {
      return -1;
    }
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public long getIndexesTotalHeapSize() {
    IdxRegion region = idxRegionRef.get();
    if (region != null) {
      return region.getIndexesTotalHeapSize();
    } else {
      return -1;
    }
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public boolean isValid() {
    IdxRegion region = idxRegionRef.get();
    if (region != null) {
      return !(region.isClosed() || region.isClosing());
    } else {
      return false;
    }
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public long getTotalIndexedScans() {
    IdxRegion region = idxRegionRef.get();
    if (region != null) {
      return region.getTotalIndexedScans();
    } else {
      return -1L;
    }
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public long resetTotalIndexedScans() {
    IdxRegion region = idxRegionRef.get();
    if (region != null) {
      return region.resetTotalIndexedScans();
    } else {
      return -1L;
    }
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public long getTotalNonIndexedScans() {
    IdxRegion region = idxRegionRef.get();
    if (region != null) {
      return region.getTotalNonIndexedScans();
    } else {
      return -1L;
    }
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public long resetTotalNonIndexedScans() {
    IdxRegion region = idxRegionRef.get();
    if (region != null) {
      return region.resetTotalNonIndexedScans();
    } else {
      return -1L;
    }
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public long getNumberOfOngoingIndexedScans() {
    IdxRegion region = idxRegionRef.get();
    if (region != null) {
      return region.getNumberOfOngoingIndexedScans();
    } else {
      return -1L;
    }
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public String getIndexBuildTimes() {
    IdxRegion region = idxRegionRef.get();
    if (region != null) {
      return toIndexBuildTimesString(region.getIndexBuildTimes());
    } else {
      return "";
    }
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public String resetIndexBuildTimes() {
    IdxRegion region = idxRegionRef.get();
    if (region != null) {
      return toIndexBuildTimesString(region.resetIndexBuildTimes());
    } else {
      return "";
    }
  }

  private String toIndexBuildTimesString(long[] buildTimes) {
    StringBuilder builder = new StringBuilder();
    for (long indexBuildTime : buildTimes) {
      if (indexBuildTime >= 0) {
        builder.append(indexBuildTime);
        builder.append(", ");
      }
    }
    return builder.length() > 2 ? builder.substring(0, builder.length() - 2) :
      "";
  }

/* StandardMBean hooks and overrides */

  @Override
  protected String getDescription(MBeanAttributeInfo info) {
    String description = ATTRIBUTE_DESCRIPTIONS.get(info.getName());
    return description == null ? super.getDescription(info) : description;
  }

  @Override
  public Object getAttribute(String attribute)
    throws AttributeNotFoundException, MBeanException, ReflectionException {
    if (attribute.endsWith(".heapSize")) {
      String columnName = attribute.substring(0, attribute.indexOf('.'));
      return getIndexHeapSize(columnName);
    }
    return super.getAttribute(attribute);
  }

  @Override
  protected void cacheMBeanInfo(MBeanInfo info) {
    IdxRegion region = idxRegionRef.get();
    if (region != null) {
      Set<String> columnNames;
      try {
        columnNames = extractIndexedColumnNames(region.getRegionInfo());
      } catch (IOException e) {
        throw new IllegalStateException("Invalid region info for " + region);
      }
      final MBeanAttributeInfo[] existingInfos = info.getAttributes();
      for (MBeanAttributeInfo attributeInfo : existingInfos) {
        String name = attributeInfo.getName();
        if (name.indexOf('.') >= 0) {
          columnNames.remove(name.substring(0, name.indexOf('.')));
        }
      }
      MBeanAttributeInfo[] attributeInfos = new
        MBeanAttributeInfo[columnNames.size() + existingInfos.length];
      System.arraycopy(existingInfos, 0, attributeInfos, 0,
        existingInfos.length);
      Iterator<String> columnNameIterator = columnNames.iterator();
      for (int i = existingInfos.length; i < attributeInfos.length; i++) {
        String name = columnNameIterator.next() + ".heapSize";
        attributeInfos[i] = new MBeanAttributeInfo(name,
          "long", "The amount of heap space occupied by this index", true,
          false, false);
      }
      info = new MBeanInfo(info.getClassName(), info.getDescription(),
        attributeInfos, info.getConstructors(), info.getOperations(),
        info.getNotifications(), info.getDescriptor());
    }
    super.cacheMBeanInfo(info);
  }

  private static Set<String> extractIndexedColumnNames(HRegionInfo regionInfo)
    throws IOException {
    Set<String> idxColumns = new HashSet<String>();
    for (HColumnDescriptor columnDescriptor :
      regionInfo.getTableDesc().getColumnFamilies()) {
      Collection<IdxIndexDescriptor> indexDescriptors =
        IdxColumnDescriptor.getIndexDescriptors(columnDescriptor).values();
      for (IdxIndexDescriptor indexDescriptor : indexDescriptors) {
        idxColumns.add(columnDescriptor.getNameAsString() + ":" +
          Bytes.toString(indexDescriptor.getQualifierName()));
      }
    }
    return idxColumns;
  }

  private long getIndexHeapSize(String columnName) {
    IdxRegion region = idxRegionRef.get();
    if (region != null) {
      return region.getIndexHeapSize(columnName);
    } else {
      return -1L;
    }
  }
}
TOP

Related Classes of org.apache.hadoop.hbase.regionserver.IdxRegionMBeanImpl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.