본문 바로가기

DB & ORM/MyBatis

MyBatis 내부 동작 원리 정리 (DBCP도)

http://javafactory.tistory.com/entry/iBatis%EC%99%80-DBCP-%EB%B0%94%EB%A1%9C%EC%95%8C%EA%B8%B0


http://d2.naver.com/helloworld/5102792 (DBCP)



요약


1. MyBatis는 모든 쿼리를 prepared statement로 실행


   prepared statement의 장점은 반복 실행 시 준비과정 없이 바로 실행해 좀 더 빠른 응답을 받을 수 있고 DBMS 입장에서는 CPU 사용률을 낮춤.


   statement pooling은 JDBC 드라이버에 의해서도 되고, MyBatis 내에 SessionScope 객체에서 저장된 prepared statement를 캐싱


   하지만 scopre 가 같은 세션으로만 한정되는 문제 때문에 실제적인 효용성은 JDBC 드라이버 단이 좋다.




2. DBCP는 Apache의 커넥션 풀 라이브러리


 1) 원리


     커넥션 생성은 Commons DBCP 에서 이루어짐. Commons DBCP는 PoolableConnection 타입의 커넥션을 생성하고 생성한 


     커넥션에 ConnectionEventListener를 등록. ConnectionEventListener 에는 애플리케이션이 사용한 커넥션을 풀로 반환하기 위해 


     JDBC 드라이버가 호출할 수 있는 콜백 메서드가 있다. 이렇게 생성된 커넥션은 커넥션 풀에 추가됨. 이 때 commons-pool 은 내부적으로


     현재 시간을 담고 있는 타임스탬프와 추가된 커넥션의 레퍼런스를 한 쌍으로 하는 ObjectTimestampPair 라는 자료구조 생성

  

     그리고 이들을 LIFO (STACK) 형태의 CursorableLinkedList 로 관리한다.


   

 2) 커넥션 개수 관련 속성


     커넥션 개수와 관련된 가장 중요한 성능 요소는 일반적으로 커넥션의 최대 개수. 다른 항목들은 크게 영향이 없다.


   2.1) MaxActive 값 설정 방법 :


    DBMS가 수용할 수 있는 커넥션 개수를 확인. 사용자가 너무 많이 몰린다면 MaxActive 값을 충분히 늘리고


    반대로 사용자가 적으면 maxActive 값을 지나치게 작게 설정하지 않는 한 성능에 영향 안줌.


    - Commons DBCP 에서는 DBMS에 로그인을 시도하고 있는 것도 



3) MaxWait 속성


   커넥션 풀 안의 커넥션이 고갈됐을 때 커넥션 반납을 대기하는 시간이며 기본값은 무한정이다. maxWait 속성을 적절하게 설정하지 않아도 


   일반적인 상황에서는 큰 문제가 되지 않는다. 하지만 사용자가 갑자기 급증하거나 DBMS에 장애가 발생했을 때 장애를 더욱 크게


   확산시킬 수 있어 주의




4) TPS와 커넥션 개수와의 관계


   커넥션의 개수가 TPS와 밀접한 관계가 있는 것은 요청 수가 증가해도 커넥션 풀의 커넥션 개수가 특정개수라면 그 이상의 성능을


   낼 수 없기 때문이다. 예를 들면, 커넥션 풀 갯수가 5개 요청은 10개면 5개는 처리되는동안 5개는 maxWait 만큼 기다려야한다.


   이를 해결하는 방법은 maxActive 값을 늘리는 것이지만, DBMS의 리소스는 다른 서비스와 공유해 사용하는 경우가 많기에 


   무조건 커넥션 개수를 크게 설정할 수 없는 상황이 많다. 따라서 예상 접속자 수와 서비스의 실제 부하를 측정해 최적값을 설정하는


   것이 중요하다.



   그렇다면 적당한 maxWait 값은 얼마일까?


   이 부분을 이해하기 위해 Tomcat의 동작 방식도 고려. Tomcat은 스레드 기반으로 동작해 사용자의 요청을 처리. Tomcat 내부에도


   스레드 풀이 있어 사용자의 요청이 들어올 때마다 하나씩 스레드를 꺼내 요청을 처리한다. 만약 여분의 커넥션이 없다면 maxWait 만큼


   기다려야하며, Tomcat 의 스레드도 마찬가지로 기다려야한다는 사실이다. 스레드가 계속 기다리면서 요청이 증가한다면 스레드 풀에 


   있는 모든 스레드가 소진되며, 오류를 출력할 것이다.


   maxWait가 너무 크면 사용자는 이를 기다리지 못하고 떠나버리고 너무 작으면 여분의 커넥션이 없을 때마다 오류를 계속 반환하겠지.


   보통 갑작스럽게 사용자가 증가해 maxWait 값 안에 커넥션을 얻지 못하는 빈도가 늘어난다면 maxWait 값을 더 줄여서 시스템에서


   사용하는 스레드가 한도에 도달하지 않도록 방어가 가능.    이렇게 한다면 시스템 장애는 피하고 간헐적 오류가 발생하는 정도로 


   장애의 영향을 줄일 수 있다. 이런 상황이 자주 있다면 DBCP 의 MaxActive 값과 Tomcat의 maxThread 값을 동시에 늘이는 것을 


   고려