본문 바로가기

세상사는 이야기/이야기들

[펌] 대량데이타 조회/전송시 고려사항 : N/W,MEM

제목 : 대량데이타 조회/전송시 고려사항 : N/W,MEM  글쓴이: 이원영(javaservice)   2001/09/11 14:27:15  조회수:10957  줄수:184
---------> 받은 메일 내용 <----------> 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으로 구현을 하고 있습니다. > 현재 프로젝트 경험도 적고,, 주위에 조언을 해줄만한 사람도 없고...... > 바쁘시더라도 한번 읽어 보시고 답변을 주셨으면 합니다. >> 현재 개발중인 환경은 >         Windows2000,>         IBM VisualAge for Java 3.5.3>         IBM UDB DB2 5.1>         IBM WebSphere Application Server 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 N/W의 경우 실제 전송속도는 대략 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밖에 나오지 않는 경우도 있습니다)(NOTE: T1:1.544Mbps,E1:2.048Mbps,T3:43.7361Mbps,OC3:155.2Mbps)다음과 같은 방법으로 실제 넘어가야할 데이타의 크기를 확인할 수 있으니 확인해 보세요.java.util.Vector v = ......java.io.ByteArrayOutputStream bos = new java.io.ByteArrayOutputStream();java.io.ObjectOutputStream oos = new java.io.ObjectOutputStream(bos);oos.writeObject(v);oos.flush();bos.close();byte[] bytes = bos.toByteArray();System.out.println("byte[] size of v : " + bytes.length);Vector 와 같은 Object 를 직접 넘기는 경우는 실제 데이타 부분 이외에 추가적인 binary데이타가 전송되기 때문에 다소 더 오래 걸리는 듯 하나, 이를 StringBuffer 로 보내고다시 쪼개는 방법의 번거로움에 비하면 그 차이는 크기 않습니다.Object[] 로 넘기나, Vector 로 넘기나, StringBuffer 로 넘기나,혹은 byte[]로 넘기나 대량 데이타의 경우는 약간의 차이밖에 나지 않습니다.즉, Vector 를 넘길 때, 기본적으로 Serializable 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()를통해 건건이 화면으로 보여준다고 생각해 보면, 순간적으로 많은 량의 메모리가필요하게 되며, 동시사용자가 증가할 때 비효율적인 메모리 bottleneck 으로 이어지게됩니다. 이처럼 대량 데이타의 경우는 오히려, 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에 관련한 부분은 아래 글을 참고하십시요[강좌]웹기반시스템하에서의 성능에 대한 이론적 고찰http://www.javaservice.net/~java/bbs/read.cgi?m=resource&b=consult&c=r_p&n=1008701211Performance Tuning QuickGuide for BenchmarkTesthttp://www.javaservice.net/~java/bbs/read.cgi?m=appserver&b=was&c=r_p&n=985764595WebSphere 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================================================