1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.hadoop.hbase.replication.regionserver;
20
21 import java.util.Date;
22 import java.util.HashMap;
23 import java.util.List;
24 import java.util.ArrayList;
25 import java.util.Map;
26
27 import org.apache.hadoop.hbase.classification.InterfaceAudience;
28 import org.apache.hadoop.hbase.protobuf.generated.ClusterStatusProtos;
29 import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;
30 import org.apache.hadoop.hbase.util.Strings;
31
32
33
34
35 @InterfaceAudience.Private
36 public class ReplicationLoad {
37
38
39 public static final ReplicationLoad EMPTY_REPLICATIONLOAD = new ReplicationLoad();
40
41 private List<MetricsSource> sourceMetricsList;
42 private MetricsSink sinkMetrics;
43
44 private List<ClusterStatusProtos.ReplicationLoadSource> replicationLoadSourceList;
45 private ClusterStatusProtos.ReplicationLoadSink replicationLoadSink;
46
47
48 public ReplicationLoad() {
49 super();
50 }
51
52
53
54
55
56
57
58 public void buildReplicationLoad(final List<MetricsSource> srMetricsList,
59 final MetricsSink skMetrics) {
60 this.sourceMetricsList = srMetricsList;
61 this.sinkMetrics = skMetrics;
62
63
64 ClusterStatusProtos.ReplicationLoadSink.Builder rLoadSinkBuild =
65 ClusterStatusProtos.ReplicationLoadSink.newBuilder();
66 rLoadSinkBuild.setAgeOfLastAppliedOp(sinkMetrics.getAgeOfLastAppliedOp());
67 rLoadSinkBuild.setTimeStampsOfLastAppliedOp(sinkMetrics.getTimeStampOfLastAppliedOp());
68 this.replicationLoadSink = rLoadSinkBuild.build();
69
70
71 Map<String, ClusterStatusProtos.ReplicationLoadSource> replicationLoadSourceMap =
72 new HashMap<String, ClusterStatusProtos.ReplicationLoadSource>();
73 for (MetricsSource sm : this.sourceMetricsList) {
74
75 String peerId = sm.getPeerID();
76 String[] parts = peerId.split("-", 2);
77 peerId = parts.length != 1 ? parts[0] : peerId;
78
79 long ageOfLastShippedOp = sm.getAgeOfLastShippedOp();
80 int sizeOfLogQueue = sm.getSizeOfLogQueue();
81 long timeStampOfLastShippedOp = sm.getTimeStampOfLastShippedOp();
82 long replicationLag =
83 calculateReplicationDelay(ageOfLastShippedOp, timeStampOfLastShippedOp, sizeOfLogQueue);
84
85 ClusterStatusProtos.ReplicationLoadSource rLoadSource = replicationLoadSourceMap.get(peerId);
86 if (rLoadSource != null) {
87 ageOfLastShippedOp = Math.max(rLoadSource.getAgeOfLastShippedOp(), ageOfLastShippedOp);
88 sizeOfLogQueue += rLoadSource.getSizeOfLogQueue();
89 timeStampOfLastShippedOp = Math.min(rLoadSource.getTimeStampOfLastShippedOp(),
90 timeStampOfLastShippedOp);
91 replicationLag = Math.max(rLoadSource.getReplicationLag(), replicationLag);
92 }
93
94 ClusterStatusProtos.ReplicationLoadSource.Builder rLoadSourceBuild =
95 ClusterStatusProtos.ReplicationLoadSource.newBuilder();
96 rLoadSourceBuild.setPeerID(peerId);
97 rLoadSourceBuild.setAgeOfLastShippedOp(ageOfLastShippedOp);
98 rLoadSourceBuild.setSizeOfLogQueue(sizeOfLogQueue);
99 rLoadSourceBuild.setTimeStampOfLastShippedOp(timeStampOfLastShippedOp);
100 rLoadSourceBuild.setReplicationLag(replicationLag);
101
102 replicationLoadSourceMap.put(peerId, rLoadSourceBuild.build());
103 }
104 this.replicationLoadSourceList = new ArrayList<ClusterStatusProtos.ReplicationLoadSource>(
105 replicationLoadSourceMap.values());
106 }
107
108 static long calculateReplicationDelay(long ageOfLastShippedOp,
109 long timeStampOfLastShippedOp, int sizeOfLogQueue) {
110 long replicationLag;
111 long timePassedAfterLastShippedOp =
112 EnvironmentEdgeManager.currentTime() - timeStampOfLastShippedOp;
113 if (sizeOfLogQueue > 1) {
114
115 replicationLag = Math.max(ageOfLastShippedOp, timePassedAfterLastShippedOp);
116 } else if (timePassedAfterLastShippedOp < 2 * ageOfLastShippedOp) {
117 replicationLag = ageOfLastShippedOp;
118 } else {
119
120
121 replicationLag = 0;
122 }
123 return replicationLag;
124 }
125
126
127
128
129
130 public String sourceToString() {
131 if (this.sourceMetricsList == null) return null;
132
133 StringBuilder sb = new StringBuilder();
134
135 for (ClusterStatusProtos.ReplicationLoadSource rls : this.replicationLoadSourceList) {
136
137 sb = Strings.appendKeyValue(sb, "\n PeerID", rls.getPeerID());
138 sb = Strings.appendKeyValue(sb, "AgeOfLastShippedOp", rls.getAgeOfLastShippedOp());
139 sb = Strings.appendKeyValue(sb, "SizeOfLogQueue", rls.getSizeOfLogQueue());
140 sb =
141 Strings.appendKeyValue(sb, "TimeStampsOfLastShippedOp",
142 (new Date(rls.getTimeStampOfLastShippedOp()).toString()));
143 sb = Strings.appendKeyValue(sb, "Replication Lag", rls.getReplicationLag());
144 }
145
146 return sb.toString();
147 }
148
149
150
151
152
153 public String sinkToString() {
154 if (this.replicationLoadSink == null) return null;
155
156 StringBuilder sb = new StringBuilder();
157 sb =
158 Strings.appendKeyValue(sb, "AgeOfLastAppliedOp",
159 this.replicationLoadSink.getAgeOfLastAppliedOp());
160 sb =
161 Strings.appendKeyValue(sb, "TimeStampsOfLastAppliedOp",
162 (new Date(this.replicationLoadSink.getTimeStampsOfLastAppliedOp()).toString()));
163
164 return sb.toString();
165 }
166
167 public ClusterStatusProtos.ReplicationLoadSink getReplicationLoadSink() {
168 return this.replicationLoadSink;
169 }
170
171 public List<ClusterStatusProtos.ReplicationLoadSource> getReplicationLoadSourceList() {
172 return this.replicationLoadSourceList;
173 }
174
175
176
177
178 @Override
179 public String toString() {
180 return this.sourceToString() + System.getProperty("line.separator") + this.sinkToString();
181 }
182
183 }