Logo Search packages:      
Sourcecode: hbase version File versions  Download package

HServerLoad.java

/**
 * Copyright 2007 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;

import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;

import org.apache.hadoop.hbase.util.Bytes;
import org.apache.hadoop.hbase.util.Strings;
import org.apache.hadoop.io.Writable;
import org.apache.hadoop.io.WritableComparable;

/**
 * This class encapsulates metrics for determining the load on a HRegionServer
 */
00037 public class HServerLoad implements WritableComparable<HServerLoad> {
  /** number of regions */
    // could just use regionLoad.size() but master.RegionManager likes to play
    // around with this value while passing HServerLoad objects around during
    // balancer calculations
00042   private int numberOfRegions;
  /** number of requests since last report */
00044   private int numberOfRequests;
  /** the amount of used heap, in MB */
00046   private int usedHeapMB;
  /** the maximum allowable size of the heap, in MB */
00048   private int maxHeapMB;
  /** per-region load metrics */
00050   private ArrayList<RegionLoad> regionLoad = new ArrayList<RegionLoad>();

  /** 
   * Encapsulates per-region loading metrics.
   */
00055   public static class RegionLoad implements Writable {
    /** the region name */
00057     private byte[] name;
    /** the number of stores for the region */
00059     private int stores;
    /** the number of storefiles for the region */
00061     private int storefiles;
    /** the current total size of the store files for the region, in MB */
00063     private int storefileSizeMB;
    /** the current size of the memstore for the region, in MB */
00065     private int memstoreSizeMB;
    /** the current total size of storefile indexes for the region, in MB */
00067     private int storefileIndexSizeMB;

    /**
     * Constructor, for Writable
     */
00072     public RegionLoad() {
        super();
    }

    /**
     * @param name
     * @param stores
     * @param storefiles
     * @param storefileSizeMB
     * @param memstoreSizeMB
     * @param storefileIndexSizeMB
     */
00084     public RegionLoad(final byte[] name, final int stores,
        final int storefiles, final int storefileSizeMB, 
        final int memstoreSizeMB, final int storefileIndexSizeMB) {
      this.name = name;
      this.stores = stores;
      this.storefiles = storefiles;
      this.storefileSizeMB = storefileSizeMB;
      this.memstoreSizeMB = memstoreSizeMB;
      this.storefileIndexSizeMB = storefileIndexSizeMB;
    }

    // Getters

    /**
     * @return the region name
     */
00100     public byte[] getName() {
      return name;
    }

    /**
     * @return the region name as a string
     */
00107     public String getNameAsString() {
      return Bytes.toString(name);
    }

    /**
     * @return the number of stores
     */
00114     public int getStores() {
      return stores;
    }

    /**
     * @return the number of storefiles
     */
00121     public int getStorefiles() {
      return storefiles;
    }

    /**
     * @return the total size of the storefiles, in MB
     */
00128     public int getStorefileSizeMB() {
      return storefileSizeMB;
    }

    /**
     * @return the memstore size, in MB
     */
00135     public int getMemStoreSizeMB() {
      return memstoreSizeMB;
    }

    /**
     * @return the approximate size of storefile indexes on the heap, in MB
     */
00142     public int getStorefileIndexSizeMB() {
      return storefileIndexSizeMB;
    }

    // Setters

    /**
     * @param name the region name
     */
00151     public void setName(byte[] name) {
      this.name = name;
    }

    /**
     * @param stores the number of stores
     */
00158     public void setStores(int stores) {
      this.stores = stores;
    }

    /**
     * @param storefiles the number of storefiles
     */
00165     public void setStorefiles(int storefiles) {
      this.storefiles = storefiles;
    }

    /**
     * @param memstoreSizeMB the memstore size, in MB
     */
00172     public void setMemStoreSizeMB(int memstoreSizeMB) {
      this.memstoreSizeMB = memstoreSizeMB;
    }

    /**
     * @param storefileIndexSizeMB the approximate size of storefile indexes
     *  on the heap, in MB
     */
00180     public void setStorefileIndexSizeMB(int storefileIndexSizeMB) {
      this.storefileIndexSizeMB = storefileIndexSizeMB;
    }

    // Writable
    public void readFields(DataInput in) throws IOException {
      int namelen = in.readInt();
      this.name = new byte[namelen];
      in.readFully(this.name);
      this.stores = in.readInt();
      this.storefiles = in.readInt();
      this.storefileSizeMB = in.readInt();
      this.memstoreSizeMB = in.readInt();
      this.storefileIndexSizeMB = in.readInt();
    }

    public void write(DataOutput out) throws IOException {
      out.writeInt(name.length);
      out.write(name);
      out.writeInt(stores);
      out.writeInt(storefiles);
      out.writeInt(storefileSizeMB);
      out.writeInt(memstoreSizeMB);
      out.writeInt(storefileIndexSizeMB);
    }

    /**
     * @see java.lang.Object#toString()
     */
    @Override
00210     public String toString() {
      StringBuilder sb = Strings.appendKeyValue(new StringBuilder(), "stores",
        Integer.valueOf(this.stores));
      sb = Strings.appendKeyValue(sb, "storefiles",
        Integer.valueOf(this.storefiles));
      sb = Strings.appendKeyValue(sb, "storefileSizeMB",
          Integer.valueOf(this.storefileSizeMB));
      sb = Strings.appendKeyValue(sb, "memstoreSizeMB",
        Integer.valueOf(this.memstoreSizeMB));
      sb = Strings.appendKeyValue(sb, "storefileIndexSizeMB",
        Integer.valueOf(this.storefileIndexSizeMB));
      return sb.toString();
    }
  }

  /*
   * TODO: Other metrics that might be considered when the master is actually
   * doing load balancing instead of merely trying to decide where to assign
   * a region:
   * <ul>
   *   <li># of CPUs, heap size (to determine the "class" of machine). For
   *       now, we consider them to be homogeneous.</li>
   *   <li>#requests per region (Map<{String|HRegionInfo}, Integer>)</li>
   *   <li>#compactions and/or #splits (churn)</li>
   *   <li>server death rate (maybe there is something wrong with this server)</li>
   * </ul>
   */

  /** default constructor (used by Writable) */
00239   public HServerLoad() {
    super();
  }
  
  /**
   * Constructor
   * @param numberOfRequests
   * @param usedHeapMB
   * @param maxHeapMB
   */
00249   public HServerLoad(final int numberOfRequests, final int usedHeapMB,
      final int maxHeapMB) {
    this.numberOfRequests = numberOfRequests;
    this.usedHeapMB = usedHeapMB;
    this.maxHeapMB = maxHeapMB;
  }

  /**
   * Constructor
   * @param hsl the template HServerLoad
   */
00260   public HServerLoad(final HServerLoad hsl) {
    this(hsl.numberOfRequests, hsl.usedHeapMB, hsl.maxHeapMB);
    this.regionLoad.addAll(hsl.regionLoad);
  }

  /**
   * Originally, this method factored in the effect of requests going to the
   * server as well. However, this does not interact very well with the current
   * region rebalancing code, which only factors number of regions. For the 
   * interim, until we can figure out how to make rebalancing use all the info
   * available, we're just going to make load purely the number of regions.
   *
   * @return load factor for this server
   */
00274   public int getLoad() {
    // int load = numberOfRequests == 0 ? 1 : numberOfRequests;
    // load *= numberOfRegions == 0 ? 1 : numberOfRegions;
    // return load;
    return numberOfRegions;
  }

  /**
   * @see java.lang.Object#toString()
   */
  @Override
00285   public String toString() {
    return toString(1);
  }
  
  /**
   * Returns toString() with the number of requests divided by the message
   * interval in seconds
   * @param msgInterval
   * @return The load as a String
   */
00295   public String toString(int msgInterval) {
    StringBuilder sb = new StringBuilder();
    sb = Strings.appendKeyValue(sb, "requests",
      Integer.valueOf(numberOfRequests/msgInterval));
    sb = Strings.appendKeyValue(sb, "regions",
      Integer.valueOf(numberOfRegions));
    sb = Strings.appendKeyValue(sb, "usedHeap",
      Integer.valueOf(this.usedHeapMB));
    sb = Strings.appendKeyValue(sb, "maxHeap", Integer.valueOf(maxHeapMB));
    return sb.toString();
  }

  /**
   * @see java.lang.Object#equals(java.lang.Object)
   */
  @Override
00311   public boolean equals(Object o) {
    if (this == o) {
      return true;
    }
    if (o == null) {
      return false;
    }
    if (getClass() != o.getClass()) {
      return false;
    }
    return compareTo((HServerLoad)o) == 0;
  }

  /**
   * @see java.lang.Object#hashCode()
   */
  @Override
00328   public int hashCode() {
    int result = Integer.valueOf(numberOfRequests).hashCode();
    result ^= Integer.valueOf(numberOfRegions).hashCode();
    return result;
  }
  
  // Getters
  
  /**
   * @return the numberOfRegions
   */
00339   public int getNumberOfRegions() {
    return numberOfRegions;
  }

  /**
   * @return the numberOfRequests
   */
00346   public int getNumberOfRequests() {
    return numberOfRequests;
  }

  /**
   * @return the amount of heap in use, in MB
   */
00353   public int getUsedHeapMB() {
    return usedHeapMB;
  }

  /**
   * @return the maximum allowable heap size, in MB
   */
00360   public int getMaxHeapMB() {
    return maxHeapMB;
  }

  /**
   * @return region load metrics
   */
00367   public Collection<RegionLoad> getRegionsLoad() {
    return Collections.unmodifiableCollection(regionLoad);
  }

  /**
   * @return Count of storefiles on this regionserver
   */
00374   public int getStorefiles() {
    int count = 0;
    for (RegionLoad info: regionLoad)
      count += info.getStorefiles();
    return count;
  }

  /**
   * @return Total size of store files in MB
   */
00384   public int getStorefileSizeInMB() {
    int count = 0;
    for (RegionLoad info: regionLoad)
      count += info.getStorefileSizeMB();
    return count;
  }

  /**
   * @return Size of memstores in MB
   */
00394   public int getMemStoreSizeInMB() {
    int count = 0;
    for (RegionLoad info: regionLoad)
      count += info.getMemStoreSizeMB();
    return count;
  }

  /**
   * @return Size of store file indexes in MB
   */
00404   public int getStorefileIndexSizeInMB() {
    int count = 0;
    for (RegionLoad info: regionLoad)
      count += info.getStorefileIndexSizeMB();
    return count;
  }

  // Setters

  /**
   * @param numberOfRegions the number of regions
   */
00416   public void setNumberOfRegions(int numberOfRegions) {
    this.numberOfRegions = numberOfRegions;
  }

  /**
   * @param numberOfRequests the number of requests to set
   */
00423   public void setNumberOfRequests(int numberOfRequests) {
    this.numberOfRequests = numberOfRequests;
  }

  /**
   * @param usedHeapMB the amount of heap in use, in MB
   */
00430   public void setUsedHeapMB(int usedHeapMB) {
    this.usedHeapMB = usedHeapMB;
  }

  /**
   * @param maxHeapMB the maximum allowable heap size, in MB
   */
00437   public void setMaxHeapMB(int maxHeapMB) {
    this.maxHeapMB = maxHeapMB;
  }

  /**
   * @param load Instance of HServerLoad
   */
00444   public void addRegionInfo(final HServerLoad.RegionLoad load) {
    this.numberOfRegions++;
    this.regionLoad.add(load);
  }

  /**
   * @param name
   * @param stores
   * @param storefiles
   * @param memstoreSizeMB
   * @param storefileIndexSizeMB
   * @deprecated Use {@link #addRegionInfo(RegionLoad)}
   */
  @Deprecated
00458   public void addRegionInfo(final byte[] name, final int stores,
      final int storefiles, final int storefileSizeMB,
      final int memstoreSizeMB, final int storefileIndexSizeMB) {
    this.regionLoad.add(new HServerLoad.RegionLoad(name, stores, storefiles,
      storefileSizeMB, memstoreSizeMB, storefileIndexSizeMB));
  }

  // Writable

  public void readFields(DataInput in) throws IOException {
    numberOfRequests = in.readInt();
    usedHeapMB = in.readInt();
    maxHeapMB = in.readInt();
    numberOfRegions = in.readInt();
    for (int i = 0; i < numberOfRegions; i++) {
      RegionLoad rl = new RegionLoad();
      rl.readFields(in);
      regionLoad.add(rl);
    }
  }

  public void write(DataOutput out) throws IOException {
    out.writeInt(numberOfRequests);
    out.writeInt(usedHeapMB);
    out.writeInt(maxHeapMB);
    out.writeInt(numberOfRegions);
    for (int i = 0; i < numberOfRegions; i++)
      regionLoad.get(i).write(out);
  }

  // Comparable

  public int compareTo(HServerLoad o) {
    return this.getLoad() - o.getLoad();
  }
}

Generated by  Doxygen 1.6.0   Back to index