View Javadoc

1   /**
2    *
3    * Licensed to the Apache Software Foundation (ASF) under one
4    * or more contributor license agreements.  See the NOTICE file
5    * distributed with this work for additional information
6    * regarding copyright ownership.  The ASF licenses this file
7    * to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance
9    * with the License.  You may obtain a copy of the License at
10   *
11   *     http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing, software
14   * distributed under the License is distributed on an "AS IS" BASIS,
15   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   * See the License for the specific language governing permissions and
17   * limitations under the License.
18   */
19  package org.apache.hadoop.hbase.master;
20  
21  import java.io.IOException;
22  import java.util.ArrayList;
23  import java.util.Arrays;
24  import java.util.HashMap;
25  import java.util.HashSet;
26  import java.util.List;
27  import java.util.Map;
28  import java.util.Set;
29  import java.util.TreeMap;
30  
31  import org.apache.commons.logging.Log;
32  import org.apache.commons.logging.LogFactory;
33  import org.apache.hadoop.hbase.classification.InterfaceAudience;
34  import org.apache.hadoop.hbase.HConstants;
35  import org.apache.hadoop.hbase.HRegionInfo;
36  import org.apache.hadoop.hbase.ServerName;
37  import org.apache.hadoop.hbase.TableName;
38  import org.apache.hadoop.hbase.catalog.CatalogTracker;
39  import org.apache.hadoop.hbase.catalog.MetaReader;
40  import org.apache.hadoop.hbase.catalog.MetaReader.Visitor;
41  import org.apache.hadoop.hbase.client.Result;
42  import org.apache.hadoop.hbase.master.balancer.FavoredNodeAssignmentHelper;
43  import org.apache.hadoop.hbase.master.balancer.FavoredNodesPlan;
44  import org.apache.hadoop.hbase.util.Pair;
45  
46  /**
47   * Used internally for reading meta and constructing datastructures that are
48   * then queried, for things like regions to regionservers, table to regions, etc.
49   * It also records the favored nodes mapping for regions.
50   *
51   */
52  @InterfaceAudience.Private
53  public class SnapshotOfRegionAssignmentFromMeta {
54    private static final Log LOG = LogFactory.getLog(SnapshotOfRegionAssignmentFromMeta.class
55        .getName());
56  
57    private CatalogTracker tracker;
58  
59    /** the table name to region map */
60    private final Map<TableName, List<HRegionInfo>> tableToRegionMap;
61    /** the region to region server map */
62    //private final Map<HRegionInfo, ServerName> regionToRegionServerMap;
63    private Map<HRegionInfo, ServerName> regionToRegionServerMap;
64    /** the region name to region info map */
65    private final Map<String, HRegionInfo> regionNameToRegionInfoMap;
66  
67    /** the regionServer to region map */
68    private final Map<ServerName, List<HRegionInfo>> regionServerToRegionMap;
69    /** the existing assignment plan in the hbase:meta region */
70    private final FavoredNodesPlan existingAssignmentPlan;
71    private final Set<TableName> disabledTables;
72    private final boolean excludeOfflinedSplitParents;
73  
74    public SnapshotOfRegionAssignmentFromMeta(CatalogTracker tracker) {
75      this(tracker, new HashSet<TableName>(), false);
76    }
77  
78    public SnapshotOfRegionAssignmentFromMeta(CatalogTracker tracker, Set<TableName> disabledTables,
79        boolean excludeOfflinedSplitParents) {
80      this.tracker = tracker;
81      tableToRegionMap = new HashMap<TableName, List<HRegionInfo>>();
82      regionToRegionServerMap = new HashMap<HRegionInfo, ServerName>();
83      regionServerToRegionMap = new HashMap<ServerName, List<HRegionInfo>>();
84      regionNameToRegionInfoMap = new TreeMap<String, HRegionInfo>();
85      existingAssignmentPlan = new FavoredNodesPlan();
86      this.disabledTables = disabledTables;
87      this.excludeOfflinedSplitParents = excludeOfflinedSplitParents;
88    }
89  
90    /**
91     * Initialize the region assignment snapshot by scanning the hbase:meta table
92     * @throws IOException
93     */
94    public void initialize() throws IOException {
95      LOG.info("Start to scan the hbase:meta for the current region assignment " +
96  		"snappshot");
97      // TODO: at some point this code could live in the MetaReader
98      Visitor v = new Visitor() {
99        @Override
100       public boolean visit(Result result) throws IOException {
101         try {
102           if (result ==  null || result.isEmpty()) return true;
103           Pair<HRegionInfo, ServerName> regionAndServer =
104               HRegionInfo.getHRegionInfoAndServerName(result);
105           HRegionInfo hri = regionAndServer.getFirst();
106           if (hri  == null) return true;
107           if (hri.getTable() == null) return true;
108           if (disabledTables.contains(hri.getTable())) {
109             return true;
110           }
111           // Are we to include split parents in the list?
112           if (excludeOfflinedSplitParents && hri.isSplit()) return true;
113           // Add the current assignment to the snapshot
114           addAssignment(hri, regionAndServer.getSecond());
115           addRegion(hri);
116           
117           // the code below is to handle favored nodes
118           byte[] favoredNodes = result.getValue(HConstants.CATALOG_FAMILY,
119               FavoredNodeAssignmentHelper.FAVOREDNODES_QUALIFIER);
120           if (favoredNodes == null) return true;
121           // Add the favored nodes into assignment plan
122           ServerName[] favoredServerList =
123               FavoredNodeAssignmentHelper.getFavoredNodesList(favoredNodes);
124           // Add the favored nodes into assignment plan
125           existingAssignmentPlan.updateFavoredNodesMap(hri,
126               Arrays.asList(favoredServerList));
127           return true;
128         } catch (RuntimeException e) {
129           LOG.error("Catche remote exception " + e.getMessage() +
130               " when processing" + result);
131           throw e;
132         }
133       }
134     };
135     // Scan hbase:meta to pick up user regions
136     MetaReader.fullScan(tracker, v);
137     //regionToRegionServerMap = regions;
138     LOG.info("Finished to scan the hbase:meta for the current region assignment" +
139       "snapshot");
140   }
141 
142   private void addRegion(HRegionInfo regionInfo) {
143     // Process the region name to region info map
144     regionNameToRegionInfoMap.put(regionInfo.getRegionNameAsString(), regionInfo);
145 
146     // Process the table to region map
147     TableName tableName = regionInfo.getTable();
148     List<HRegionInfo> regionList = tableToRegionMap.get(tableName);
149     if (regionList == null) {
150       regionList = new ArrayList<HRegionInfo>();
151     }
152     // Add the current region info into the tableToRegionMap
153     regionList.add(regionInfo);
154     tableToRegionMap.put(tableName, regionList);
155   }
156 
157   private void addAssignment(HRegionInfo regionInfo, ServerName server) {
158     // Process the region to region server map
159     regionToRegionServerMap.put(regionInfo, server);
160 
161     // Process the region server to region map
162     List<HRegionInfo> regionList = regionServerToRegionMap.get(server);
163     if (regionList == null) {
164       regionList = new ArrayList<HRegionInfo>();
165     }
166     regionList.add(regionInfo);
167     regionServerToRegionMap.put(server, regionList);
168   }
169 
170   /**
171    * Get the regioninfo for a region
172    * @return the regioninfo
173    */
174   public Map<String, HRegionInfo> getRegionNameToRegionInfoMap() {
175     return this.regionNameToRegionInfoMap;
176   }
177 
178   /**
179    * Get regions for tables
180    * @return a mapping from table to regions
181    */
182   public Map<TableName, List<HRegionInfo>> getTableToRegionMap() {
183     return tableToRegionMap;
184   }
185 
186   /**
187    * Get region to region server map
188    * @return region to region server map
189    */
190   public Map<HRegionInfo, ServerName> getRegionToRegionServerMap() {
191     return regionToRegionServerMap;
192   }
193 
194   /**
195    * Get regionserver to region map
196    * @return regionserver to region map
197    */
198   public Map<ServerName, List<HRegionInfo>> getRegionServerToRegionMap() {
199     return regionServerToRegionMap;
200   }
201 
202   /**
203    * Get the favored nodes plan
204    * @return the existing favored nodes plan
205    */
206   public FavoredNodesPlan getExistingAssignmentPlan() {
207     return this.existingAssignmentPlan;
208   }
209 
210   /**
211    * Get the table set
212    * @return the table set
213    */
214   public Set<TableName> getTableSet() {
215     return this.tableToRegionMap.keySet();
216   }
217 }