ISSUE: Pinning inside synchronized
대부분의 애플리케이션은 RDB를 통해서 영속화 합니다. 제가 관리하는 서비스 경우에는 MySQL 를 사용하고 있습니다. 대부분의 jdbc-driver 코드 내에는 동시성 이슈를 처리하기 위해서 synchronized
를 이용해서 구현되어 있습니다. 이것 때문에 Carrier Thread에서 lock이 걸리는 일명 pinning(고정) 이슈가 있으며, 이것 때문에 성능 저하가 큽니다.
대표로 jdbc-driver를 예로 들긴 했지만 jdbc-driver 만의 문제는 아닙니다. 기존 레거시 라이브러리에서 synchronized
를 사용한다면 다 문제가 될 수 있습니다. 다행히 Spring 에서는 이 문제를 대부분 해결한 버전이 릴리즈 됐습니다.
Pinning Issue on Virtual Thread
Pinning 이슈에서 대해서 간단하게 알아보겠습니다. 먼저 Virtual Thread에 대한 구조를 알아야합니다.
// TODO 이거 제대로 작성해야하는데 귀찮음. 정리가 잘 된 다른 블로그 글을 링크할까 고민 중…
Pinning Solution
해결책은 의외로 간단합니다. synchronized -> ReteerantLock
로 변경하면 끝이죠.
MySQL Driver
mysql에서 이미 대응 중이며, MySQL Connector/J(jdbc-driver) 9.0 버전에서 해결될 예정이라고 합니다.
참고: https://bugs.mysql.com/bug.php?id=110512
여러분들도 사용하시는 jdbc-driver나 라이브러리의 릴리즈 노트 또는 코드를 확인하시길 바랍니다.
MariaDB Driver
mysql 사촌 뻘인 MariaDB의 경우에는 벌써 Virtual Thread를 MariaDB Java connector 3.3.0 적용했네요.
거기에 https://mariadb.com/resources/blog/benchmark-jdbc-connectors-and-java-21-virtual-threads/ 블로그에 벤치마크 정보까지 보여주는군요.
힘내라 MySQL!!!
아직은 시기상조?
하지만 non-blocking 기반으로 구현된 driver(ex: MariaDB)를 사용한다면 Virtual Thread를 긍정적으로 검토해 볼 수 있습니다. 그 외 아래와 같은 경우 좋다고 봅니다.
- Edge 서비스(Api Gateway)
- 처리량이 중요한 서비스: 단, Latency는 좀 부족할 수 있습니다. 그럼에도 리소스 대비 처리량은 우수합니다.
이미 Java 커뮤니티에서는 synchronized
지시어 를 많이 제거하고 있습니다. 제가 봤을 때는 시간의 문제라고 보고 있으며, 이제 타 플랫폼의 경량 스레드(고루틴, 코루틴)를 기존 Thread 모델 기반 코드 베이스에서 편하게 사용할 수 있는 시대가 곧 다가올 거라고 봅니다.
추가로 JEP 425: Virtual Threads (Preview) 에서 추후 Pinning 이슈를 회피할 수 있다고 했습니다. 이게 된다면 기존 레거시 라이브러리 상에서도 편하게 Virtual Thread를 사용할 수 있을 것 같네요. (하지만 native
호출에 대해서는 제약은 유지한다고 하네요)
JEP-425 일부 발췌
...
1. When it executes code inside a synchronized block or method, or
2. When it executes a native method or a foreign function.
...
In a future release, we may be able to remove the first limitation above (pinning inside synchronized). The second limitation is required for proper interaction with native code.
그래서 우리가 할 수 있는 것은?
- 공유 자원 동시성 제어가 필요하면
synchronized
를 사용하지 않고ReentrantLock
을 사용. - 사용하는 라이브러리에 Pinning 이슈가 있는지 확인하기(모든 라이브러리를 일일이 찾기는 힘드니 성능테스트 추천)
-Djdk.tracePinnedThreads=full
or short
JVM 옵션으로 Pinning 이슈 추적 가능 - 기다린다 – 언젠가 Java 커뮤니티에서 다 해결해 줄 겁니다.-
1 thought on “Virtual Thread Pinning Issue”