[강운덕] [LUCYSUS-1744] index의 rowkey 의 agentid를 fixed하게 저장하도록 수정. root span만 스캔하던것을 전체 스캔하도록 다시 변경. root span만 스캔하니 조회시 한계가 있음. hbase client의 thread limit 조정.

git-svn-id: http://svn.bds.nhncorp.com/pe/hippo-commons/trunk@832 84d0f5b1-2673-498c-a247-62c4ff18d310
This commit is contained in:
Woonduk Kang
2012-10-29 02:50:44 +00:00
parent 6001aa54cc
commit 16ea3f2a5a
11 changed files with 627 additions and 407 deletions
@@ -0,0 +1,78 @@
package com.profiler.common.hbase;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HTableDescriptor;
import org.apache.hadoop.hbase.MasterNotRunningException;
import org.apache.hadoop.hbase.ZooKeeperConnectionException;
import org.apache.hadoop.hbase.client.HBaseAdmin;
import org.springframework.data.hadoop.hbase.HbaseSystemException;
import java.io.IOException;
/**
*
*/
public class HBaseAdminTemplate {
private final HBaseAdmin hBaseAdmin;
public HBaseAdminTemplate(Configuration configuration) {
try {
this.hBaseAdmin = new HBaseAdmin(configuration);
} catch (MasterNotRunningException e) {
throw new HbaseSystemException(e);
} catch (ZooKeeperConnectionException e) {
throw new HbaseSystemException(e);
}
}
public boolean createTableIfNotExist(HTableDescriptor htd) {
try {
if (!hBaseAdmin.tableExists(htd.getName())) {
this.hBaseAdmin.createTable(htd);
return true;
}
return false;
} catch (IOException e) {
throw new HbaseSystemException(e);
}
}
public boolean tableExists(String tableName) {
try {
return hBaseAdmin.tableExists(tableName);
} catch (IOException e) {
throw new HbaseSystemException(e);
}
}
public boolean dropTableIfExist(String tableName) {
try {
if (hBaseAdmin.tableExists(tableName)) {
this.hBaseAdmin.disableTable(tableName);
this.hBaseAdmin.deleteTable(tableName);
return true;
}
return false;
} catch (IOException e) {
throw new HbaseSystemException(e);
}
}
public void dropTable(String tableName) {
try {
this.hBaseAdmin.disableTable(tableName);
this.hBaseAdmin.deleteTable(tableName);
} catch (IOException e) {
throw new HbaseSystemException(e);
}
}
public void close() {
try {
this.hBaseAdmin.close();
} catch (IOException e) {
throw new HbaseSystemException(e);
}
}
}
@@ -11,12 +11,8 @@ import java.util.Properties;
import org.apache.commons.lang.math.NumberUtils;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.HTableDescriptor;
import org.apache.hadoop.hbase.MasterNotRunningException;
import org.apache.hadoop.hbase.ZooKeeperConnectionException;
import org.apache.hadoop.hbase.client.Delete;
import org.apache.hadoop.hbase.client.Get;
import org.apache.hadoop.hbase.client.HBaseAdmin;
import org.apache.hadoop.hbase.client.HTable;
import org.apache.hadoop.hbase.client.HTableInterface;
import org.apache.hadoop.hbase.client.HTablePool;
@@ -31,315 +27,281 @@ import com.profiler.common.hbase.HBaseQuery.HbaseColumn;
public class HBaseClient {
private static final Logger LOG = LoggerFactory.getLogger(HBaseClient.class);
private static final Logger LOG = LoggerFactory.getLogger(HBaseClient.class);
private HTablePool tablePool;
private HBaseAdmin admin;
private Configuration configuration;
private HTablePool tablePool;
private final Map<String, HTableInterface> htableList = new HashMap<String, HTableInterface>();
private final Map<String, HTableInterface> htableList = new HashMap<String, HTableInterface>();
public HBaseClient(Properties properties) {
String host = properties.getProperty("hbase.client.host", "localhost");
String port = properties.getProperty("hbase.client.port", "2181");
Integer poolSize = NumberUtils.toInt(properties.getProperty("hbase.client.poolSize"), 16);
init(host, port, poolSize, null);
}
public HBaseClient(Properties properties) {
String host = properties.getProperty("hbase.client.host", "localhost");
String port = properties.getProperty("hbase.client.port", "2181");
this.configuration = createConfiguration(host, port);
Integer poolSize = NumberUtils.toInt(properties.getProperty("hbase.client.poolSize"), 16);
init(configuration, poolSize);
}
public HBaseClient(String zk, String port, int poolSize) {
init(zk, port, poolSize, null);
}
public HBaseClient(String zk, String port, int poolSize) {
Configuration cfg = createConfiguration(zk, port);
init(cfg, poolSize);
}
public HBaseClient(String zk, String port, int poolSize, Configuration configuration) {
init(zk, port, poolSize, configuration);
}
private Configuration createConfiguration(String zk, String port) {
Configuration cfg = HBaseConfiguration.create();
cfg.set("hbase.zookeeper.quorum", zk);
cfg.set("hbase.zookeeper.property.clientPort", port);
return cfg;
}
public HBaseClient(Configuration configuration, int poolSize) {
init(null, null, poolSize, configuration);
}
public HBaseClient(Configuration configuration, int poolSize) {
init(configuration, poolSize);
}
private void init(String zk, String port, int poolSize, Configuration configuration) {
if (configuration == null) {
Configuration cfg = HBaseConfiguration.create();
if (zk != null) {
cfg.set("hbase.zookeeper.quorum", zk);
}
if (port != null) {
cfg.set("hbase.zookeeper.property.clientPort", port);
}
configuration = cfg;
}
private void init(Configuration configuration, int poolSize) {
tablePool = new HTablePool(configuration, poolSize);
}
tablePool = new HTablePool(configuration, poolSize);
try {
admin = new HBaseAdmin(configuration);
} catch (MasterNotRunningException e) {
e.printStackTrace();
} catch (ZooKeeperConnectionException e) {
e.printStackTrace();
}
}
public Configuration getConfiguration() {
return configuration;
}
public void close() {
// htableList는 안지워워도 되지.
try {
tablePool.close();
} catch (IOException e) {
// TODO
e.printStackTrace(); // To change body of catch statement use File |
// Settings | File Templates.
}
}
public void close() {
// htableList는 안지워워도 되지.
try {
tablePool.close();
} catch (IOException e) {
// TODO
e.printStackTrace(); // To change body of catch statement use File |
// Settings | File Templates.
}
}
HTablePool getTablePool() {
return tablePool;
}
HTablePool getTablePool() {
return tablePool;
}
public Iterator<Map<String, byte[]>> getHBaseData(HBaseQuery query) {
ResultSetIterator r = new ResultSetIterator(query);
return r.getIterator();
}
public Iterator<Map<String, byte[]>> getHBaseData(HBaseQuery query) {
ResultSetIterator r = new ResultSetIterator(query);
return r.getIterator();
}
private HTableInterface getHTable(String tableName) {
HTableInterface htable = null;
synchronized (htableList) {
htable = htableList.get(tableName);
if (htable == null) {
htable = tablePool.getTable(tableName);
htableList.put(tableName, htable);
}
}
return htable;
}
private HTableInterface getHTable(String tableName) {
HTableInterface htable = null;
synchronized (htableList) {
htable = htableList.get(tableName);
if (htable == null) {
htable = tablePool.getTable(tableName);
htableList.put(tableName, htable);
}
}
return htable;
}
public boolean isTableExists(final String tableName) {
try {
return admin.tableExists(tableName);
} catch (IOException e) {
e.printStackTrace();
return false;
}
}
public void dropTable(final String tableName) {
try {
admin.disableTable(tableName);
admin.deleteTable(tableName);
} catch (IOException e) {
e.printStackTrace();
}
}
public void insert(String tableName, Put put) {
HTable htable = (HTable) tablePool.getTable(tableName);
try {
htable.put(put);
} catch (IOException e) {
e.printStackTrace();
} finally {
closeHTable(htable);
}
}
public void createTable(HTableDescriptor td) {
try {
admin.createTable(td);
} catch (IOException e) {
e.printStackTrace();
}
}
public void insert(String tableName, List<Put> put) {
HTable htable = (HTable) tablePool.getTable(tableName);
try {
htable.put(put);
} catch (IOException e) {
e.printStackTrace();
} finally {
closeHTable(htable);
}
}
public void insert(String tableName, Put put) {
HTable htable = (HTable) tablePool.getTable(tableName);
try {
htable.put(put);
} catch (IOException e) {
e.printStackTrace();
} finally {
closeHTable(htable);
}
}
public void delete(String tableName, Delete delete) {
HTable htable = (HTable) tablePool.getTable(tableName);
try {
htable.delete(delete);
} catch (IOException e) {
e.printStackTrace();
} finally {
closeHTable(htable);
}
}
public void insert(String tableName, List<Put> put) {
HTable htable = (HTable) tablePool.getTable(tableName);
try {
htable.put(put);
} catch (IOException e) {
e.printStackTrace();
} finally {
closeHTable(htable);
}
}
public void execute(String tableName, HTableCallBack callBack) {
HTable htable = (HTable) tablePool.getTable(tableName);
try {
callBack.doExecute(htable);
} catch (IOException e) {
e.printStackTrace();
// TODO ex 처리
} finally {
closeHTable(htable);
}
}
public void delete(String tableName, Delete delete) {
HTable htable = (HTable) tablePool.getTable(tableName);
try {
htable.delete(delete);
} catch (IOException e) {
e.printStackTrace();
} finally {
closeHTable(htable);
}
}
public Result[] get(String tablename, List<Get> get) {
HTable htable = (HTable) tablePool.getTable(tablename);
public void execute(String tableName, HTableCallBack callBack) {
HTable htable = (HTable) tablePool.getTable(tableName);
try {
callBack.doExecute(htable);
} catch (IOException e) {
e.printStackTrace();
// TODO ex 처리
} finally {
closeHTable(htable);
}
}
try {
return htable.get(get);
} catch (IOException e) {
e.printStackTrace();
// TODO ex 처리
} finally {
closeHTable(htable);
}
return new Result[0];
}
public Result[] get(String tablename, List<Get> get) {
HTable htable = (HTable) tablePool.getTable(tablename);
private void closeHTable(HTable htable) {
if (htable != null) {
try {
htable.close();
} catch (IOException e) {
LOG.warn(e.getMessage(), e);
}
}
}
try {
return htable.get(get);
} catch (IOException e) {
e.printStackTrace();
// TODO ex 처리
} finally {
closeHTable(htable);
}
return new Result[0];
}
private class ResultSetIterator {
ResultScanner resultScanner = null;
Iterator<Result> resultIterator;
List<HbaseColumn> columns;
Iterator<Map<String, byte[]>> rSetIterator;
private void closeHTable(HTable htable) {
if (htable != null) {
try {
htable.close();
} catch (IOException e) {
LOG.warn(e.getMessage(), e);
}
}
}
public ResultSetIterator(HBaseQuery query) {
try {
byte[] startRow = query.getStartRow();
byte[] stopRow = query.getStopRow();
String tableName = query.getTableName();
private class ResultSetIterator {
ResultScanner resultScanner = null;
Iterator<Result> resultIterator;
List<HbaseColumn> columns;
Iterator<Map<String, byte[]>> rSetIterator;
columns = query.getColumns();
HTableInterface htable = getHTable(tableName);
public ResultSetIterator(HBaseQuery query) {
try {
byte[] startRow = query.getStartRow();
byte[] stopRow = query.getStopRow();
String tableName = query.getTableName();
if (query.isSingleRow()) {
Get get = new Get(startRow);
columns = query.getColumns();
HTableInterface htable = getHTable(tableName);
if (columns != null) {
for (HbaseColumn column : columns) {
get.addColumn(column.getFamily().getBytes(), column.getColumnName().getBytes());
}
}
if (query.isSingleRow()) {
Get get = new Get(startRow);
Result result = htable.get(get);
List<Result> resultList = new ArrayList<Result>(1);
resultList.add(result);
resultIterator = resultList.iterator();
} else {
Scan scan = new Scan();
if (columns != null) {
for (HbaseColumn column : columns) {
get.addColumn(column.getFamily().getBytes(), column.getColumnName().getBytes());
}
}
if (startRow != null) {
scan.setStartRow(startRow);
}
Result result = htable.get(get);
List<Result> resultList = new ArrayList<Result>(1);
resultList.add(result);
resultIterator = resultList.iterator();
} else {
Scan scan = new Scan();
if (stopRow != null) {
scan.setStopRow(stopRow);
}
if (startRow != null) {
scan.setStartRow(startRow);
}
if (columns != null) {
for (HbaseColumn column : columns) {
scan.addColumn(column.getFamily().getBytes(), column.getColumnName().getBytes());
}
}
if (stopRow != null) {
scan.setStopRow(stopRow);
}
LOG.debug("Executing scanner: " + query);
if (columns != null) {
for (HbaseColumn column : columns) {
scan.addColumn(column.getFamily().getBytes(), column.getColumnName().getBytes());
}
}
long start = System.currentTimeMillis();
LOG.debug("Executing scanner: " + query);
resultScanner = htable.getScanner(scan);
long start = System.currentTimeMillis();
LOG.trace("Time taken for scanner: " + (System.currentTimeMillis() - start));
resultScanner = htable.getScanner(scan);
resultIterator = resultScanner.iterator();
}
} catch (Exception e) {
throw new RuntimeException("UNable to execute SCANNER : " + query, e);
}
LOG.trace("Time taken for scanner: " + (System.currentTimeMillis() - start));
if (!resultIterator.hasNext()) {
rSetIterator = new ArrayList<Map<String, byte[]>>().iterator();
return;
}
resultIterator = resultScanner.iterator();
}
} catch (Exception e) {
throw new RuntimeException("UNable to execute SCANNER : " + query, e);
}
rSetIterator = new Iterator<Map<String, byte[]>>() {
public boolean hasNext() {
return hasnext();
}
if (!resultIterator.hasNext()) {
rSetIterator = new ArrayList<Map<String, byte[]>>().iterator();
return;
}
public Map<String, byte[]> next() {
return getARow();
}
rSetIterator = new Iterator<Map<String, byte[]>>() {
public boolean hasNext() {
return hasnext();
}
public void remove() {
}
};
}
public Map<String, byte[]> next() {
return getARow();
}
private Iterator<Map<String, byte[]>> getIterator() {
return rSetIterator;
}
public void remove() {
}
};
}
private Map<String, byte[]> getARow() {
if (resultIterator == null)
return null;
Result res = resultIterator.next();
private Iterator<Map<String, byte[]>> getIterator() {
return rSetIterator;
}
Map<String, byte[]> result = new HashMap<String, byte[]>();
if (!res.isEmpty()) {
byte[] value;
if (columns != null) {
for (HbaseColumn column : columns) {
String colName = column.getColumnName();
value = res.getValue(column.getFamily().getBytes(), column.getColumnName().getBytes());
private Map<String, byte[]> getARow() {
if (resultIterator == null)
return null;
Result res = resultIterator.next();
if (value == null) {
continue;
}
Map<String, byte[]> result = new HashMap<String, byte[]>();
if (!res.isEmpty()) {
byte[] value;
if (columns != null) {
for (HbaseColumn column : columns) {
String colName = column.getColumnName();
value = res.getValue(column.getFamily().getBytes(), column.getColumnName().getBytes());
result.put(colName, value);
}
}
value = res.getRow();
}
if (value == null) {
continue;
}
return result;
}
result.put(colName, value);
}
}
value = res.getRow();
}
private boolean hasnext() {
if (resultIterator == null)
return false;
try {
if (resultIterator.hasNext()) {
return true;
} else {
close();
return false;
}
} catch (Exception e) {
close();
e.printStackTrace();
return false;
}
}
return result;
}
private boolean hasnext() {
if (resultIterator == null)
return false;
try {
if (resultIterator.hasNext()) {
return true;
} else {
close();
return false;
}
} catch (Exception e) {
close();
e.printStackTrace();
return false;
}
}
private void close() {
try {
if (resultScanner != null) {
resultScanner.close();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
}
}
}
private void close() {
try {
if (resultScanner != null) {
resultScanner.close();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
}
}
}
}
@@ -78,6 +78,10 @@ public class Buffer {
if (size == 0) {
return EMPTY;
}
return readBytes(size);
}
private byte[] readBytes(int size) {
byte[] b = new byte[size];
System.arraycopy(buffer, offset, b, 0, size);
this.offset = offset + size;
@@ -89,6 +93,10 @@ public class Buffer {
if (size == 0) {
return "";
}
return readString(size);
}
private String readString(int size) {
String s = new String(buffer, offset, size, UTF8);
this.offset = offset + size;
return s;
@@ -8,97 +8,94 @@ import org.apache.thrift.protocol.*;
import org.apache.thrift.transport.TMemoryInputTransport;
public class HeaderTBaseDeserializer {
private final TProtocol protocol_;
private final TMemoryInputTransport trans_;
/**
* Create a new TDeserializer that uses the TBinaryProtocol by default.
*/
public HeaderTBaseDeserializer() {
this(new TBinaryProtocol.Factory());
}
private final TProtocol protocol_;
private final TMemoryInputTransport trans_;
/**
* Create a new TDeserializer. It will use the TProtocol specified by the
* factory that is passed in.
*
* @param protocolFactory
* Factory to create a protocol
*/
public HeaderTBaseDeserializer(TProtocolFactory protocolFactory) {
trans_ = new TMemoryInputTransport();
protocol_ = protocolFactory.getProtocol(trans_);
}
/**
* Create a new TDeserializer that uses the TBinaryProtocol by default.
*/
public HeaderTBaseDeserializer() {
this(new TBinaryProtocol.Factory());
}
/**
* Deserialize the Thrift object from a byte array.
*
* @param locator
* The object to read into
* @param bytes
* The array to read from
*/
public TBase<?, ?> deserialize(TBaseLocator locator, byte[] bytes) throws TException {
try {
trans_.reset(bytes);
Header header = readHeader();
validate(header);
TBase<?, ?> base = locator.tBaseLookup(header.getType());
base.read(protocol_);
return base;
} finally {
trans_.clear();
protocol_.reset();
}
}
/**
* Create a new TDeserializer. It will use the TProtocol specified by the
* factory that is passed in.
*
* @param protocolFactory Factory to create a protocol
*/
public HeaderTBaseDeserializer(TProtocolFactory protocolFactory) {
trans_ = new TMemoryInputTransport();
protocol_ = protocolFactory.getProtocol(trans_);
}
private void validate(Header header) {
boolean accepted = HeaderUtil.validateSignature(header.getSignature());
if (!accepted) {
throw new IllegalArgumentException("Invalid Signature:" + header);
}
}
/**
* Deserialize the Thrift object from a byte array.
*
* @param locator The object to read into
* @param bytes The array to read from
*/
public TBase<?, ?> deserialize(TBaseLocator locator, byte[] bytes) throws TException {
try {
trans_.reset(bytes);
Header header = readHeader();
validate(header);
TBase<?, ?> base = locator.tBaseLookup(header.getType());
base.read(protocol_);
return base;
} finally {
trans_.clear();
protocol_.reset();
}
}
private Header readHeader() throws TException {
byte signature = protocol_.readByte();
byte version = protocol_.readByte();
short type = protocol_.readI16();
return new Header(signature, version, type);
}
private void validate(Header header) {
boolean accepted = HeaderUtils.validateSignature(header.getSignature());
if (!accepted) {
throw new IllegalArgumentException("Invalid Signature:" + header);
}
}
/**
* Deserialize the Thrift object from a Java string, using a specified
* character set for decoding.
*
* @param base
* The object to read into
* @param data
* The string to read from
* @param charset
* Valid JVM charset
*/
// public void deserialize(TBase base, String data, String charset) throws
// TException {
// try {
// deserialize(base, data.getBytes(charset));
// } catch (UnsupportedEncodingException uex) {
// throw new TException("JVM DOES NOT SUPPORT ENCODING: " + charset);
// } finally {
// protocol_.reset();
// }
// }
private Header readHeader() throws TException {
byte signature = protocol_.readByte();
byte version = protocol_.readByte();
short type = protocol_.readI16();
return new Header(signature, version, type);
}
/**
* Deserialize the Thrift object from a Java string, using the default JVM
* charset encoding.
*
* @param base
* The object to read into
* @param data
* The string to read from
*/
// public void fromString(TBase base, String data) throws TException {
// deserialize(base, data.getBytes());
// }
/**
* Deserialize the Thrift object from a Java string, using a specified
* character set for decoding.
*
* @param base
* The object to read into
* @param data
* The string to read from
* @param charset
* Valid JVM charset
*/
// public void deserialize(TBase base, String data, String charset) throws
// TException {
// try {
// deserialize(base, data.getBytes(charset));
// } catch (UnsupportedEncodingException uex) {
// throw new TException("JVM DOES NOT SUPPORT ENCODING: " + charset);
// } finally {
// protocol_.reset();
// }
// }
/**
* Deserialize the Thrift object from a Java string, using the default JVM
* charset encoding.
*
* @param base
* The object to read into
* @param data
* The string to read from
*/
// public void fromString(TBase base, String data) throws TException {
// deserialize(base, data.getBytes());
// }
}
@@ -3,8 +3,8 @@ package com.profiler.common.util;
import com.profiler.common.dto.Header;
public class HeaderUtil {
public static boolean validateSignature(byte signature){
public class HeaderUtils {
public static boolean validateSignature(byte signature) {
return Header.SIGNATURE == signature;
}
}
@@ -0,0 +1,24 @@
package com.profiler.common.util;
import org.apache.hadoop.hbase.util.Bytes;
/**
*
*/
public class RowKeyUtils {
public static int LONG_BYTE_LENGTH = 8;
public static byte[] concatFixedByteAndLong(byte[] fixedBytes, int maxFixedLength, long l) {
if (fixedBytes == null) {
throw new IllegalArgumentException("fixedBytes must not null");
}
if (fixedBytes.length > maxFixedLength) {
throw new IllegalArgumentException("fixedBytes.length too big. length:" + fixedBytes.length);
}
byte[] rowKey = new byte[maxFixedLength + LONG_BYTE_LENGTH];
Bytes.putBytes(rowKey, 0, fixedBytes, 0, fixedBytes.length);
BytesUtils.writeLong(l, rowKey, maxFixedLength);
return rowKey;
}
}
@@ -1,11 +1,27 @@
package com.profiler.common.util;
import com.profiler.common.dto.thrift.Span;
import org.apache.hadoop.hbase.util.Bytes;
public class SpanUtils {
public static final int AGENT_NAME_LIMIT = 24;
public static byte[] getTraceIndexRowKey(Span span) {
return BytesUtils.add(span.getAgentId(), span.getTimestamp());
return getTraceIndexRowKey(span.getAgentId(), span.getTimestamp());
}
public static byte[] getTraceIndexRowKey(byte[] agentId, long time) {
return RowKeyUtils.concatFixedByteAndLong(agentId, AGENT_NAME_LIMIT, time);
}
public static byte[] getTraceIndexRowKey(String agentId, long time) {
if (agentId == null) {
throw new IllegalArgumentException("agentId must not null");
}
byte[] bAgentId = BytesUtils.getBytes(agentId);
return getTraceIndexRowKey(bAgentId, time);
}
public static byte[] getTraceId(Span span) {