대량데이타 조회시 고려사항 |
대량데이타 조회시 고려사항 글쓴이: 이원영(javaservice) 2001/09/11 14:27:15 조회수:69 줄수:171 ---------> 받은 메일 내용 <---------- > Title : 도움을 부탁드립니다.......... > Date : Thu, 06 Sep 2001 10:07:58 +0900 > From : SCAINET@chollian.net > To : javaservice@hanmail.net > > 지금 프로젝트 초기인데.. EJB의 성능에 대해서 궁금한점이 있어 이렇게 메일을 > 보냅니다.현재 다량의 데이터를 가져올때는 SessionBean에서 직접 DB와 연결하고, > update나 insert, delete 해주는 부분은 EntityBean으로 구현을 하고 있습니다. > 현재 프로젝트 경험도 적고,, 주위에 조언을 해줄만한 사람도 없고...... > 바쁘시더라도 한번 읽어 보시고 답변을 주셨으면 합니다. > > 현재 개발중인 환경은 > Win2000, > Visual age for java 3.5.3 > db2 5.1 > WAS 3.5 입니다. > > 질문할 내용은 다음과 같습니다. > > 1. SessionBean에서 DB를 Access할때 최고 500건정도의 데이터를 가져오는데 그 방식을 > 어떻게 할것인가 입니다. > 첫번째로 다음과 같은 방식으로 구현을 했는데..소량의 데이터는 문제가 안되는데 > 많은 수의 레코드일 경우 엄청난 성능의 저하를 가져옵니다. > .............. > Source > Vector v = new Vector(); > PreparedStatment pstmt = conn.prepareStatment(QUERY); > ... > > resultset = pstmt.executeQuery(); > .. > while(resultset.next()) { > v.addElement(new DATASET(resultset.getString(1),....)); > } > return v; > > 이렇게 할 경우 Query해 오는 부분은 빠른데 return v할때 굉장한 과부하가 > 생깁니다. 그래서 다음과 같이 해 보았는데.. 마찬가지입니다. > > DATASET[] ds = null; > ........... > while(resultset.next()) { > v.addElement(new DATASET(resultset.getString(1),....)); > } > ds = new DATASET[v.size()]; > for(int i=0; i < v.size(); i++ ) { > ds[i] = (DATASET)v.get(i); > } > return ds; > > 마찬 가지로 return ds할때 과부하가 생겨 수행속도가 현저히 떨어집니다. > > 현재는 StringBuffer를 이용해 return 해주고 클라이언트에서 잘라쓰는 방식으로 > 만들고 있는데 이 방식이 과연 최선인가 궁금합니다. > ........ > ResultSetMetaData MetaData = SqlResult.getMetaData(); > ColumnCount = MetaData.getColumnCount(); > StringBuffer BufferValue = new StringBuffer(); > while (SqlResult.next()) { > for(int i = 1 ; i <= ColumnCount ; i ++) { > BufferValue.append(SqlResult.getString(i)); > BufferValue.append(FILED); > }// THE END ONE RECORD > BufferValue.append(RECORD); > } > return BufferValue; > > 2. (기타 질문 생략) > > 평소에 javaservice에서 많은 도움을 얻고 있습니다. 바쁘시더라도 조언을 > 부탁합니다. 다시한번 이렇게 불쑥 메일을 보내 죄송합니다. > > 좋은 하루 되세요... > 그것은 EJB의 성능저하라기 보다는 N/W 부하로서, 정상적인 현상입니다. N/W bandwidth를 높이시든가, 아니면 특정건수 이상은 허용치 않는 것과 같은 업무프로세스적 관점에서 접근해야 합니다. 위의 경우는 특별히 뾰족한 수가 없습니다. 산술적으로 계산하여도, 10 Mbps 라인의 경우 실제 전송속도는 대략 6Mbps 가 나오며, 6Mbps = 6*1024(Kbps) = 6*1024/8 (KB/sec) = 768(KB/sec) 10KB 를 보낼 때, 768(KB/sec) / 10(KB) = 76.8, 즉 1초당전송건수인 TPS(Transaction Per Second) 77 이상을 낼 수 없습니다. 만약 100KB라면 768(KB/sec)/100KB = 7.68, 즉 TPS 7-8 이상을 낼 수 없게 됩니다. N/W 라인이 100Mbps 의 경우 실제 전송속도는 60 Mbps 정도가 나오는 것이 일반적이며 앞서 10 Mbps 의 10배 정도의 TPS 향상이 있게 됩니다.(같은 100Mbps급 허브도 종류에 따라 기껏 20Mbps밖에 나오지 않는 경우도 있습니다) Vector 와 같은 Object 를 직접 넘기는 경우는 실제 데이타 부분 이외에 추가적인 binary 데이타가 전송되기 때문에 다소 더 오래 걸리는 듯 하나, 이를 StringBuffer 로 보내고 다시 쪼개는 방법의 번거로움에 비하면 그 차이는 크기 않습니다. Object[] 로 넘기나, Vector 로 넘기나, StringBuffer 로 넘기나,혹은 byte[]로 넘기나 대량 데이타의 경우는 약간의 차이밖에 나지 않습니다. 즉, Vector 를 넘길 때, 기본적으로 Object 이기 때문에 넘어가야할 일정한 추가적인 binary 데이타가 붙게 되는데, 만약, 실제 데이타의 크기가 작다면 이는 performance 에 큰 차이를 보이지만, 반면 실제 데이타의 사이즈가 무지 크다면, 추가적으로 달라 붙는 데이타는 그에 비해 새발의 피인 것이지요. 어플리케이션 관점에서 주의할 사항은 예를 들어 10MB 의 크기의 데이타를 전송할 때, 특정 Tier 에서 10MB의 데이타를 전부 메모리에 일시적으로 올려두는 우를 범하면 안된다는 것이지요. 동시사용자에 비례해서 순간적으로 그만큼의 메모리 점유가 일어나기 때문입니다. 이 경우는 4k 씩 혹은 일정량씩 주고받고/주고받는 방법을 택해야만이 효율적인 메모리관리가 됩니다. 예를 들면, SmartUpload 의 경우처럼, upload 하는 파일의 크기만큼을 몽땅 메모리에 일시적으로 저장하는 경우가 그러하고, FTP 와 유사한 프로그램을 작성할 때, 파일을 몽땅 읽어들인 후에 전송하려는 경우가 그러합니다. JDBC 프로그램의 경우에도, Entity 클래스나 DBWrapper(혹은 Data Access Object)를 통해 데이타베이스에서 수백건의 데이타를 rs.next()를 돌면서 Vector 에 모두 저장 한 후 이를 return 하는 구조가 일반적으로 사용되고 있는데, 이는 소량 데이타의 경우에 적절한 방법일 뿐이며 대량 데이타 조회시에는 적절치 않습니다. (인터넷기반시스템에서는 이런 경우가 잘 없겠지만) 수백 수천건의 데이타를 JDBC로 조회하여 Servlet 이나 JSP로 웹브라우져에 보여주는 경우, 만약 이를 DBWrapper(혹은 DAO)에서 while(rs.next()) 를 통해 전체를 Entity 클래스의 Vector 에 모두 담은 후 이를 Servlet 이나 JSP로 return 하고, 이를 다시 Enumeration hasMoreElements()를 통해 건건이 화면으로 보여준다고 생각해 보면, 순간적으로 많은 량의 메모리가 필요하게 되며, 동시사용자가 증가할 때 비효율적인 메모리 bottlenect 으로 이어지게 됩니다. 이처럼 대량 데이타의 경우는 오히려, JSP에서 곧바로 while(rs.next()) 를 돌면서 건건이 화면으로 출력되도록 하여 필요 메모리 량을 줄이는 것이 더욱 효과적 입니다. (물론 필요로 하는 Database 연결 개수의 증가를 야기하게 되니 별도의 조치가 필요합니다) C/S 시스템 튜닝을 여러번 해 보신 분들은, 대량 데이타 조회시 건건이 조회하지 않고 Buffer 를 이용하여 대량 데이타를 한번이 조회하여 한번에 File을 경유하거나 혹은 N/W으로 보냄으로써 단일 요청에 따른 응답시간 개선 효과를 경험하신 분들이 많으실 겁니다. 그러나, 한가지 간과하면 안될 사항이, 그 업무가 Batch성이냐 On-Line 성이냐에 따라 상황이 달라 질 수 있다는 것입니다. On-Line 성의 경우, 단위 응답 시간도 중요한 부분이지만, 동시사용자 증가에 따른 TPS(Transaction Per Second,초당 처리건수)의 향상이 더욱 중요하다는 사실입니다. 단일 응답속도가 10초 걸리던 것을 Buffering 을 통해 5초로 단축시켰더라도, 동시에 10명,50명,100명이 접속했을 때, 응답속도가 10초,20초,30초,... 로 급격하게 느려질 수 있다는 것이지요. 반면 단일 응답속도가 여전히 10초가 걸리더라도 동시사용자가 10명,50명,100명이 접속하여도 여전히 10초,11초,12초 가 걸린다면 이것이 더욱 On-Line 성의 업무에 더욱 성능이 높다할 것입니다. (어쩌면 누군가는, "그러면 어느정도의 크키가 '대량데이타'인가요?" 라고 질문을 할 지도 모르겠습니다. 정답은 없습니다. 너무나 다양한 경우의 수가 있기 때문에, 결국 해당 시점에서 CPU/MEM/NW 및 어플리케이션 특성을 고려하여 여러가지 테스트를 통해 스스로 판단하셔야 합니다. 50KB 라면 On-Line 시스템에서 '대량데이타'가 아닐까요??) 또, 어플리케이션서버 파라메터 관점에서는 어떤 특정 어플리케이션의 응답속도가 상대적으로 느리면서 특별히 CPU나 MEM를 점유하지 않는 특성을 가질 경우, 동시에 최대로 처리할 수 있는 수치를 상대적으로 높여 주어야 합니다. 님의 경우처럼 EJB컨테이너를 이용하여 대량 데이타 전송이 결부된 어플리케이션이라면 충분한 N/W bandwidth 상태에서, "최대 EJB Object Pool크기"를 상대적으로 높여주어야 만이 동시에 여러개의 요청을 처리할 수 있게 되고, 그렇게 함으로써, 1초당 처리건수인 TPS 를 상대적으로 높일 수 있습니다.(물론 N/W bottlenect으로 나타나기 전 까지만 효과를 볼 수 있습니다.) TPS 가 높다는 것은 단일 요청에 대한 응답시간이 빨라진다는 뜻이 아닙니다. 예를 들어 단일 요청시에 5초가 걸리는 서비스가 있다면, 동시에 대량 호출이 발생할 때 TPS가 낮다는 것은 응답시간이 10초,20초,30초 등과 같이 산술급수적으로 증가하는 현상으로 이어지는 반면, TPS가 높다는 것은 일정정도까지는 응답시간의 변화가 크지않고 유지되는 현상으로 나타납니다. 이러한 응답속도 및 TPS에 관련한 부분은 아래 글을 참고 하십시요 Performance Tuning QuickGuide for BenchmarkTest http://www.javaservice.net/~java/bbs/read.cgi?m=appserver&b=was&c=r_p&n=985764595 WebSphere BMT 최적 파라메터 셋팅 방법론 http://www.javaservice.net/~java/bbs/read.cgi?m=appserver&b=was&c=r_p&n=989760940 ------------------------------------------------------- 본 문서는 자유롭게 배포/복사 할 수 있으나 반드시 이 문서의 저자에 대한 언급을 삭제하시면 안됩니다 ================================================ 자바서비스넷 이원영 E-mail: javaservice@hanmail.net PCS:011-898-7904 ================================================ from: http://www.javaservice.net/~java/bbs/read.cgi?m=qna&c=r_p&b=consult&n=1000186035 |
'Jop Tip' 카테고리의 다른 글
jvm terminated 와 함께 eclipse가 비정상종료되는 에러!!! (0) | 2006.12.28 |
---|---|
http://www.javastudy.co.kr/api/index.html (1) | 2006.12.28 |
쉘 프로그램의 종류 (0) | 2006.12.14 |
Websphere V3 and V4 Connection Pool 사용법 (0) | 2006.12.14 |
Thread Pool을 만들어 최적의 프로그램을 만들어 보자 (0) | 2006.12.14 |