본문 바로가기

스터디/자바

HikariCp 설정 유의사항

HikariCp 설정

HikariCp를 설정할때 다양한 설정값들이 존재한다.

설정시 유의사항을 알아보자.

HikariCp는 DB 커넥션들을 담아놓는 하나의 통이다.

매번 사용할 때마다 db에 연결할 시 많은 비용이 부담이 크니, 사용할 db 커넥션들을 미리 연결해놓고 풀안에서 관리한다.

 

connectionTimeout

Hikaricp커넥션 타임아웃은 풀에서 커넥션을 구할때까지 기다리는 시간이다.

흔히 jdbc의 커넥션 타임아웃과 헷갈려서 실제 DB의 커넥션을 구할때까지의 시간으로 착각하기도 하는데 실제 DB의 연결시간과는 관련없다.

 

minimumIdle

커넥션 풀에 유지할 최소 유휴 커넥션최소 개수이다.

최적의 성능을 유지하려면 minimumIdle = maximumPoolSize 같게 설정하여 고정 커넥션 수를 유지한다.

트래픽에 따라 커넥션을 늘었다 줄었다하면 고정적인 성능을 낼 수 없다.
DB의 커넥션 자원은 낭비될 수 있지만, MSA로 도메인 별 DB를 각각 구축하는 트렌드 덕분에 풀 사이즈를 최대로 설정하는 편이다.

기본값은 maximumPoolSize와 동일하므로 minimumIdle을 설정하지 않으면 minimumIdle = maximumPoolSize가 된다.

 

maximumPoolSize

유휴 상태 + 사용중인 커넥션의 총합 최대 갯수 설정이다.

풀에 커넥션이 없을때 connectionTimeout 시간까지 기다려도 커넥션을 받지 못하면 예외가 발생한다.

내 어플리케이션이 어느정도의 커넥션을 만들어야 적절한지 쉽게 파악할 수 없다.
너무 많은 커넥션을 할당하도록 설정하면 DB의 자원낭비이고, 적은 양의 커넥션을 설정하면 커넥션이 모잘라 원하는 트래픽을 받을 수 없다.

아래 링크는 적정량의 poolSize를 설정하는 방법에 대한 설명이다.
hikari docs

 

 

maxLifetime

maxLifetime은 커넥션을 최대 얼마동안 연결유지 할지에 대한 설정이다.

maxLifetime에 설정한 시간이 지나면 커넥션을 재연결한다.

커넥션풀에서 꺼내서 사용중인 커넥션제거되진 않지만, 커넥션 풀에 돌아오는 순간 제거된다.

Ex) 커넥션 설정 예

connectionTimeout : 30초

maximumPoolSize : 3

maxLifetime : 60초

풀 밖에서 사용되고 있는 커넥션은 63초동안 사용되었다. 60초가 지났지만 해제되지 않았다. 이 커넥션은 커넥션풀에 반납되면 해제된다.

60초 연결 유지된 커넥션은 재연결 시도되고, 45초는 아직 재연결 될 시간이 아니다.

DB의 wait timeout보다 짧게 유지하는 것을 추천

 

idleTimeout

커넥션 풀유휴 상태로 놀고 있는 커넥션들의 유지시간이다. 커넥션들이 idleTimeout시간 동안 놀고 있으면 연결 해제 한다.

idleTimeout은 특정 상태일때만 동작한다.

 

   1.minimumIdle < maximumPoolSize

최대 커넥션 수최소 유휴 커넥션 수 보다 커야한다.

idleTimeout은 유휴 상태로 놀고 있는 커넥션들을 ** 제거하는 역할인데, **풀의 최소 갯수까지 떨어지면 더 이상 제거하지 않는다.

그러므로 idleTimeout은 최소 유휴 커넥션수가 최대풀 사이즈보다 작을때 설정하면 된다.

    private final class HouseKeeper implements Runnable
      {
         .....

         @Override
         public void run()
         {
            try {
                ....
               // refresh values in case they changed via MBean
               if (idleTimeout > 0L && config.getMinimumIdle() < config.getMaximumPoolSize()) { --> 설정
                  logPoolState("Before cleanup ");
                  afterPrefix = "After cleanup  ";

                  final List<PoolEntry> notInUse = connectionBag.values(STATE_NOT_IN_USE);
                  int toRemove = notInUse.size() - config.getMinimumIdle();
                  for (PoolEntry entry : notInUse) {
                     if (toRemove > 0 && elapsedMillis(entry.lastAccessed, now) > idleTimeout && connectionBag.reserve(entry)) {
                        closeConnection(entry, "(connection has passed idleTimeout)");
                        toRemove--;
                     }
                  }
               }

               logPoolState(afterPrefix);

               fillPool(); // Try to maintain minimum connections
            }
            catch (Exception e) {
               logger.error("Unexpected exception in housekeeping task", e);
            }
         }
      }
 커넥션 풀안쪽 innerClass로 HouseKeeper라는 별도의 쓰레드가 idleTimeout의 설정에 따라 커넥션을 제거한다.

중간의 코드를 보면 minimumIdle < maximumPoolSize 설정이 존재한다.

 

   2.maxLifetime -1 > idleTimeout

maxLifeTime이 왜 일초이상 커야 동작할까?

maxLifetime은 재연결 시간으로 idleTimeout보다 작다면 계속 idleTimeout이 되기전에 계속 재연결 해버리기 때문에 실제 커넥션들이 최소 갯수까지 떨어지지 않을것이다.

      private void validateNumerics(){
              ...
      if (idleTimeout + SECONDS.toMillis(1) > maxLifetime && maxLifetime > 0 && minIdle < maxPoolSize) {
          LOGGER.warn("{} - idleTimeout is close to or more than maxLifetime, disabling it.", poolName);
          idleTimeout = 0;
       }
              ....
       }

'스터디 > 자바' 카테고리의 다른 글

Long과 double의 원자성을 보장하기 위한 volatile 선언  (0) 2020.07.15
Java의 Future Interface 란?  (0) 2020.07.14
JMH 사용해보기  (1) 2020.06.28
자바의 제네릭  (1) 2020.06.14
자바 인액션으로 보는 병렬스트림  (0) 2020.05.31