From 067abb052c8197b7a602ccf2816435fc3b183dda Mon Sep 17 00:00:00 2001 From: Woonduk Kang Date: Thu, 25 Oct 2012 09:46:00 +0000 Subject: [PATCH] =?UTF-8?q?[=EA=B0=95=EC=9A=B4=EB=8D=95]=20[LUCYSUS-1744]?= =?UTF-8?q?=20root=20Span=EB=A7=8C=20=EC=A1=B0=ED=9A=8C=ED=95=98=EC=97=AC?= =?UTF-8?q?=20trace=20=EB=8D=B0=EC=9D=B4=ED=84=B0=EB=A5=BC=20=EA=B5=AC?= =?UTF-8?q?=EC=84=B1=ED=95=98=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://svn.bds.nhncorp.com/pe/hippo-web/trunk@822 84d0f5b1-2673-498c-a247-62c4ff18d310 --- .../web/controller/FlowChartController.java | 10 ++- .../hippo/web/dao/HbaseRootTraceIndexDao.java | 86 +++++++++++++++++++ .../nhn/hippo/web/dao/HbaseTraceIndexDao.java | 5 +- .../nhn/hippo/web/dao/RootTraceIndexDao.java | 15 ++++ .../hippo/web/mapper/AnnotationMapper.java | 11 ++- .../web/mapper/BinaryAnnotationDecoder.java | 11 --- .../hippo/web/mapper/JavaObjectDecoder.java | 46 ---------- .../com/nhn/hippo/web/mapper/SpanMapper.java | 32 ------- .../web/service/FlowChartServiceImpl.java | 11 ++- src/main/resources/hbase.properties | 4 +- .../nhn/hippo/web/performance/TestSuite.java | 42 +++++++++ 11 files changed, 170 insertions(+), 103 deletions(-) create mode 100644 src/main/java/com/nhn/hippo/web/dao/HbaseRootTraceIndexDao.java create mode 100644 src/main/java/com/nhn/hippo/web/dao/RootTraceIndexDao.java delete mode 100644 src/main/java/com/nhn/hippo/web/mapper/BinaryAnnotationDecoder.java delete mode 100644 src/main/java/com/nhn/hippo/web/mapper/JavaObjectDecoder.java create mode 100644 src/test/java/com/nhn/hippo/web/performance/TestSuite.java diff --git a/src/main/java/com/nhn/hippo/web/controller/FlowChartController.java b/src/main/java/com/nhn/hippo/web/controller/FlowChartController.java index 0a6a3ff1f..265bcfc59 100644 --- a/src/main/java/com/nhn/hippo/web/controller/FlowChartController.java +++ b/src/main/java/com/nhn/hippo/web/controller/FlowChartController.java @@ -7,6 +7,7 @@ import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; +import org.springframework.util.StopWatch; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; @@ -47,9 +48,16 @@ public class FlowChartController { @RequestMapping(value = "/flowserver", method = RequestMethod.GET) public String flowserver(Model model, @RequestParam("host") String[] hosts, @RequestParam("from") long from, @RequestParam("to") long to) { String[] agentIds = flow.selectAgentIds(hosts); + // TODO 제거 하거나, interceptor로 할것. + StopWatch watch = new StopWatch(); + watch.start("scanTraceindex"); Set traceIds = flow.selectTraceIdsFromTraceIndex(agentIds, from, to); - + watch.stop(); + logger.info("time:{} {}", watch.getLastTaskTimeMillis(), traceIds.size()); + watch.start("selectServerCallTree"); ServerCallTree callTree = flow.selectServerCallTree(traceIds); + watch.stop(); + logger.info("time:{}", watch.getLastTaskTimeMillis()); model.addAttribute("nodes", callTree.getNodes()); model.addAttribute("links", callTree.getLinks()); diff --git a/src/main/java/com/nhn/hippo/web/dao/HbaseRootTraceIndexDao.java b/src/main/java/com/nhn/hippo/web/dao/HbaseRootTraceIndexDao.java new file mode 100644 index 000000000..d2cbd9ea9 --- /dev/null +++ b/src/main/java/com/nhn/hippo/web/dao/HbaseRootTraceIndexDao.java @@ -0,0 +1,86 @@ +package com.nhn.hippo.web.dao; + +import com.profiler.common.hbase.HBaseTables; +import com.profiler.common.hbase.HbaseOperations2; +import com.profiler.common.util.BytesUtils; +import org.apache.hadoop.hbase.client.Scan; +import org.apache.hadoop.hbase.util.Bytes; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.data.hadoop.hbase.RowMapper; +import org.springframework.stereotype.Repository; + +import java.util.ArrayList; +import java.util.List; + +/** + * + */ +@Repository +public class HbaseRootTraceIndexDao implements RootTraceIndexDao { + + private Logger logger = LoggerFactory.getLogger(this.getClass()); + + private final byte[] COLFAM_TRACE = Bytes.toBytes("Trace"); + private final byte[] COLNAME_ID = Bytes.toBytes("ID"); + + @Autowired + private HbaseOperations2 hbaseOperations2; + + @Autowired + @Qualifier("traceIndexMapper") + private RowMapper traceIndexMapper; + + + private int scanCacheSize = 40; + + public void setScanCacheSize(int scanCacheSize) { + this.scanCacheSize = scanCacheSize; + } + + + @Override + public List scanTraceIndex(String agent, long start, long end) { + Scan scan = createScan(agent, start, end); + return hbaseOperations2.find(HBaseTables.ROOT_TRACE_INDEX, scan, traceIndexMapper); + } + + @Override + public List> multiScanTraceIndex(String[] agents, long start, long end) { + final List multiScan = new ArrayList(agents.length); + for (String agent : agents) { + Scan scan = createScan(agent, start, end); + multiScan.add(scan); + } + return hbaseOperations2.find(HBaseTables.ROOT_TRACE_INDEX, multiScan, traceIndexMapper); + } + + private Scan createScan(String agent, long start, long end) { + Scan scan = new Scan(); + // cache size를 지정해야 되는거 같음.?? + scan.setCaching(this.scanCacheSize); + + byte[] bAgent = Bytes.toBytes(agent); + byte[] bStart = BytesUtils.add(bAgent, start); + scan.setStartRow(bStart); +// TODO 추가 filter를 구현하여 scan시 중복된 값을 제가 할수 있음. 단 server에도 Filter 클래스가 배포되어야 한다. +// scan.setFilter(new ValueFilter()); + + byte[] bEnd = BytesUtils.add(bAgent, end); + scan.setStopRow(bEnd); + + scan.addColumn(COLFAM_TRACE, COLNAME_ID); + scan.setId("rootTraceIndexScan"); + + // json으로 변화해서 로그를 찍어서. 최초 변환 속도가 느림. + logger.debug("create scan:{}", scan); + return scan; + } + + @Override + public List parallelScanTraceIndex(String[] agents, long start, long end) { + return null; //To change body of implemented methods use File | Settings | File Templates. + } +} diff --git a/src/main/java/com/nhn/hippo/web/dao/HbaseTraceIndexDao.java b/src/main/java/com/nhn/hippo/web/dao/HbaseTraceIndexDao.java index b9f92cba5..a5ca0fbae 100644 --- a/src/main/java/com/nhn/hippo/web/dao/HbaseTraceIndexDao.java +++ b/src/main/java/com/nhn/hippo/web/dao/HbaseTraceIndexDao.java @@ -34,7 +34,7 @@ public class HbaseTraceIndexDao implements TraceIndexDao { private RowMapper traceIndexMapper; - private int scanCacheSize = 20; + private int scanCacheSize = 40; public void setScanCacheSize(int scanCacheSize) { this.scanCacheSize = scanCacheSize; @@ -59,12 +59,12 @@ public class HbaseTraceIndexDao implements TraceIndexDao { private Scan createScan(String agent, long start, long end) { - byte[] bAgent = Bytes.toBytes(agent); Scan scan = new Scan(); // cache size를 지정해야 되는거 같음.?? scan.setCaching(this.scanCacheSize); + byte[] bAgent = Bytes.toBytes(agent); byte[] bStart = BytesUtils.add(bAgent, start); scan.setStartRow(bStart); // TODO 추가 filter를 구현하여 scan시 중복된 값을 제가 할수 있음. 단 server에도 Filter 클래스가 배포되어야 한다. @@ -72,7 +72,6 @@ public class HbaseTraceIndexDao implements TraceIndexDao { byte[] bEnd = BytesUtils.add(bAgent, end); scan.setStopRow(bEnd); - scan.addColumn(COLFAM_TRACE, COLNAME_ID); scan.setId("traceIndexScan"); diff --git a/src/main/java/com/nhn/hippo/web/dao/RootTraceIndexDao.java b/src/main/java/com/nhn/hippo/web/dao/RootTraceIndexDao.java new file mode 100644 index 000000000..7fbc305f9 --- /dev/null +++ b/src/main/java/com/nhn/hippo/web/dao/RootTraceIndexDao.java @@ -0,0 +1,15 @@ +package com.nhn.hippo.web.dao; + +import java.util.List; + +/** + * + */ +public interface RootTraceIndexDao { + List scanTraceIndex(String agent, long start, long end); + + List> multiScanTraceIndex(String[] agents, long start, long end); + + List parallelScanTraceIndex(String[] agents, long start, long end); + +} diff --git a/src/main/java/com/nhn/hippo/web/mapper/AnnotationMapper.java b/src/main/java/com/nhn/hippo/web/mapper/AnnotationMapper.java index e955bb50c..24bd211fc 100644 --- a/src/main/java/com/nhn/hippo/web/mapper/AnnotationMapper.java +++ b/src/main/java/com/nhn/hippo/web/mapper/AnnotationMapper.java @@ -31,27 +31,26 @@ public class AnnotationMapper implements RowMapper> int offset = kv.getValueOffset(); if (kv.getFamilyLength() == HBaseTables.TRACES_CF_ANNOTATION.length) { -// byte[] value = kv.getValue(); -// if(value == null) { -// continue; -// } int valueLength = kv.getValueLength(); if (valueLength == 0) { continue; } int size = BytesUtils.bytesToInt(buffer, offset); + offset += 4; if (size == 0) { continue; } - offset += 4; + List bos = new ArrayList(size); for (int i = 0; i < size; i++) { AnnotationBo annotationBo = new AnnotationBo(); annotationBo.setSpanId(spanId); offset = annotationBo.readValue(buffer, offset); bos.add(annotationBo); - logger.trace("read annotation:{}", annotationBo); + if (logger.isTraceEnabled()) { + logger.trace("read annotation:{}", annotationBo); + } } annotationList.put(spanId, bos); } diff --git a/src/main/java/com/nhn/hippo/web/mapper/BinaryAnnotationDecoder.java b/src/main/java/com/nhn/hippo/web/mapper/BinaryAnnotationDecoder.java deleted file mode 100644 index a88c2348c..000000000 --- a/src/main/java/com/nhn/hippo/web/mapper/BinaryAnnotationDecoder.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.nhn.hippo.web.mapper; - -import com.profiler.common.dto.thrift.BinaryAnnotation; -import com.profiler.common.dto.thrift.Span; - -/** - * - */ -public interface BinaryAnnotationDecoder { - void decode(Span span); -} diff --git a/src/main/java/com/nhn/hippo/web/mapper/JavaObjectDecoder.java b/src/main/java/com/nhn/hippo/web/mapper/JavaObjectDecoder.java deleted file mode 100644 index 5c81a1616..000000000 --- a/src/main/java/com/nhn/hippo/web/mapper/JavaObjectDecoder.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.nhn.hippo.web.mapper; - -import com.profiler.common.dto.thrift.Annotation; -import com.profiler.common.dto.thrift.BinaryAnnotation; -import com.profiler.common.dto.thrift.Span; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.*; -import java.util.ArrayList; -import java.util.List; - -/** - * 임시 객체 - */ -public class JavaObjectDecoder implements BinaryAnnotationDecoder { - - private Logger logger = LoggerFactory.getLogger(this.getClass()); - - @Override - public void decode(Span span) { -// List annotations = span.getAnnotations(); -// -// List binaryAnnotations = span.getBinaryAnnotations(); -// for (BinaryAnnotation binaryAnnotation : binaryAnnotations) { -// Object decode = decode(binaryAnnotation); -// Annotation annotation = new Annotation(binaryAnnotation.getTimestamp(), binaryAnnotation.getKey() + ":" + decode.toString()); -// annotations.add(annotation); -// } - } - -// private Object decode(BinaryAnnotation binaryAnnotation) { -// ByteArrayInputStream ins = new ByteArrayInputStream(binaryAnnotation.getValue()); -// try { -// ObjectInputStream in = new ObjectInputStream(ins); -// Object readValue = in.readValue(); -// return readValue; -// } catch (IOException e) { -// logger.warn("binaryAnnotation decode fail Cause:{}", e.getMessage(), e); -// return "binaryAnnotation decode fail Cause:" + e.getMessage(); -// } catch (ClassNotFoundException e) { -// logger.warn("binaryAnnotation decode fail Cause:{}", e.getMessage(), e); -// return "binaryAnnotation decode fail Cause:" + e.getMessage(); -// } -// } -} diff --git a/src/main/java/com/nhn/hippo/web/mapper/SpanMapper.java b/src/main/java/com/nhn/hippo/web/mapper/SpanMapper.java index 4573d8466..e3e6678fb 100644 --- a/src/main/java/com/nhn/hippo/web/mapper/SpanMapper.java +++ b/src/main/java/com/nhn/hippo/web/mapper/SpanMapper.java @@ -68,38 +68,6 @@ public class SpanMapper implements RowMapper> { return spanList; -// NavigableMap familyMap = result.getFamilyMap(COLFAM_SPAN); -// if (familyMap == null) { -// return Collections.emptyList(); -// } - -// List spanList = new ArrayList(familyMap.size()); -// Put put = new Put(SpanUtils.getTracesRowkey(span), span.getTimestamp()); -// // TODO columName이 중복일 경우를 확인가능하면 span id 중복 발급을 알수 있음. -// put.add(COLFAM_SPAN, Bytes.toBytes(span.getSpanID()), value); - -// byte[] rowKey = result.getRow(); -// long most = BytesUtils.bytesToFirstLong(rowKey); -// long least = BytesUtils.bytesToSecondLong(rowKey); -// -// for (NavigableMap.Entry entry : familyMap.entrySet()) { -// SpanBo spanBo = new SpanBo(); -// -// spanBo.setMostTraceID(most); -// spanBo.setLeastTraceID(least); -// spanBo.setSpanID(Bytes.toLong(entry.getKey())); -// // -// //byte[] spanId = entry.getKey(); -//// if (binaryAnnotationDecoder != null) { -//// binaryAnnotationDecoder.decode(span); -//// } -// -// if (logger.isDebugEnabled()) { -// logger.debug("read span :{}", spanBo); -// } -// spanList.add(spanBo); -// } -// return spanList; } private void addAnnotation(List spanList, Map> annotationMap) { diff --git a/src/main/java/com/nhn/hippo/web/service/FlowChartServiceImpl.java b/src/main/java/com/nhn/hippo/web/service/FlowChartServiceImpl.java index 38c9ba568..5d9de582d 100755 --- a/src/main/java/com/nhn/hippo/web/service/FlowChartServiceImpl.java +++ b/src/main/java/com/nhn/hippo/web/service/FlowChartServiceImpl.java @@ -2,6 +2,7 @@ package com.nhn.hippo.web.service; import com.nhn.hippo.web.calltree.rpc.RPCCallTree; import com.nhn.hippo.web.calltree.server.ServerCallTree; +import com.nhn.hippo.web.dao.RootTraceIndexDao; import com.nhn.hippo.web.dao.TraceDao; import com.nhn.hippo.web.dao.TraceIndexDao; import com.nhn.hippo.web.service.TracesProcessor.SpanHandler; @@ -19,6 +20,7 @@ import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Service; +import org.springframework.util.StopWatch; import java.util.*; @@ -37,6 +39,9 @@ public class FlowChartServiceImpl implements FlowChartService { @Autowired private TraceDao traceDao; + @Autowired + private RootTraceIndexDao rootTraceIndexDao; + @Autowired private TraceIndexDao traceIndexDao; @@ -71,7 +76,8 @@ public class FlowChartServiceImpl implements FlowChartService { if (logger.isTraceEnabled()) { logger.trace("scan {}, {}, {}", new Object[]{agentIds[0], from, to}); } - List bytes = this.traceIndexDao.scanTraceIndex(agentIds[0], from, to); +// List bytes = this.traceIndexDao.scanTraceIndex(agentIds[0], from, to); + List bytes = this.rootTraceIndexDao.scanTraceIndex(agentIds[0], from, to); // 이런 필터로직을 scan filter에서 할수 없나? Set result = new HashSet(); for (byte[] traceId : bytes) { @@ -82,7 +88,8 @@ public class FlowChartServiceImpl implements FlowChartService { return result; } else { // multi scan 가능한 동일 htable 에서 액세스함. - List> multiScan = this.traceIndexDao.multiScanTraceIndex(agentIds, from, to); +// List> multiScan = this.traceIndexDao.multiScanTraceIndex(agentIds, from, to); + List> multiScan = this.rootTraceIndexDao.multiScanTraceIndex(agentIds, from, to); Set result = new HashSet(); for (List scan : multiScan) { for (byte[] traceId : scan) { diff --git a/src/main/resources/hbase.properties b/src/main/resources/hbase.properties index 2fca7995f..2bbb9d2c0 100644 --- a/src/main/resources/hbase.properties +++ b/src/main/resources/hbase.properties @@ -1,3 +1,3 @@ -hbase.client.host=localhost -#hbase.client.host=10.25.131.38 +#hbase.client.host=localhost +hbase.client.host=10.25.131.38 hbase.client.port=2181 \ No newline at end of file diff --git a/src/test/java/com/nhn/hippo/web/performance/TestSuite.java b/src/test/java/com/nhn/hippo/web/performance/TestSuite.java new file mode 100644 index 000000000..a2feb9123 --- /dev/null +++ b/src/test/java/com/nhn/hippo/web/performance/TestSuite.java @@ -0,0 +1,42 @@ +package com.nhn.hippo.web.performance; + +import org.apache.http.HttpResponse; +import org.apache.http.client.HttpClient; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.impl.client.DefaultHttpClient; +import org.junit.Test; + +import java.io.IOException; + +/** + * + */ +public class TestSuite { + // @Test + public void insertData() throws IOException, InterruptedException { + + + for (int i = 0; i < 10000; i++) { + int mod = i % 4; + if (mod == 0) { + HttpClient client = new DefaultHttpClient(); + HttpGet get1 = new HttpGet("http://localhost:8080/combination.hippo"); + HttpResponse execute = client.execute(get1); + } else if (mod == 1) { + HttpClient client = new DefaultHttpClient(); + HttpGet get2 = new HttpGet("http://localhost:8080/mysql.hippo"); + HttpResponse execute = client.execute(get2); + } else if (mod == 2) { + HttpClient client = new DefaultHttpClient(); + HttpGet get3 = new HttpGet("http://localhost:8080/donothing.hippo"); + HttpResponse execute = client.execute(get3); + } else if (mod == 3) { + HttpClient client = new DefaultHttpClient(); + HttpGet get4 = new HttpGet("http://localhost:8080/combination.hippo"); + HttpResponse execute = client.execute(get4); + } + Thread.sleep(300); + } + + } +}