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 batches by the source */
48    public final MetricsRate shippedBatchesRate =
49        new MetricsRate("shippedBatchesRate", registry);
50  
51    /** Rate of log entries (can be multiple Puts) read from the logs */
52    public final MetricsRate logEditsReadRate =
53        new MetricsRate("logEditsReadRate", registry);
54  
55    /** Rate of log entries filtered by the source */
56    public final MetricsRate logEditsFilteredRate =
57        new MetricsRate("logEditsFilteredRate", registry);
58  
59    /** Age of the last operation that was shipped by the source */
60    private final MetricsLongValue ageOfLastShippedOp =
61        new MetricsLongValue("ageOfLastShippedOp", registry);
62  
63    /**
64     * Current size of the queue of logs to replicate,
65     * excluding the one being processed at the moment
66     */
67    public final MetricsIntValue sizeOfLogQueue =
68        new MetricsIntValue("sizeOfLogQueue", registry);
69  
70    // It's a little dirty to preset the age to now since if we fail
71    // to replicate the very first time then it will show that age instead
72    // of nothing (although that might not be good either).
73    private long lastTimestampForAge = System.currentTimeMillis();
74  
75    /**
76     * Constructor used to register the metrics
77     * @param id Name of the source this class is monitoring
78     */
79    public ReplicationSourceMetrics(String id) {
80      MetricsContext context = MetricsUtil.getContext("hbase");
81      String name = Thread.currentThread().getName();
82      metricsRecord = MetricsUtil.createRecord(context, "replication");
83      metricsRecord.setTag("RegionServer", name);
84      context.registerUpdater(this);
85      try {
86        id = URLEncoder.encode(id, "UTF8");
87      } catch (UnsupportedEncodingException e) {
88        id = "CAN'T ENCODE UTF8";
89      }
90      // export for JMX
91      replicationStatistics = new ReplicationStatistics(this.registry, "ReplicationSource for " + id);
92    }
93  
94    /**
95     * Set the age of the last edit that was shipped
96     * @param timestamp write time of the edit
97     */
98    public void setAgeOfLastShippedOp(long timestamp) {
99      lastTimestampForAge = timestamp;
100     ageOfLastShippedOp.set(System.currentTimeMillis() - lastTimestampForAge);
101   }
102 
103   /**
104    * Convenience method to use the last given timestamp to refresh the age
105    * of the last edit. Used when replication fails and need to keep that
106    * metric accurate.
107    */
108   public void refreshAgeOfLastShippedOp() {
109     setAgeOfLastShippedOp(lastTimestampForAge);
110   }
111 
112   @Override
113   public void doUpdates(MetricsContext metricsContext) {
114     synchronized (this) {
115       refreshAgeOfLastShippedOp();
116       this.shippedOpsRate.pushMetric(this.metricsRecord);
117       this.shippedBatchesRate.pushMetric(this.metricsRecord);
118       this.logEditsReadRate.pushMetric(this.metricsRecord);
119       this.logEditsFilteredRate.pushMetric(this.metricsRecord);
120       this.ageOfLastShippedOp.pushMetric(this.metricsRecord);
121       this.sizeOfLogQueue.pushMetric(this.metricsRecord);
122     }
123     this.metricsRecord.update();
124   }
125   
126   public void stopReportMetrics() {
127     if (this.replicationStatistics != null) {
128       this.replicationStatistics.unRegisterMBean();
129     }
130   }
131 }