blob: 969c39955fc7e81db2012f8bb53155f34e8b9cd8 [file] [log] [blame]
/*
* 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.kylin.storage.hbase.cube;
import java.io.IOException;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.Result;
import org.apache.hadoop.hbase.client.ResultScanner;
import org.apache.kylin.common.KylinConfig;
import org.apache.kylin.common.util.ImmutableBitSet;
import org.apache.kylin.gridtable.GTInfo;
import org.apache.kylin.gridtable.GTInfo.Builder;
import org.apache.kylin.gridtable.GTRecord;
import org.apache.kylin.gridtable.GTSampleCodeSystem;
import org.apache.kylin.gridtable.GTScanRequest;
import org.apache.kylin.gridtable.IGTScanner;
import org.apache.kylin.gridtable.IGTWriter;
import org.apache.kylin.gridtable.benchmark.SortedGTRecordGenerator;
import org.apache.kylin.metadata.datatype.DataType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Benchmark of processing 10 million GTRecords. 5 dimensions of type int4, and 2 measures of type long8.
*/
public class HBaseScannerBenchmark {
static final Logger logger = LoggerFactory.getLogger(HBaseScannerBenchmark.class);
final GTInfo info;
final SortedGTRecordGenerator gen;
final ImmutableBitSet dimensions = ImmutableBitSet.valueOf(0, 1, 2, 3, 4);
final ImmutableBitSet metrics = ImmutableBitSet.valueOf(5, 6);
final String[] aggrFuncs = new String[] { "SUM", "SUM" };
final long N = 1000000; // 1M, note the limit memory of HBase in sandbox
final TableName htableName = TableName.valueOf("HBaseScannerBenchmark");
final SimpleHBaseStore simpleStore;
public HBaseScannerBenchmark() throws IOException {
Builder builder = GTInfo.builder();
builder.setCodeSystem(new GTSampleCodeSystem());
DataType tint = DataType.getType("int4");
DataType tlong = DataType.getType("long8");
builder.setColumns(tint, tint, tint, tint, tint, tlong, tlong);
builder.setPrimaryKey(ImmutableBitSet.valueOf(0, 1, 2, 3, 4));
info = builder.build();
gen = new SortedGTRecordGenerator(info);
gen.addDimension(10, 4, null);
gen.addDimension(10, 4, null);
gen.addDimension(10, 4, null);
gen.addDimension(10, 4, null);
gen.addDimension(100, 4, null);
gen.addMeasure(8);
gen.addMeasure(8);
simpleStore = new SimpleHBaseStore(info, htableName);
}
private void buildTable() throws IOException {
IGTWriter builder = simpleStore.rebuild();
logger.info("Writing " + N + " records");
long t = System.currentTimeMillis();
long count = 0;
for (GTRecord rec : gen.generate(N)) {
builder.write(rec);
count++;
if (count % 100000 == 0)
logger.info(count + " rows written");
}
builder.close();
t = System.currentTimeMillis() - t;
logger.info(count + " rows written, " + speed(t) + "K row/sec");
}
public void testScan() throws IOException {
int rounds = 5;
for (int i = 0; i < rounds; i++) {
testScanRaw("Scan raw " + (i + 1) + " of " + rounds);
testScanRecords("Scan records " + (i + 1) + " of " + rounds);
}
}
@SuppressWarnings("unused")
private void testScanRaw(String msg) throws IOException {
long t = System.currentTimeMillis();
IGTScanner scan = simpleStore.scan(new GTScanRequest(info, null, null, null));
ResultScanner innerScanner = ((SimpleHBaseStore.Reader) scan).getHBaseScanner();
int count = 0;
for (Result r : innerScanner) {
count++;
}
scan.close();
t = System.currentTimeMillis() - t;
logger.info(msg + ", " + count + " rows, " + speed(t) + "K row/sec");
}
@SuppressWarnings("unused")
private void testScanRecords(String msg) throws IOException {
long t = System.currentTimeMillis();
IGTScanner scan = simpleStore.scan(new GTScanRequest(info, null, null, null));
int count = 0;
for (GTRecord rec : scan) {
count++;
}
scan.close();
if (scan.getScannedRowCount() != count)
throw new IllegalStateException();
t = System.currentTimeMillis() - t;
logger.info(msg + ", " + count + " records, " + speed(t) + "K rec/sec");
}
private int speed(long t) {
double sec = (double) t / 1000;
return (int) (N / sec / 1000);
}
public void cleanup() throws IOException {
simpleStore.cleanup();
}
public static void main(String[] args) throws IOException {
boolean createTable = true;
boolean deleteTable = true;
if (args != null && args.length > 1) {
try {
createTable = Boolean.parseBoolean(args[0]);
} catch (Exception e) {
createTable = true;
}
try {
deleteTable = Boolean.parseBoolean(args[1]);
} catch (Exception e) {
deleteTable = true;
}
}
KylinConfig.setSandboxEnvIfPossible();
HBaseScannerBenchmark benchmark = new HBaseScannerBenchmark();
if (createTable) {
benchmark.buildTable();
}
benchmark.testScan();
if (deleteTable) {
benchmark.cleanup();
}
}
}