org.apache.hadoop.hbase.hbtop.mode.RegionModeStrategy Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of hbase-hbtop Show documentation
Show all versions of hbase-hbtop Show documentation
A real-time monitoring tool for HBase like Unix's top command
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hadoop.hbase.hbtop.mode;
import edu.umd.cs.findbugs.annotations.Nullable;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import org.apache.commons.lang3.time.FastDateFormat;
import org.apache.hadoop.hbase.ClusterMetrics;
import org.apache.hadoop.hbase.RegionMetrics;
import org.apache.hadoop.hbase.ServerMetrics;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.RegionInfo;
import org.apache.hadoop.hbase.hbtop.Record;
import org.apache.hadoop.hbase.hbtop.RecordFilter;
import org.apache.hadoop.hbase.hbtop.field.Field;
import org.apache.hadoop.hbase.hbtop.field.FieldInfo;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.yetus.audience.InterfaceAudience;
/**
* Implementation for {@link ModeStrategy} for Region Mode.
*/
@InterfaceAudience.Private
public final class RegionModeStrategy implements ModeStrategy {
private final List fieldInfos = Arrays.asList(
new FieldInfo(Field.REGION_NAME, 0, false), new FieldInfo(Field.NAMESPACE, 0, true),
new FieldInfo(Field.TABLE, 0, true), new FieldInfo(Field.START_CODE, 13, false),
new FieldInfo(Field.REPLICA_ID, 5, false), new FieldInfo(Field.REGION, 32, true),
new FieldInfo(Field.REGION_SERVER, 0, true), new FieldInfo(Field.LONG_REGION_SERVER, 0, false),
new FieldInfo(Field.REQUEST_COUNT_PER_SECOND, 8, true),
new FieldInfo(Field.READ_REQUEST_COUNT_PER_SECOND, 8, true),
new FieldInfo(Field.FILTERED_READ_REQUEST_COUNT_PER_SECOND, 8, true),
new FieldInfo(Field.WRITE_REQUEST_COUNT_PER_SECOND, 8, true),
new FieldInfo(Field.STORE_FILE_SIZE, 10, true),
new FieldInfo(Field.UNCOMPRESSED_STORE_FILE_SIZE, 12, false),
new FieldInfo(Field.NUM_STORE_FILES, 4, true), new FieldInfo(Field.MEM_STORE_SIZE, 8, true),
new FieldInfo(Field.LOCALITY, 8, true), new FieldInfo(Field.START_KEY, 0, false),
new FieldInfo(Field.COMPACTING_CELL_COUNT, 12, false),
new FieldInfo(Field.COMPACTED_CELL_COUNT, 12, false),
new FieldInfo(Field.COMPACTION_PROGRESS, 7, false),
new FieldInfo(Field.LAST_MAJOR_COMPACTION_TIME, 19, false));
private final Map requestCountPerSecondMap = new HashMap<>();
RegionModeStrategy() {
}
@Override
public List getFieldInfos() {
return fieldInfos;
}
@Override
public Field getDefaultSortField() {
return Field.REQUEST_COUNT_PER_SECOND;
}
@Override
public List getRecords(ClusterMetrics clusterMetrics,
List pushDownFilters) {
List ret = new ArrayList<>();
for (ServerMetrics sm : clusterMetrics.getLiveServerMetrics().values()) {
long lastReportTimestamp = sm.getLastReportTimestamp();
for (RegionMetrics rm : sm.getRegionMetrics().values()) {
ret.add(createRecord(sm, rm, lastReportTimestamp));
}
}
return ret;
}
private Record createRecord(ServerMetrics serverMetrics, RegionMetrics regionMetrics,
long lastReportTimestamp) {
Record.Builder builder = Record.builder();
String regionName = regionMetrics.getNameAsString();
builder.put(Field.REGION_NAME, regionName);
String namespaceName = "";
String tableName = "";
String region = "";
String startKey = "";
String startCode = "";
String replicaId = "";
try {
byte[][] elements = RegionInfo.parseRegionName(regionMetrics.getRegionName());
TableName tn = TableName.valueOf(elements[0]);
namespaceName = tn.getNamespaceAsString();
tableName = tn.getQualifierAsString();
startKey = Bytes.toStringBinary(elements[1]);
startCode = Bytes.toString(elements[2]);
replicaId =
elements.length == 4 ? Integer.valueOf(Bytes.toString(elements[3])).toString() : "";
region = RegionInfo.encodeRegionName(regionMetrics.getRegionName());
} catch (IOException ignored) {
// Exception deliberately ignored
}
builder.put(Field.NAMESPACE, namespaceName);
builder.put(Field.TABLE, tableName);
builder.put(Field.START_CODE, startCode);
builder.put(Field.REPLICA_ID, replicaId);
builder.put(Field.REGION, region);
builder.put(Field.START_KEY, startKey);
builder.put(Field.REGION_SERVER, serverMetrics.getServerName().toShortString());
builder.put(Field.LONG_REGION_SERVER, serverMetrics.getServerName().getServerName());
RequestCountPerSecond requestCountPerSecond = requestCountPerSecondMap.get(regionName);
if (requestCountPerSecond == null) {
requestCountPerSecond = new RequestCountPerSecond();
requestCountPerSecondMap.put(regionName, requestCountPerSecond);
}
requestCountPerSecond.refresh(lastReportTimestamp, regionMetrics.getReadRequestCount(),
regionMetrics.getFilteredReadRequestCount(), regionMetrics.getWriteRequestCount());
builder.put(Field.READ_REQUEST_COUNT_PER_SECOND,
requestCountPerSecond.getReadRequestCountPerSecond());
builder.put(Field.FILTERED_READ_REQUEST_COUNT_PER_SECOND,
requestCountPerSecond.getFilteredReadRequestCountPerSecond());
builder.put(Field.WRITE_REQUEST_COUNT_PER_SECOND,
requestCountPerSecond.getWriteRequestCountPerSecond());
builder.put(Field.REQUEST_COUNT_PER_SECOND, requestCountPerSecond.getRequestCountPerSecond());
builder.put(Field.STORE_FILE_SIZE, regionMetrics.getStoreFileSize());
builder.put(Field.UNCOMPRESSED_STORE_FILE_SIZE, regionMetrics.getUncompressedStoreFileSize());
builder.put(Field.NUM_STORE_FILES, regionMetrics.getStoreFileCount());
builder.put(Field.MEM_STORE_SIZE, regionMetrics.getMemStoreSize());
builder.put(Field.LOCALITY, regionMetrics.getDataLocality());
long compactingCellCount = regionMetrics.getCompactingCellCount();
long compactedCellCount = regionMetrics.getCompactedCellCount();
float compactionProgress = 0;
if (compactedCellCount > 0) {
compactionProgress = 100 * ((float) compactedCellCount / compactingCellCount);
}
builder.put(Field.COMPACTING_CELL_COUNT, compactingCellCount);
builder.put(Field.COMPACTED_CELL_COUNT, compactedCellCount);
builder.put(Field.COMPACTION_PROGRESS, compactionProgress);
FastDateFormat df = FastDateFormat.getInstance("yyyy-MM-dd HH:mm:ss");
long lastMajorCompactionTimestamp = regionMetrics.getLastMajorCompactionTimestamp();
builder.put(Field.LAST_MAJOR_COMPACTION_TIME,
lastMajorCompactionTimestamp == 0 ? "" : df.format(lastMajorCompactionTimestamp));
return builder.build();
}
/**
* Form new record list with records formed by only fields provided through fieldInfo and add a
* count field for each record with value 1 We are doing two operation of selecting and adding new
* field because of saving some CPU cycles on rebuilding the record again
* @param fieldInfos List of FieldInfos required in the record
* @param records List of records which needs to be processed
* @param countField Field which needs to be added with value 1 for each record
* @return records after selecting required fields and adding count field
*/
List selectModeFieldsAndAddCountField(List fieldInfos, List records,
Field countField) {
return records.stream().map(
record -> Record.ofEntries(fieldInfos.stream().filter(fi -> record.containsKey(fi.getField()))
.map(fi -> Record.entry(fi.getField(), record.get(fi.getField())))))
.map(record -> Record.builder().putAll(record).put(countField, 1).build())
.collect(Collectors.toList());
}
@Nullable
@Override
public DrillDownInfo drillDown(Record selectedRecord) {
// do nothing
return null;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy