001/**
002 * Copyright The Apache Software Foundation
003 *
004 * Licensed to the Apache Software Foundation (ASF) under one
005 * or more contributor license agreements.  See the NOTICE file
006 * distributed with this work for additional information
007 * regarding copyright ownership.  The ASF licenses this file
008 * to you under the Apache License, Version 2.0 (the
009 * "License"); you may not use this file except in compliance
010 * with the License.  You may obtain a copy of the License at
011 *
012 *     http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing, software
015 * distributed under the License is distributed on an "AS IS" BASIS,
016 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017 * See the License for the specific language governing permissions and
018 * limitations under the License.
019 */
020
021package org.apache.hadoop.hbase;
022
023import java.util.Collections;
024import java.util.List;
025import java.util.Map;
026import java.util.stream.Collectors;
027import org.apache.hadoop.hbase.util.Strings;
028import org.apache.yetus.audience.InterfaceAudience;
029
030import org.apache.hbase.thirdparty.com.google.common.base.Preconditions;
031import org.apache.hbase.thirdparty.com.google.protobuf.UnsafeByteOperations;
032
033import org.apache.hadoop.hbase.shaded.protobuf.generated.AdminProtos;
034import org.apache.hadoop.hbase.shaded.protobuf.generated.ClusterStatusProtos;
035import org.apache.hadoop.hbase.shaded.protobuf.generated.HBaseProtos;
036
037@InterfaceAudience.Private
038public final class RegionMetricsBuilder {
039
040  public static List<RegionMetrics> toRegionMetrics(
041      AdminProtos.GetRegionLoadResponse regionLoadResponse) {
042    return regionLoadResponse.getRegionLoadsList().stream()
043        .map(RegionMetricsBuilder::toRegionMetrics).collect(Collectors.toList());
044  }
045
046  public static RegionMetrics toRegionMetrics(ClusterStatusProtos.RegionLoad regionLoadPB) {
047    return RegionMetricsBuilder
048        .newBuilder(regionLoadPB.getRegionSpecifier().getValue().toByteArray())
049        .setBloomFilterSize(new Size(regionLoadPB.getTotalStaticBloomSizeKB(), Size.Unit.KILOBYTE))
050        .setCompactedCellCount(regionLoadPB.getCurrentCompactedKVs())
051        .setCompactingCellCount(regionLoadPB.getTotalCompactingKVs())
052        .setCompletedSequenceId(regionLoadPB.getCompleteSequenceId())
053        .setDataLocality(regionLoadPB.hasDataLocality() ? regionLoadPB.getDataLocality() : 0.0f)
054        .setFilteredReadRequestCount(regionLoadPB.getFilteredReadRequestsCount())
055        .setStoreFileUncompressedDataIndexSize(new Size(regionLoadPB.getTotalStaticIndexSizeKB(),
056          Size.Unit.KILOBYTE))
057        .setLastMajorCompactionTimestamp(regionLoadPB.getLastMajorCompactionTs())
058        .setMemStoreSize(new Size(regionLoadPB.getMemStoreSizeMB(), Size.Unit.MEGABYTE))
059        .setReadRequestCount(regionLoadPB.getReadRequestsCount())
060        .setWriteRequestCount(regionLoadPB.getWriteRequestsCount())
061        .setStoreFileIndexSize(new Size(regionLoadPB.getStorefileIndexSizeKB(),
062          Size.Unit.KILOBYTE))
063        .setStoreFileRootLevelIndexSize(new Size(regionLoadPB.getRootIndexSizeKB(),
064          Size.Unit.KILOBYTE))
065        .setStoreCount(regionLoadPB.getStores())
066        .setStoreFileCount(regionLoadPB.getStorefiles())
067        .setStoreFileSize(new Size(regionLoadPB.getStorefileSizeMB(), Size.Unit.MEGABYTE))
068        .setStoreSequenceIds(regionLoadPB.getStoreCompleteSequenceIdList().stream()
069          .collect(Collectors.toMap(
070            (ClusterStatusProtos.StoreSequenceId s) -> s.getFamilyName().toByteArray(),
071              ClusterStatusProtos.StoreSequenceId::getSequenceId)))
072        .setUncompressedStoreFileSize(
073          new Size(regionLoadPB.getStoreUncompressedSizeMB(),Size.Unit.MEGABYTE))
074        .build();
075  }
076
077  private static List<ClusterStatusProtos.StoreSequenceId> toStoreSequenceId(
078      Map<byte[], Long> ids) {
079    return ids.entrySet().stream()
080        .map(e -> ClusterStatusProtos.StoreSequenceId.newBuilder()
081          .setFamilyName(UnsafeByteOperations.unsafeWrap(e.getKey()))
082          .setSequenceId(e.getValue())
083          .build())
084        .collect(Collectors.toList());
085  }
086
087  public static ClusterStatusProtos.RegionLoad toRegionLoad(RegionMetrics regionMetrics) {
088    return ClusterStatusProtos.RegionLoad.newBuilder()
089        .setRegionSpecifier(HBaseProtos.RegionSpecifier
090          .newBuilder().setType(HBaseProtos.RegionSpecifier.RegionSpecifierType.REGION_NAME)
091          .setValue(UnsafeByteOperations.unsafeWrap(regionMetrics.getRegionName()))
092          .build())
093        .setTotalStaticBloomSizeKB((int) regionMetrics.getBloomFilterSize()
094          .get(Size.Unit.KILOBYTE))
095        .setCurrentCompactedKVs(regionMetrics.getCompactedCellCount())
096        .setTotalCompactingKVs(regionMetrics.getCompactingCellCount())
097        .setCompleteSequenceId(regionMetrics.getCompletedSequenceId())
098        .setDataLocality(regionMetrics.getDataLocality())
099        .setFilteredReadRequestsCount(regionMetrics.getFilteredReadRequestCount())
100        .setTotalStaticIndexSizeKB((int) regionMetrics.getStoreFileUncompressedDataIndexSize()
101          .get(Size.Unit.KILOBYTE))
102        .setLastMajorCompactionTs(regionMetrics.getLastMajorCompactionTimestamp())
103        .setMemStoreSizeMB((int) regionMetrics.getMemStoreSize().get(Size.Unit.MEGABYTE))
104        .setReadRequestsCount(regionMetrics.getReadRequestCount())
105        .setWriteRequestsCount(regionMetrics.getWriteRequestCount())
106        .setStorefileIndexSizeKB((long) regionMetrics.getStoreFileIndexSize()
107          .get(Size.Unit.KILOBYTE))
108        .setRootIndexSizeKB((int) regionMetrics.getStoreFileRootLevelIndexSize()
109          .get(Size.Unit.KILOBYTE))
110        .setStores(regionMetrics.getStoreCount())
111        .setStorefiles(regionMetrics.getStoreCount())
112        .setStorefileSizeMB((int) regionMetrics.getStoreFileSize().get(Size.Unit.MEGABYTE))
113        .addAllStoreCompleteSequenceId(toStoreSequenceId(regionMetrics.getStoreSequenceId()))
114        .setStoreUncompressedSizeMB(
115          (int) regionMetrics.getUncompressedStoreFileSize().get(Size.Unit.MEGABYTE))
116        .build();
117  }
118
119  public static RegionMetricsBuilder newBuilder(byte[] name) {
120    return new RegionMetricsBuilder(name);
121  }
122
123  private final byte[] name;
124  private int storeCount;
125  private int storeFileCount;
126  private long compactingCellCount;
127  private long compactedCellCount;
128  private Size storeFileSize = Size.ZERO;
129  private Size memStoreSize = Size.ZERO;
130  private Size indexSize = Size.ZERO;
131  private Size rootLevelIndexSize = Size.ZERO;
132  private Size uncompressedDataIndexSize = Size.ZERO;
133  private Size bloomFilterSize = Size.ZERO;
134  private Size uncompressedStoreFileSize = Size.ZERO;
135  private long writeRequestCount;
136  private long readRequestCount;
137  private long filteredReadRequestCount;
138  private long completedSequenceId;
139  private Map<byte[], Long> storeSequenceIds = Collections.emptyMap();
140  private float dataLocality;
141  private long lastMajorCompactionTimestamp;
142  private RegionMetricsBuilder(byte[] name) {
143    this.name = name;
144  }
145
146  public RegionMetricsBuilder setStoreCount(int value) {
147    this.storeCount = value;
148    return this;
149  }
150  public RegionMetricsBuilder setStoreFileCount(int value) {
151    this.storeFileCount = value;
152    return this;
153  }
154  public RegionMetricsBuilder setCompactingCellCount(long value) {
155    this.compactingCellCount = value;
156    return this;
157  }
158  public RegionMetricsBuilder setCompactedCellCount(long value) {
159    this.compactedCellCount = value;
160    return this;
161  }
162  public RegionMetricsBuilder setStoreFileSize(Size value) {
163    this.storeFileSize = value;
164    return this;
165  }
166  public RegionMetricsBuilder setMemStoreSize(Size value) {
167    this.memStoreSize = value;
168    return this;
169  }
170  public RegionMetricsBuilder setStoreFileIndexSize(Size value) {
171    this.indexSize = value;
172    return this;
173  }
174  public RegionMetricsBuilder setStoreFileRootLevelIndexSize(Size value) {
175    this.rootLevelIndexSize = value;
176    return this;
177  }
178  public RegionMetricsBuilder setStoreFileUncompressedDataIndexSize(Size value) {
179    this.uncompressedDataIndexSize = value;
180    return this;
181  }
182  public RegionMetricsBuilder setBloomFilterSize(Size value) {
183    this.bloomFilterSize = value;
184    return this;
185  }
186  public RegionMetricsBuilder setUncompressedStoreFileSize(Size value) {
187    this.uncompressedStoreFileSize = value;
188    return this;
189  }
190  public RegionMetricsBuilder setWriteRequestCount(long value) {
191    this.writeRequestCount = value;
192    return this;
193  }
194  public RegionMetricsBuilder setReadRequestCount(long value) {
195    this.readRequestCount = value;
196    return this;
197  }
198  public RegionMetricsBuilder setFilteredReadRequestCount(long value) {
199    this.filteredReadRequestCount = value;
200    return this;
201  }
202  public RegionMetricsBuilder setCompletedSequenceId(long value) {
203    this.completedSequenceId = value;
204    return this;
205  }
206  public RegionMetricsBuilder setStoreSequenceIds(Map<byte[], Long> value) {
207    this.storeSequenceIds = value;
208    return this;
209  }
210  public RegionMetricsBuilder setDataLocality(float value) {
211    this.dataLocality = value;
212    return this;
213  }
214  public RegionMetricsBuilder setLastMajorCompactionTimestamp(long value) {
215    this.lastMajorCompactionTimestamp = value;
216    return this;
217  }
218
219  public RegionMetrics build() {
220    return new RegionMetricsImpl(name,
221        storeCount,
222        storeFileCount,
223        compactingCellCount,
224        compactedCellCount,
225        storeFileSize,
226        memStoreSize,
227        indexSize,
228        rootLevelIndexSize,
229        uncompressedDataIndexSize,
230        bloomFilterSize,
231        uncompressedStoreFileSize,
232        writeRequestCount,
233        readRequestCount,
234        filteredReadRequestCount,
235        completedSequenceId,
236        storeSequenceIds,
237        dataLocality,
238        lastMajorCompactionTimestamp);
239  }
240
241  private static class RegionMetricsImpl implements RegionMetrics {
242    private final byte[] name;
243    private final int storeCount;
244    private final int storeFileCount;
245    private final long compactingCellCount;
246    private final long compactedCellCount;
247    private final Size storeFileSize;
248    private final Size memStoreSize;
249    private final Size indexSize;
250    private final Size rootLevelIndexSize;
251    private final Size uncompressedDataIndexSize;
252    private final Size bloomFilterSize;
253    private final Size uncompressedStoreFileSize;
254    private final long writeRequestCount;
255    private final long readRequestCount;
256    private final long filteredReadRequestCount;
257    private final long completedSequenceId;
258    private final Map<byte[], Long> storeSequenceIds;
259    private final float dataLocality;
260    private final long lastMajorCompactionTimestamp;
261    RegionMetricsImpl(byte[] name,
262        int storeCount,
263        int storeFileCount,
264        final long compactingCellCount,
265        long compactedCellCount,
266        Size storeFileSize,
267        Size memStoreSize,
268        Size indexSize,
269        Size rootLevelIndexSize,
270        Size uncompressedDataIndexSize,
271        Size bloomFilterSize,
272        Size uncompressedStoreFileSize,
273        long writeRequestCount,
274        long readRequestCount,
275        long filteredReadRequestCount,
276        long completedSequenceId,
277        Map<byte[], Long> storeSequenceIds,
278        float dataLocality,
279        long lastMajorCompactionTimestamp) {
280      this.name = Preconditions.checkNotNull(name);
281      this.storeCount = storeCount;
282      this.storeFileCount = storeFileCount;
283      this.compactingCellCount = compactingCellCount;
284      this.compactedCellCount = compactedCellCount;
285      this.storeFileSize = Preconditions.checkNotNull(storeFileSize);
286      this.memStoreSize = Preconditions.checkNotNull(memStoreSize);
287      this.indexSize = Preconditions.checkNotNull(indexSize);
288      this.rootLevelIndexSize = Preconditions.checkNotNull(rootLevelIndexSize);
289      this.uncompressedDataIndexSize = Preconditions.checkNotNull(uncompressedDataIndexSize);
290      this.bloomFilterSize = Preconditions.checkNotNull(bloomFilterSize);
291      this.uncompressedStoreFileSize = Preconditions.checkNotNull(uncompressedStoreFileSize);
292      this.writeRequestCount = writeRequestCount;
293      this.readRequestCount = readRequestCount;
294      this.filteredReadRequestCount = filteredReadRequestCount;
295      this.completedSequenceId = completedSequenceId;
296      this.storeSequenceIds = Preconditions.checkNotNull(storeSequenceIds);
297      this.dataLocality = dataLocality;
298      this.lastMajorCompactionTimestamp = lastMajorCompactionTimestamp;
299    }
300
301    @Override
302    public byte[] getRegionName() {
303      return name;
304    }
305
306    @Override
307    public int getStoreCount() {
308      return storeCount;
309    }
310
311    @Override
312    public int getStoreFileCount() {
313      return storeFileCount;
314    }
315
316    @Override
317    public Size getStoreFileSize() {
318      return storeFileSize;
319    }
320
321    @Override
322    public Size getMemStoreSize() {
323      return memStoreSize;
324    }
325
326    @Override
327    public long getReadRequestCount() {
328      return readRequestCount;
329    }
330
331    @Override
332    public long getFilteredReadRequestCount() {
333      return filteredReadRequestCount;
334    }
335
336    @Override
337    public long getWriteRequestCount() {
338      return writeRequestCount;
339    }
340
341    @Override
342    public Size getStoreFileIndexSize() {
343      return indexSize;
344    }
345
346    @Override
347    public Size getStoreFileRootLevelIndexSize() {
348      return rootLevelIndexSize;
349    }
350
351    @Override
352    public Size getStoreFileUncompressedDataIndexSize() {
353      return uncompressedDataIndexSize;
354    }
355
356    @Override
357    public Size getBloomFilterSize() {
358      return bloomFilterSize;
359    }
360
361    @Override
362    public long getCompactingCellCount() {
363      return compactingCellCount;
364    }
365
366    @Override
367    public long getCompactedCellCount() {
368      return compactedCellCount;
369    }
370
371    @Override
372    public long getCompletedSequenceId() {
373      return completedSequenceId;
374    }
375
376    @Override
377    public Map<byte[], Long> getStoreSequenceId() {
378      return Collections.unmodifiableMap(storeSequenceIds);
379    }
380
381    @Override
382    public Size getUncompressedStoreFileSize() {
383      return uncompressedStoreFileSize;
384    }
385
386    @Override
387    public float getDataLocality() {
388      return dataLocality;
389    }
390
391    @Override
392    public long getLastMajorCompactionTimestamp() {
393      return lastMajorCompactionTimestamp;
394    }
395
396    @Override
397    public String toString() {
398      StringBuilder sb = Strings.appendKeyValue(new StringBuilder(), "storeCount",
399          this.getStoreCount());
400      Strings.appendKeyValue(sb, "storeFileCount",
401          this.getStoreFileCount());
402      Strings.appendKeyValue(sb, "uncompressedStoreFileSize",
403          this.getUncompressedStoreFileSize());
404      Strings.appendKeyValue(sb, "lastMajorCompactionTimestamp",
405          this.getLastMajorCompactionTimestamp());
406      Strings.appendKeyValue(sb, "storeFileSize",
407          this.getStoreFileSize());
408      if (this.getUncompressedStoreFileSize().get() != 0) {
409        Strings.appendKeyValue(sb, "compressionRatio",
410            String.format("%.4f",
411                (float) this.getStoreFileSize().get(Size.Unit.MEGABYTE) /
412                (float) this.getUncompressedStoreFileSize().get(Size.Unit.MEGABYTE)));
413      }
414      Strings.appendKeyValue(sb, "memStoreSize",
415          this.getMemStoreSize());
416      Strings.appendKeyValue(sb, "readRequestCount",
417          this.getReadRequestCount());
418      Strings.appendKeyValue(sb, "writeRequestCount",
419          this.getWriteRequestCount());
420      Strings.appendKeyValue(sb, "rootLevelIndexSize",
421          this.getStoreFileRootLevelIndexSize());
422      Strings.appendKeyValue(sb, "uncompressedDataIndexSize",
423          this.getStoreFileUncompressedDataIndexSize());
424      Strings.appendKeyValue(sb, "bloomFilterSize",
425          this.getBloomFilterSize());
426      Strings.appendKeyValue(sb, "compactingCellCount",
427          this.getCompactingCellCount());
428      Strings.appendKeyValue(sb, "compactedCellCount",
429          this.getCompactedCellCount());
430      float compactionProgressPct = Float.NaN;
431      if (this.getCompactingCellCount() > 0) {
432        compactionProgressPct = ((float) this.getCompactedCellCount() /
433            (float) this.getCompactingCellCount());
434      }
435      Strings.appendKeyValue(sb, "compactionProgressPct",
436          compactionProgressPct);
437      Strings.appendKeyValue(sb, "completedSequenceId",
438          this.getCompletedSequenceId());
439      Strings.appendKeyValue(sb, "dataLocality",
440          this.getDataLocality());
441      return sb.toString();
442    }
443  }
444
445}