You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hbase.apache.org by st...@apache.org on 2008/06/04 21:10:04 UTC

svn commit: r663346 - in /hadoop/hbase/trunk/src: java/org/apache/hadoop/hbase/RegionHistorian.java webapps/master/regionhistorian.jsp

Author: stack
Date: Wed Jun  4 12:10:03 2008
New Revision: 663346

URL: http://svn.apache.org/viewvc?rev=663346&view=rev
Log:
HBASE-533 Region Historian (forgot to add these files)

Added:
    hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/RegionHistorian.java
    hadoop/hbase/trunk/src/webapps/master/regionhistorian.jsp

Added: hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/RegionHistorian.java
URL: http://svn.apache.org/viewvc/hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/RegionHistorian.java?rev=663346&view=auto
==============================================================================
--- hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/RegionHistorian.java (added)
+++ hadoop/hbase/trunk/src/java/org/apache/hadoop/hbase/RegionHistorian.java Wed Jun  4 12:10:03 2008
@@ -0,0 +1,291 @@
+/**
+ * Copyright 2008 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.IOException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.GregorianCalendar;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.hbase.client.HTable;
+import org.apache.hadoop.hbase.io.BatchUpdate;
+import org.apache.hadoop.hbase.io.Cell;
+import org.apache.hadoop.hbase.util.Bytes;
+/**
+ * The Region Historian task is to keep track of every modification a region
+ * has to go trought. Public methods are used to update the information in the
+ * .META. table and to retreive it.
+ */
+public class RegionHistorian implements HConstants {
+
+  static final Log LOG = LogFactory.getLog(RegionHistorian.class);
+
+  private HTable metaTable;
+
+  private GregorianCalendar cal = new GregorianCalendar();
+
+  /** Singleton reference */
+  private static RegionHistorian historian;
+
+  /** Date formater for the timestamp in RegionHistoryInformation */
+  private static SimpleDateFormat dateFormat = new SimpleDateFormat(
+  "EEE, d MMM yyyy HH:mm:ss");
+
+  public static enum HistorianColumnKey  {
+    REGION_CREATION ( Bytes.toBytes(COLUMN_FAMILY_HISTORIAN_STR+"creation")),
+    REGION_OPEN ( Bytes.toBytes(COLUMN_FAMILY_HISTORIAN_STR+"open")),
+    REGION_SPLIT ( Bytes.toBytes(COLUMN_FAMILY_HISTORIAN_STR+"split")),
+    REGION_COMPACTION ( Bytes.toBytes(COLUMN_FAMILY_HISTORIAN_STR+"compaction")),
+    REGION_FLUSH ( Bytes.toBytes(COLUMN_FAMILY_HISTORIAN_STR+"flush")),
+    REGION_ASSIGNMENT ( Bytes.toBytes(COLUMN_FAMILY_HISTORIAN_STR+"assignment"));
+
+    public byte[] key;
+
+    HistorianColumnKey(byte[] key) {
+      this.key = key;
+    }
+  } 
+
+  /**
+   * Default constructor. Initializes reference to .META. table
+   *
+   */
+  private RegionHistorian() {
+    HBaseConfiguration conf = new HBaseConfiguration();
+
+    try {
+      metaTable = new HTable(conf, META_TABLE_NAME);
+      LOG.debug("Region historian is ready.");
+    } catch (IOException ioe) {
+      LOG.warn("Unable to create RegionHistorian", ioe);
+    }
+  }
+
+  /**
+   * Singleton method
+   * 
+   * @return The region historian
+   */
+  public static RegionHistorian getInstance() {
+    if (historian == null) {
+      historian = new RegionHistorian();
+    }
+    return historian;
+  }
+
+  /**
+   * Returns, for a given region name, an ordered list by timestamp of all
+   * values in the historian column of the .META. table.
+   * 
+   * @param regionName
+   *          Region name as a string
+   * @return List of RegionHistoryInformation
+   */
+  public static List<RegionHistoryInformation> getRegionHistory(
+      String regionName) {
+    getInstance();
+    List<RegionHistoryInformation> informations = new ArrayList<RegionHistoryInformation>();
+    try {
+      /*
+       * TODO REGION_HISTORIAN_KEYS is used because there is no other for the
+       * moment to retrieve all version and to have the column key information.
+       * To be changed when HTable.getRow handles versions.
+       */
+      for (HistorianColumnKey keyEnu : HistorianColumnKey.values()) {
+        byte[] columnKey = keyEnu.key;
+        Cell[] cells = historian.metaTable.get(Bytes.toBytes(regionName),
+            columnKey, ALL_VERSIONS);
+        if (cells != null) {
+          for (Cell cell : cells) {
+            informations.add(historian.new RegionHistoryInformation(cell
+                .getTimestamp(), Bytes.toString(columnKey).split(":")[1], Bytes
+                .toString(cell.getValue())));
+          }
+        }
+      }
+    } catch (IOException ioe) {
+      LOG.warn("Unable to retrieve region history", ioe);
+    }
+    Collections.sort(informations);
+    return informations;
+  }
+  
+  /**
+   * Method to add a creation event to the row in the .META table
+   * 
+   * @param info
+   */
+  public static void addRegionAssignment(HRegionInfo info, String serverName) {
+
+    add(HistorianColumnKey.REGION_ASSIGNMENT.key, "Region assigned to server "
+        + serverName, info);
+  }
+
+  /**
+   * Method to add a creation event to the row in the .META table
+   * 
+   * @param info
+   */
+  public static void addRegionCreation(HRegionInfo info) {
+
+    add(HistorianColumnKey.REGION_CREATION.key, "Region creation", info);
+  }
+
+  /**
+   * Method to add a opening event to the row in the .META table
+   * 
+   * @param info
+   * @param address
+   */
+  public static void addRegionOpen(HRegionInfo info, HServerAddress address) {
+
+    add(HistorianColumnKey.REGION_OPEN.key, "Region opened on server : "
+        + address.getHostname(), info);
+  }
+
+  /**
+   * Method to add a split event to the rows in the .META table with
+   * information from oldInfo.
+   * @param oldInfo
+   * @param newInfo1 
+   * @param newInfo2
+   */
+  public static void addRegionSplit(HRegionInfo oldInfo, HRegionInfo newInfo1,
+      HRegionInfo newInfo2) {
+
+    HRegionInfo[] infos = new HRegionInfo[] { newInfo1, newInfo2 };
+    for (HRegionInfo info : infos) {
+      add(HistorianColumnKey.REGION_SPLIT.key, "Region split from  : "
+          + oldInfo.getRegionNameAsString(), info);
+    }
+  }
+
+  /**
+   * Method to add a compaction event to the row in the .META table
+   * 
+   * @param info
+   */
+  public static void addRegionCompaction(HRegionInfo info, String timeTaken) {
+    if (LOG.isDebugEnabled()) {
+      add(HistorianColumnKey.REGION_COMPACTION.key,
+          "Region compaction completed in " + timeTaken, info);
+    }
+  }
+
+  /**
+   * Method to add a flush event to the row in the .META table
+   * 
+   * @param info
+   */
+  public static void addRegionFlush(HRegionInfo info, String timeTaken) {
+    if (LOG.isDebugEnabled()) {
+      add(HistorianColumnKey.REGION_FLUSH.key, "Region flush completed in "
+          + timeTaken, info);
+    }
+  }
+
+  /**
+   * Method to add an event with LATEST_TIMESTAMP.
+   * @param column
+   * @param text
+   * @param info
+   */
+  private static void add(byte[] column, String text, HRegionInfo info) {
+    add(column, text, info, LATEST_TIMESTAMP);
+  }
+
+  /**
+   * Method to add an event with provided information.
+   * @param column
+   * @param text
+   * @param info
+   * @param timestamp
+   */
+  private static void add(byte[] column, String text, HRegionInfo info, long timestamp) {
+    if (!info.isMetaRegion()) {
+      getInstance();
+      BatchUpdate batch = new BatchUpdate(info.getRegionName());
+      batch.setTimestamp(timestamp);
+      batch.put(column, Bytes.toBytes(text));
+      try {
+        historian.metaTable.commit(batch);
+      } catch (IOException ioe) {
+        LOG.warn("Unable to '" + text + "'", ioe);
+      }
+    }
+  }
+
+  /**
+   * Inner class that only contains information about an event.
+   * 
+   */
+  public class RegionHistoryInformation implements
+  Comparable<RegionHistoryInformation> {
+
+    private long timestamp;
+
+    private String event;
+
+    private String description;
+
+    public RegionHistoryInformation(long timestamp, String event,
+        String description) {
+      this.timestamp = timestamp;
+      this.event = event;
+      this.description = description;
+    }
+
+    /**
+     * Returns the inverse value of Long.compareTo
+     */
+    public int compareTo(RegionHistoryInformation otherInfo) {
+      return -1 * Long.valueOf(timestamp).compareTo(otherInfo.getTimestamp());
+    }
+
+    public String getEvent() {
+      return event;
+    }
+
+    public String getDescription() {
+      return description;
+    }
+
+    public long getTimestamp() {
+      return timestamp;
+    }
+
+    /**
+     * Returns the value of the timestamp processed
+     * with the date formater.
+     * @return
+     */
+    public String getTimestampAsString() {
+      cal.setTimeInMillis(timestamp);
+      return dateFormat.format(cal.getTime());
+    }
+
+  }
+
+}

Added: hadoop/hbase/trunk/src/webapps/master/regionhistorian.jsp
URL: http://svn.apache.org/viewvc/hadoop/hbase/trunk/src/webapps/master/regionhistorian.jsp?rev=663346&view=auto
==============================================================================
--- hadoop/hbase/trunk/src/webapps/master/regionhistorian.jsp (added)
+++ hadoop/hbase/trunk/src/webapps/master/regionhistorian.jsp Wed Jun  4 12:10:03 2008
@@ -0,0 +1,42 @@
+<%@ page contentType="text/html;charset=UTF-8"
+  import="java.util.List"
+  import="org.apache.hadoop.hbase.RegionHistorian"
+  import="org.apache.hadoop.hbase.RegionHistorian.RegionHistoryInformation"
+  import="org.apache.hadoop.hbase.HConstants"%><%
+  String regionName = request.getParameter("regionname");
+  List<RegionHistoryInformation> informations = RegionHistorian.getRegionHistory(regionName);
+%><?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
+  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/>
+<title>Region in <%= regionName %></title>
+<link rel="stylesheet" type="text/css" href="/static/hbase.css" />
+</head>
+
+<body>
+<a id="logo" href="http://wiki.apache.org/lucene-hadoop/Hbase"><img src="/static/hbase_logo_med.gif" alt="HBase Logo" title="HBase Logo" /></a>
+<h1 id="page_title">Region <%= regionName %></h1>
+<p id="links_menu"><a href="/master.jsp">Master</a>, <a href="/logs/">Local logs</a>, <a href="/stacks">Thread Dump</a>, <a href="/logLevel">Log Level</a></p>
+<hr id="head_rule" />
+<%if(informations != null && informations.size() > 0) { %>
+<table><tr><th>Timestamp</th><th>Event</th><th>Description</th></tr>
+<%  for( RegionHistoryInformation information : informations) {%>
+<tr><td><%= information.getTimestampAsString() %></td><td><%= information.getEvent() %></td><td><%= information.getDescription()%></td></tr>
+<%  } %>
+</table>
+<p>
+Master is the source of following events : 
+creation,open,assignment. 
+Regions are the source of following events :
+split,compaction, flush
+</p>
+<%} else {%>
+<p>
+This region is no longer available. It may be due to a split, a merge or the name changed.
+</p>
+<%} %>
+
+
+</body>
+</html>