View Javadoc

1   /**
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  
19  package org.apache.hadoop.hbase.replication.regionserver;
20  
21  import java.util.HashMap;
22  import java.util.Map;
23  
24  import org.apache.commons.logging.Log;
25  import org.apache.commons.logging.LogFactory;
26  import org.apache.hadoop.hbase.classification.InterfaceAudience;
27  import org.apache.hadoop.hbase.CompatibilitySingletonFactory;
28  import org.apache.hadoop.hbase.HBaseInterfaceAudience;
29  import org.apache.hadoop.hbase.metrics.BaseSource;
30  import org.apache.hadoop.hbase.metrics.MetricRegistryInfo;
31  import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;
32  
33  /**
34   * This class is for maintaining the various replication statistics for a source and publishing them
35   * through the metrics interfaces.
36   */
37  @InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.REPLICATION)
38  public class MetricsSource implements BaseSource {
39  
40    private static final Log LOG = LogFactory.getLog(MetricsSource.class);
41  
42    // tracks last shipped timestamp for each wal group
43    private Map<String, Long> lastTimeStamps = new HashMap<String, Long>();
44    private long lastHFileRefsQueueSize = 0;
45    private String id;
46  
47    private final MetricsReplicationSourceSource singleSourceSource;
48    private final MetricsReplicationSourceSource globalSourceSource;
49  
50  
51    /**
52     * Constructor used to register the metrics
53     *
54     * @param id Name of the source this class is monitoring
55     */
56    public MetricsSource(String id) {
57      this.id = id;
58      singleSourceSource =
59          CompatibilitySingletonFactory.getInstance(MetricsReplicationSourceFactory.class)
60              .getSource(id);
61      globalSourceSource = CompatibilitySingletonFactory.getInstance(MetricsReplicationSourceFactory.class).getGlobalSource();
62    }
63  
64    /**
65     * Constructor for injecting custom (or test) MetricsReplicationSourceSources
66     * @param id Name of the source this class is monitoring
67     * @param singleSourceSource Class to monitor id-scoped metrics
68     * @param globalSourceSource Class to monitor global-scoped metrics
69     */
70    public MetricsSource(String id, MetricsReplicationSourceSource singleSourceSource,
71                         MetricsReplicationSourceSource globalSourceSource) {
72      this.id = id;
73      this.singleSourceSource = singleSourceSource;
74      this.globalSourceSource = globalSourceSource;
75    }
76  
77    /**
78     * Set the age of the last edit that was shipped
79     * @param timestamp write time of the edit
80     * @param walGroup which group we are setting
81     */
82    public void setAgeOfLastShippedOp(long timestamp, String walGroup) {
83      long age = EnvironmentEdgeManager.currentTime() - timestamp;
84      singleSourceSource.setLastShippedAge(age);
85      globalSourceSource.setLastShippedAge(age);
86      this.lastTimeStamps.put(walGroup, timestamp);
87    }
88  
89    /**
90     * Convenience method to use the last given timestamp to refresh the age of the last edit. Used
91     * when replication fails and need to keep that metric accurate.
92     * @param walGroupId id of the group to update
93     */
94    public void refreshAgeOfLastShippedOp(String walGroupId) {
95      Long lastTimestamp = this.lastTimeStamps.get(walGroupId);
96      if (lastTimestamp == null) {
97        this.lastTimeStamps.put(walGroupId, 0L);
98        lastTimestamp = 0L;
99      }
100     if (lastTimestamp > 0) {
101       setAgeOfLastShippedOp(lastTimestamp, walGroupId);
102     }
103   }
104 
105   /**
106    * Increment size of the log queue.
107    */
108   public void incrSizeOfLogQueue() {
109     singleSourceSource.incrSizeOfLogQueue(1);
110     globalSourceSource.incrSizeOfLogQueue(1);
111   }
112 
113   public void decrSizeOfLogQueue() {
114     singleSourceSource.decrSizeOfLogQueue(1);
115     globalSourceSource.decrSizeOfLogQueue(1);
116   }
117 
118   /**
119    * Add on the the number of log edits read
120    *
121    * @param delta the number of log edits read.
122    */
123   private void incrLogEditsRead(long delta) {
124     singleSourceSource.incrLogReadInEdits(delta);
125     globalSourceSource.incrLogReadInEdits(delta);
126   }
127 
128   /** Increment the number of log edits read by one. */
129   public void incrLogEditsRead() {
130     incrLogEditsRead(1);
131   }
132 
133   /**
134    * Add on the number of log edits filtered
135    *
136    * @param delta the number filtered.
137    */
138   public void incrLogEditsFiltered(long delta) {
139     singleSourceSource.incrLogEditsFiltered(delta);
140     globalSourceSource.incrLogEditsFiltered(delta);
141   }
142 
143   /** The number of log edits filtered out. */
144   public void incrLogEditsFiltered() {
145     incrLogEditsFiltered(1);
146   }
147 
148   /**
149    * Convience method to apply changes to metrics do to shipping a batch of logs.
150    *
151    * @param batchSize the size of the batch that was shipped to sinks.
152    */
153   public void shipBatch(long batchSize, int sizeInBytes) {
154     singleSourceSource.incrBatchesShipped(1);
155     globalSourceSource.incrBatchesShipped(1);
156 
157     singleSourceSource.incrOpsShipped(batchSize);
158     globalSourceSource.incrOpsShipped(batchSize);
159 
160     singleSourceSource.incrShippedBytes(sizeInBytes);
161     globalSourceSource.incrShippedBytes(sizeInBytes);
162   }
163 
164   /**
165    * Convience method to apply changes to metrics do to shipping a batch of logs.
166    *
167    * @param batchSize the size of the batch that was shipped to sinks.
168    * @param hfiles total number of hfiles shipped to sinks.
169    */
170   public void shipBatch(long batchSize, int sizeInBytes, long hfiles) {
171     shipBatch(batchSize, sizeInBytes);
172     singleSourceSource.incrHFilesShipped(hfiles);
173     globalSourceSource.incrHFilesShipped(hfiles);
174   }
175 
176   /** increase the byte number read by source from log file */
177   public void incrLogReadInBytes(long readInBytes) {
178     singleSourceSource.incrLogReadInBytes(readInBytes);
179     globalSourceSource.incrLogReadInBytes(readInBytes);
180   }
181 
182   /** Removes all metrics about this Source. */
183   public void clear() {
184     int lastQueueSize = singleSourceSource.getSizeOfLogQueue();
185     globalSourceSource.decrSizeOfLogQueue(lastQueueSize);
186     singleSourceSource.decrSizeOfLogQueue(lastQueueSize);
187     singleSourceSource.clear();
188     globalSourceSource.decrSizeOfHFileRefsQueue(lastHFileRefsQueueSize);
189     lastTimeStamps.clear();
190     lastHFileRefsQueueSize = 0;
191   }
192 
193   /**
194    * Get AgeOfLastShippedOp
195    * @return AgeOfLastShippedOp
196    */
197   public Long getAgeOfLastShippedOp() {
198     return singleSourceSource.getLastShippedAge();
199   }
200 
201   /**
202    * Get the sizeOfLogQueue
203    * @return sizeOfLogQueue
204    */
205   public int getSizeOfLogQueue() {
206     return singleSourceSource.getSizeOfLogQueue();
207   }
208 
209   /**
210    * Get the timeStampsOfLastShippedOp, if there are multiple groups, return the latest one
211    * @return lastTimestampForAge
212    */
213   public long getTimeStampOfLastShippedOp() {
214     long lastTimestamp = 0L;
215     for (long ts : lastTimeStamps.values()) {
216       if (ts > lastTimestamp) {
217         lastTimestamp = ts;
218       }
219     }
220     return lastTimestamp;
221   }
222 
223   /**
224    * Get the slave peer ID
225    * @return peerID
226    */
227   public String getPeerID() {
228     return id;
229   }
230 
231   public void incrSizeOfHFileRefsQueue(long size) {
232     singleSourceSource.incrSizeOfHFileRefsQueue(size);
233     globalSourceSource.incrSizeOfHFileRefsQueue(size);
234     lastHFileRefsQueueSize = size;
235   }
236 
237   public void decrSizeOfHFileRefsQueue(int size) {
238     singleSourceSource.decrSizeOfHFileRefsQueue(size);
239     globalSourceSource.decrSizeOfHFileRefsQueue(size);
240     lastHFileRefsQueueSize -= size;
241     if (lastHFileRefsQueueSize < 0) {
242       lastHFileRefsQueueSize = 0;
243     }
244   }
245 
246   public void incrUnknownFileLengthForClosedWAL() {
247     singleSourceSource.incrUnknownFileLengthForClosedWAL();
248     globalSourceSource.incrUnknownFileLengthForClosedWAL();
249   }
250 
251   public void incrUncleanlyClosedWALs() {
252     singleSourceSource.incrUncleanlyClosedWALs();
253     globalSourceSource.incrUncleanlyClosedWALs();
254   }
255 
256   public void incrBytesSkippedInUncleanlyClosedWALs(final long bytes) {
257     singleSourceSource.incrBytesSkippedInUncleanlyClosedWALs(bytes);
258     globalSourceSource.incrBytesSkippedInUncleanlyClosedWALs(bytes);
259   }
260 
261   public void incrRestartedWALReading() {
262     singleSourceSource.incrRestartedWALReading();
263     globalSourceSource.incrRestartedWALReading();
264   }
265 
266   public void incrRepeatedFileBytes(final long bytes) {
267     singleSourceSource.incrRepeatedFileBytes(bytes);
268     globalSourceSource.incrRepeatedFileBytes(bytes);
269   }
270 
271   public void incrCompletedWAL() {
272     singleSourceSource.incrCompletedWAL();
273     globalSourceSource.incrCompletedWAL();
274   }
275 
276   public void incrCompletedRecoveryQueue() {
277     singleSourceSource.incrCompletedRecoveryQueue();
278     globalSourceSource.incrCompletedRecoveryQueue();
279   }
280 
281   public void incrFailedRecoveryQueue() {
282     globalSourceSource.incrFailedRecoveryQueue();
283   }
284 
285 
286   @Override
287   public void init() {
288     singleSourceSource.init();
289     globalSourceSource.init();
290   }
291 
292   @Override
293   public void setGauge(String gaugeName, long value) {
294     singleSourceSource.setGauge(gaugeName, value);
295     globalSourceSource.setGauge(gaugeName, value);
296   }
297 
298   @Override
299   public void incGauge(String gaugeName, long delta) {
300     singleSourceSource.incGauge(gaugeName, delta);
301     globalSourceSource.incGauge(gaugeName, delta);
302   }
303 
304   @Override
305   public void decGauge(String gaugeName, long delta) {
306     singleSourceSource.decGauge(gaugeName, delta);
307     globalSourceSource.decGauge(gaugeName, delta);
308   }
309 
310   @Override
311   public void removeMetric(String key) {
312     singleSourceSource.removeMetric(key);
313     globalSourceSource.removeMetric(key);
314   }
315 
316   @Override
317   public void incCounters(String counterName, long delta) {
318     singleSourceSource.incCounters(counterName, delta);
319     globalSourceSource.incCounters(counterName, delta);
320   }
321 
322   @Override
323   public void updateHistogram(String name, long value) {
324     singleSourceSource.updateHistogram(name, value);
325     globalSourceSource.updateHistogram(name, value);
326   }
327 
328   @Override
329   public String getMetricsContext() {
330     return globalSourceSource.getMetricsContext();
331   }
332 
333   @Override
334   public String getMetricsDescription() {
335     return globalSourceSource.getMetricsDescription();
336   }
337 
338   @Override
339   public String getMetricsJmxContext() {
340     return globalSourceSource.getMetricsJmxContext();
341   }
342 
343   @Override
344   public String getMetricsName() {
345     return globalSourceSource.getMetricsName();
346   }
347 
348   @Override
349   public MetricRegistryInfo getMetricRegistryInfo() {
350     return new MetricRegistryInfo(getMetricsName(), getMetricsDescription(),
351       getMetricsContext(), getMetricsJmxContext(), true);
352   }
353 }