View Javadoc

1   /**
2    * Copyright 2009 The Apache Software Foundation
3    *
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *     http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing, software
15   * distributed under the License is distributed on an "AS IS" BASIS,
16   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17   * See the License for the specific language governing permissions and
18   * limitations under the License.
19   */
20  
21  package org.apache.hadoop.hbase;
22  
23  import java.io.DataInput;
24  import java.io.DataOutput;
25  import java.io.IOException;
26  import java.util.ArrayList;
27  import java.util.Arrays;
28  import java.util.Collection;
29  import java.util.Collections;
30  import java.util.HashMap;
31  import java.util.Map;
32  import java.util.TreeMap;
33  
34  import org.apache.hadoop.hbase.master.AssignmentManager.RegionState;
35  import org.apache.hadoop.hbase.util.Bytes;
36  import org.apache.hadoop.io.VersionedWritable;
37  
38  /**
39   * Status information on the HBase cluster.
40   * <p>
41   * <tt>ClusterStatus</tt> provides clients with information such as:
42   * <ul>
43   * <li>The count and names of region servers in the cluster.</li>
44   * <li>The count and names of dead region servers in the cluster.</li>
45   * <li>The average cluster load.</li>
46   * <li>The number of regions deployed on the cluster.</li>
47   * <li>The number of requests since last report.</li>
48   * <li>Detailed region server loading and resource usage information,
49   *  per server and per region.</li>
50   *  <li>Regions in transition at master</li>
51   *  <li>The unique cluster ID</li>
52   * </ul>
53   */
54  public class ClusterStatus extends VersionedWritable {
55    /**
56     * Version for object serialization.  Incremented for changes in serialized
57     * representation.
58     * <dl>
59     *   <dt>0</dt> <dd>initial version</dd>
60     *   <dt>1</dt> <dd>added cluster ID</dd>
61     *   <dt>2</dt> <dd>Added Map of ServerName to ServerLoad</dd>
62     * </dl>
63     */
64    private static final byte VERSION = 2;
65  
66    private String hbaseVersion;
67    private Map<ServerName, HServerLoad> liveServers;
68    private Collection<ServerName> deadServers;
69    private Map<String, RegionState> intransition;
70    private String clusterId;
71    private String[] masterCoprocessors;
72  
73    /**
74     * Constructor, for Writable
75     */
76    public ClusterStatus() {
77      super();
78    }
79  
80    public ClusterStatus(final String hbaseVersion, final String clusterid,
81        final Map<ServerName, HServerLoad> servers,
82        final Collection<ServerName> deadServers, final Map<String, RegionState> rit,
83        final String[] masterCoprocessors) {
84      this.hbaseVersion = hbaseVersion;
85      this.liveServers = servers;
86      this.deadServers = deadServers;
87      this.intransition = rit;
88      this.clusterId = clusterid;
89      this.masterCoprocessors = masterCoprocessors;
90    }
91  
92    /**
93     * @return the names of region servers on the dead list
94     */
95    public Collection<ServerName> getDeadServerNames() {
96      return Collections.unmodifiableCollection(deadServers);
97    }
98  
99    /**
100    * @return the number of region servers in the cluster
101    */
102   public int getServersSize() {
103     return liveServers.size();
104   }
105 
106   /**
107    * @return the number of dead region servers in the cluster
108    */
109   public int getDeadServers() {
110     return deadServers.size();
111   }
112 
113   /**
114    * @return the average cluster load
115    */
116   public double getAverageLoad() {
117     int load = getRegionsCount();
118     return (double)load / (double)getServersSize();
119   }
120 
121   /**
122    * @return the number of regions deployed on the cluster
123    */
124   public int getRegionsCount() {
125     int count = 0;
126     for (Map.Entry<ServerName, HServerLoad> e: this.liveServers.entrySet()) {
127       count += e.getValue().getNumberOfRegions();
128     }
129     return count;
130   }
131 
132   /**
133    * @return the number of requests since last report
134    */
135   public int getRequestsCount() {
136     int count = 0;
137     for (Map.Entry<ServerName, HServerLoad> e: this.liveServers.entrySet()) {
138       count += e.getValue().getNumberOfRequests();
139     }
140     return count;
141   }
142 
143   /**
144    * @return the HBase version string as reported by the HMaster
145    */
146   public String getHBaseVersion() {
147     return hbaseVersion;
148   }
149 
150   /**
151    * @see java.lang.Object#equals(java.lang.Object)
152    */
153   public boolean equals(Object o) {
154     if (this == o) {
155       return true;
156     }
157     if (!(o instanceof ClusterStatus)) {
158       return false;
159     }
160     return (getVersion() == ((ClusterStatus)o).getVersion()) &&
161       getHBaseVersion().equals(((ClusterStatus)o).getHBaseVersion()) &&
162       this.liveServers.equals(((ClusterStatus)o).liveServers) &&
163       deadServers.equals(((ClusterStatus)o).deadServers) &&
164       Arrays.equals(this.masterCoprocessors, ((ClusterStatus)o).masterCoprocessors);
165   }
166 
167   /**
168    * @see java.lang.Object#hashCode()
169    */
170   public int hashCode() {
171     return VERSION + hbaseVersion.hashCode() + this.liveServers.hashCode() +
172       deadServers.hashCode();
173   }
174 
175   /** @return the object version number */
176   public byte getVersion() {
177     return VERSION;
178   }
179 
180   //
181   // Getters
182   //
183 
184   /**
185    * Returns detailed region server information: A list of
186    * {@link ServerName}.
187    * @return region server information
188    * @deprecated Use {@link #getServers()}
189    */
190   public Collection<ServerName> getServerInfo() {
191     return getServers();
192   }
193 
194   public Collection<ServerName> getServers() {
195     return Collections.unmodifiableCollection(this.liveServers.keySet());
196   }
197 
198   /**
199    * @param sn
200    * @return Server's load or null if not found.
201    */
202   public HServerLoad getLoad(final ServerName sn) {
203     return this.liveServers.get(sn);
204   }
205 
206   public Map<String, RegionState> getRegionsInTransition() {
207     return this.intransition;
208   }
209 
210   public String getClusterId() {
211     return clusterId;
212   }
213 
214    public String[] getMasterCoprocessors() {
215      return masterCoprocessors;
216   }
217 
218   //
219   // Writable
220   //
221 
222   public void write(DataOutput out) throws IOException {
223     super.write(out);
224     out.writeUTF(hbaseVersion);
225     out.writeInt(getServersSize());
226     for (Map.Entry<ServerName, HServerLoad> e: this.liveServers.entrySet()) {
227       Bytes.writeByteArray(out, e.getKey().getVersionedBytes());
228       e.getValue().write(out);
229     }
230     out.writeInt(deadServers.size());
231     for (ServerName server: deadServers) {
232       Bytes.writeByteArray(out, server.getVersionedBytes());
233     }
234     out.writeInt(this.intransition.size());
235     for (Map.Entry<String, RegionState> e: this.intransition.entrySet()) {
236       out.writeUTF(e.getKey());
237       e.getValue().write(out);
238     }
239     out.writeUTF(clusterId);
240     out.writeInt(masterCoprocessors.length);
241     for(String masterCoprocessor: masterCoprocessors) {
242       out.writeUTF(masterCoprocessor);
243     }
244   }
245 
246   public void readFields(DataInput in) throws IOException {
247     super.readFields(in);
248     hbaseVersion = in.readUTF();
249     int count = in.readInt();
250     this.liveServers = new HashMap<ServerName, HServerLoad>(count);
251     for (int i = 0; i < count; i++) {
252       byte [] versionedBytes = Bytes.readByteArray(in);
253       HServerLoad hsl = new HServerLoad();
254       hsl.readFields(in);
255       this.liveServers.put(ServerName.parseVersionedServerName(versionedBytes), hsl);
256     }
257     count = in.readInt();
258     deadServers = new ArrayList<ServerName>(count);
259     for (int i = 0; i < count; i++) {
260       deadServers.add(ServerName.parseVersionedServerName(Bytes.readByteArray(in)));
261     }
262     count = in.readInt();
263     this.intransition = new TreeMap<String, RegionState>();
264     for (int i = 0; i < count; i++) {
265       String key = in.readUTF();
266       RegionState regionState = new RegionState();
267       regionState.readFields(in);
268       this.intransition.put(key, regionState);
269     }
270     this.clusterId = in.readUTF();
271     int masterCoprocessorsLength = in.readInt();
272     masterCoprocessors = new String[masterCoprocessorsLength];
273     for(int i = 0; i < masterCoprocessorsLength; i++) {
274       masterCoprocessors[i] = in.readUTF();
275     }
276   }
277 }