View Javadoc

1   /**
2    * Copyright 2010 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  package org.apache.hadoop.hbase.replication.regionserver;
21  import java.io.UnsupportedEncodingException;
22  import java.net.URLEncoder;
23  
24  import org.apache.hadoop.hbase.metrics.MetricsRate;
25  import org.apache.hadoop.metrics.MetricsContext;
26  import org.apache.hadoop.metrics.MetricsRecord;
27  import org.apache.hadoop.metrics.MetricsUtil;
28  import org.apache.hadoop.metrics.Updater;
29  import org.apache.hadoop.metrics.jvm.JvmMetrics;
30  import org.apache.hadoop.metrics.util.MetricsIntValue;
31  import org.apache.hadoop.metrics.util.MetricsLongValue;
32  import org.apache.hadoop.metrics.util.MetricsRegistry;
33  
34  /**
35   * This class is for maintaining the various replication statistics
36   * for a source and publishing them through the metrics interfaces.
37   */
38  public class ReplicationSourceMetrics implements Updater {
39    private final MetricsRecord metricsRecord;
40    private MetricsRegistry registry = new MetricsRegistry();
41    private ReplicationStatistics replicationStatistics;
42  
43    /** Rate of shipped operations by the source */
44    public final MetricsRate shippedOpsRate =
45        new MetricsRate("shippedOpsRate", registry);
46  
47    /** Rate of shipped bytes (in KB) by the source */
48    public final MetricsRate shippedKBRate =
49        new MetricsRate("shippedBytesRate", registry);
50  
51    /** Rate of shipped batches by the source */
52    public final MetricsRate shippedBatchesRate =
53        new MetricsRate("shippedBatchesRate", registry);
54  
55    /** Rate of log entries (can be multiple Puts) read from the logs */
56    public final MetricsRate logEditsReadRate =
57        new MetricsRate("logEditsReadRate", registry);
58  
59    /** Rate of log entries filtered by the source */
60    public final MetricsRate logEditsFilteredRate =
61        new MetricsRate("logEditsFilteredRate", registry);
62  
63    /** Age of the last operation that was shipped by the source */
64    private final MetricsLongValue ageOfLastShippedOp =
65        new MetricsLongValue("ageOfLastShippedOp", registry);
66  
67    /**
68     * Current size of the queue of logs to replicate,
69     * excluding the one being processed at the moment
70     */
71    public final MetricsIntValue sizeOfLogQueue =
72        new MetricsIntValue("sizeOfLogQueue", registry);
73  
74    // It's a little dirty to preset the age to now since if we fail
75    // to replicate the very first time then it will show that age instead
76    // of nothing (although that might not be good either).
77    private long lastTimestampForAge = System.currentTimeMillis();
78  
79    /**
80     * Constructor used to register the metrics
81     * @param id Name of the source this class is monitoring
82     */
83    public ReplicationSourceMetrics(String id) {
84      MetricsContext context = MetricsUtil.getContext("hbase");
85      String name = Thread.currentThread().getName();
86      metricsRecord = MetricsUtil.createRecord(context, "replication");
87      metricsRecord.setTag("RegionServer", name);
88      context.registerUpdater(this);
89      try {
90        id = URLEncoder.encode(id, "UTF8");
91      } catch (UnsupportedEncodingException e) {
92        id = "CAN'T ENCODE UTF8";
93      }
94      // export for JMX
95      replicationStatistics = new ReplicationStatistics(this.registry, "ReplicationSource for " + id);
96    }
97  
98    /**
99     * Set the age of the last edit that was shipped
100    * @param timestamp write time of the edit
101    */
102   public void setAgeOfLastShippedOp(long timestamp) {
103     lastTimestampForAge = timestamp;
104     ageOfLastShippedOp.set(System.currentTimeMillis() - lastTimestampForAge);
105   }
106 
107   /**
108    * Convenience method to use the last given timestamp to refresh the age
109    * of the last edit. Used when replication fails and need to keep that
110    * metric accurate.
111    */
112   public void refreshAgeOfLastShippedOp() {
113     setAgeOfLastShippedOp(lastTimestampForAge);
114   }
115 
116   @Override
117   public void doUpdates(MetricsContext metricsContext) {
118     synchronized (this) {
119       refreshAgeOfLastShippedOp();
120       this.shippedOpsRate.pushMetric(this.metricsRecord);
121       this.shippedBatchesRate.pushMetric(this.metricsRecord);
122       this.shippedKBRate.pushMetric(this.metricsRecord);
123       this.logEditsReadRate.pushMetric(this.metricsRecord);
124       this.logEditsFilteredRate.pushMetric(this.metricsRecord);
125       this.ageOfLastShippedOp.pushMetric(this.metricsRecord);
126       this.sizeOfLogQueue.pushMetric(this.metricsRecord);
127     }
128     this.metricsRecord.update();
129   }
130   
131   public void stopReportMetrics() {
132     if (this.replicationStatistics != null) {
133       this.replicationStatistics.unRegisterMBean();
134     }
135   }
136 }