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.util.EnvironmentEdgeManager;
31
32  /**
33   * This class is for maintaining the various replication statistics for a source and publishing them
34   * through the metrics interfaces.
35   */
36  @InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.REPLICATION)
37  public class MetricsSource implements BaseSource {
38
39    private static final Log LOG = LogFactory.getLog(MetricsSource.class);
40
41    // tracks last shipped timestamp for each wal group
42    private Map<String, Long> lastTimeStamps = new HashMap<String, Long>();
43    private int lastQueueSize = 0;
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     singleSourceSource.clear();
185     globalSourceSource.decrSizeOfLogQueue(lastQueueSize);
186     globalSourceSource.decrSizeOfHFileRefsQueue(lastHFileRefsQueueSize);
187     lastTimeStamps.clear();
188     lastQueueSize = 0;
189     lastHFileRefsQueueSize = 0;
190   }
191
192   /**
193    * Get AgeOfLastShippedOp
194    * @return AgeOfLastShippedOp
195    */
196   public Long getAgeOfLastShippedOp() {
197     return singleSourceSource.getLastShippedAge();
198   }
199
200   /**
201    * Get the sizeOfLogQueue
202    * @return sizeOfLogQueue
203    */
204   public int getSizeOfLogQueue() {
205     return singleSourceSource.getSizeOfLogQueue();
206   }
207 
208   /**
209    * Get the timeStampsOfLastShippedOp, if there are multiple groups, return the latest one
210    * @return lastTimestampForAge
211    */
212   public long getTimeStampOfLastShippedOp() {
213     long lastTimestamp = 0L;
214     for (long ts : lastTimeStamps.values()) {
215       if (ts > lastTimestamp) {
216         lastTimestamp = ts;
217       }
218     }
219     return lastTimestamp;
220   }
221 
222   /**
223    * Get the slave peer ID
224    * @return peerID
225    */
226   public String getPeerID() {
227     return id;
228   }
229
230   public void incrSizeOfHFileRefsQueue(long size) {
231     singleSourceSource.incrSizeOfHFileRefsQueue(size);
232     globalSourceSource.incrSizeOfHFileRefsQueue(size);
233     lastHFileRefsQueueSize = size;
234   }
235
236   public void decrSizeOfHFileRefsQueue(int size) {
237     singleSourceSource.decrSizeOfHFileRefsQueue(size);
238     globalSourceSource.decrSizeOfHFileRefsQueue(size);
239     lastHFileRefsQueueSize -= size;
240     if (lastHFileRefsQueueSize < 0) {
241       lastHFileRefsQueueSize = 0;
242     }
243   }
244
245   @Override
246   public void init() {
247     singleSourceSource.init();
248     globalSourceSource.init();
249   }
250
251   @Override
252   public void setGauge(String gaugeName, long value) {
253     singleSourceSource.setGauge(gaugeName, value);
254     globalSourceSource.setGauge(gaugeName, value);
255   }
256
257   @Override
258   public void incGauge(String gaugeName, long delta) {
259     singleSourceSource.incGauge(gaugeName, delta);
260     globalSourceSource.incGauge(gaugeName, delta);
261   }
262
263   @Override
264   public void decGauge(String gaugeName, long delta) {
265     singleSourceSource.decGauge(gaugeName, delta);
266     globalSourceSource.decGauge(gaugeName, delta);
267   }
268
269   @Override
270   public void removeMetric(String key) {
271     singleSourceSource.removeMetric(key);
272     globalSourceSource.removeMetric(key);
273   }
274
275   @Override
276   public void incCounters(String counterName, long delta) {
277     singleSourceSource.incCounters(counterName, delta);
278     globalSourceSource.incCounters(counterName, delta);
279   }
280
281   @Override
282   public void updateHistogram(String name, long value) {
283     singleSourceSource.updateHistogram(name, value);
284     globalSourceSource.updateHistogram(name, value);
285   }
286
287   @Override
288   public String getMetricsContext() {
289     return globalSourceSource.getMetricsContext();
290   }
291
292   @Override
293   public String getMetricsDescription() {
294     return globalSourceSource.getMetricsDescription();
295   }
296
297   @Override
298   public String getMetricsJmxContext() {
299     return globalSourceSource.getMetricsJmxContext();
300   }
301
302   @Override
303   public String getMetricsName() {
304     return globalSourceSource.getMetricsName();
305   }
306 }