NameLock을 사용하는데 자꾸 멈춘다?

GwanMtCat·2023년 11월 25일
0

NameLock을 세팅하고 분산 락을 처리하려고 테스트하는데.. 테스트 코드가 자꾸 멈춘다

SQL Error: 0, SQLState: null
Connection is not available, request timed out after 30006ms.

뭐지...? 난 잘못 설정한 게 없는데, 혹시나 poolSize를 확인해보았다.

  • minimum-idle

    • 아무런 일을 하지않아도 적어도 이 옵션에 설정 값 size로 커넥션들을 유지해주는 설정을 말한다.
  • maximum-pool-size

    • pool에 유지시킬 수 있는 최대 커넥션 수. pool의 커넥션 수가 옵션 값에 도달하게 되면 idle인 상태는 존재하지 않는다.
  • maxLifetime

    • 커넥션 풀에서 살아있을 수 있는 커넥션의 최대 수명시간. 사용중인 커넥션은 maxLifetime에 상관없이 제거되지않음. 사용중이지 않을 때만 제거됨. 풀 전체가아닌 커넥션 별로 적용이되는데 그 이유는 풀에서 대량으로 커넥션들이 제거되는 것을 방지하기 위함
    • 단위는 ms로 위의 경우는 5분이 된다.

이외에도 다양한 값이 있는데 여길 참조하자.

나의 경우 NamedLock을 사용하는데 다음과 같이 짜여 있다.

즉 한 기능을 처리하기 위해 한 쓰레드에서 Connection 을 2개 잡고 있다.

근데 나는 동시성 테스트를 하기 위해 10개 이상의 쓰레드를 동시에 실행하고 있고,
순간적으로 3개를 얻은 후, 추가 커넥션을 얻기위해 대기하는 쓰레드, 커넥션을 대기하지 못하고 큐에 쌓아있는 쓰레드의 상태로 timeOut 상태까지 동작이 안하는 것이 었다..

그럼 대체 커넥션은 몇개를 설정해야 할까?

나랑 같은 상황을 겪으신 분이 이것에 대한 해답을 주었다.

HikariCP팀은 아래와 같은 DBCP 최소 사이즈 공식을 제안하였는데 다음과 같다.

필요한 풀사이즈 = 스레드 수 * (하나의 작업에 필요한 커넥션 수 - 1) + 1(교착상태를 피하기 위한 여유 공간)

나의 코드는 10개 이상의 클라이언트가 동시에 수행하고, 네임드락을 사용하면
네임드락의 락을 걸기 위한 커넥션, 이외 추가 커넥션이 1개 더필요하므로

즉 나의 경우, 10 * (2 - 1) + 1 = 총 11개이면 정상 동작한다는 것이다.

테스트 결과, 이제 정상 동작한다.

다만 이 공식은 실무에서는 그대로 적용해서는 안된다. 실무에서는 예상한 인원만큼 안들어오고 수많은 쿼리가 돌고있기 때문에 커넥션이 내 의도대로 사용되지 않으므로 항상 꾸준한 테스트와 모니터링을 위해 커넥션 수를 유지해야겠다.

우아한 형제들에서 HikariCP 데드락 케이스가 있는데 나중에 꼭 읽어보도록 해야겠다.
https://techblog.woowahan.com/2663/


참조한 책 및 사이트

https://velog.io/@hhg1993/%EC%A0%81%EC%A0%88%ED%95%9C-ConnectionPool-%EC%84%A4%EC%A0%95%EC%9D%98-%EC%A4%91%EC%9A%94%EC%84%B1

0개의 댓글