From 3153e7697d200e0cc1fe31f7c7ff6bf8c2d7ae70 Mon Sep 17 00:00:00 2001 From: wkwon Date: Wed, 15 May 2024 16:00:28 +0900 Subject: [PATCH] =?UTF-8?q?[15=EC=A3=BC=EC=B0=A8=201]=20JDBC,=20DataSource?= =?UTF-8?q?,=20HikariCP?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- woo/img/jdbc.jpg | Bin 0 -> 57731 bytes woo/jdbc-datasource-hikaricp.md | 165 ++++++++++++++++++++++++++++++++ 2 files changed, 165 insertions(+) create mode 100644 woo/img/jdbc.jpg create mode 100644 woo/jdbc-datasource-hikaricp.md diff --git a/woo/img/jdbc.jpg b/woo/img/jdbc.jpg new file mode 100644 index 0000000000000000000000000000000000000000..03ebaee68d178a24af17946c3bae30bc0a2f40f9 GIT binary patch literal 57731 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 O{i&w>b4&T##Qy`IsrHuu literal 0 HcmV?d00001 diff --git a/woo/jdbc-datasource-hikaricp.md b/woo/jdbc-datasource-hikaricp.md new file mode 100644 index 0000000..07e5364 --- /dev/null +++ b/woo/jdbc-datasource-hikaricp.md @@ -0,0 +1,165 @@ +# JDBC, DataSource, HikariCP +## 개요 +--- +1. JDBC API +2. DataSource +3. HikariCP +

+## JDBC (Java Database Connectivity) +--- +![jdbc.jpg](img/jdbc.jpg) +JDBC는 Java Application과 DB 사이에 연결을 위한 표준 API이다. JDBC를 통해 개발자는 DB의 구체적인 종류와 관계 없이 일관된 접근 방식으로 DB에 접근할 수 있다. +위 그림을 보면 알 수 있듯이 JDBC를 사용하기 위해서는 JDBC 구현체인 JDBC Driver가 필요하고 개발자는 Driver의 사용법은 알 필요 없이 JDBC를 사용해 DB에 접근하게 된다. +

+ +### (1) DriverManager +```java +private static Connection getConnection(String url, java.util.Properties info, Class caller) throws SQLException { + ... 생략 + + for (DriverInfo aDriver : registeredDrivers) { + // If the caller does not have permission to load the driver then + // skip it. + if (isDriverAllowed(aDriver.driver, callerCL)) { + try { + println(" trying " + aDriver.driver.getClass().getName()); + Connection con = aDriver.driver.connect(url, info); + if (con != null) { + // Success! + println("getConnection returning " + aDriver.driver.getClass().getName()); + return (con); + } + } catch (SQLException ex) { + if (reason == null) { + reason = ex; + } + } + + } else { + println(" skipping: " + aDriver.driver.getClass().getName()); + } + + } + + ... 생략 +} +``` +DriverManager는 JDBC Driver들을 관리할 수 있는 객체이고 DriverManager를 통해 DB Connection을 얻을 수 있다. +위 메서드는 DriverManager 객체 내의 private static getConnection(...) 메서드로 public static getConnection(...)가 최종적으로 호출하게 되는 메서드이다. +로직을 살펴보면 등록된 Driver들을 순회하며 connection을 맺어보고 가장 먼저 맺어진 Connection을 반환한다. (여러 Driver가 등록된 경우) +

+ +```java +public static void main(String[] args) throws SQLException { + String url = "jdbc:mysql://localhost:3306/study_db"; + String user = "root"; + String password = "1234"; + + try (Connection connection = DriverManager.getConnection(url, user, password)) { + + // 정적 SQL 실행을 위한 객체 + Statement statement = connection.createStatement(); + + // 질의 결과 테이블 객체 + // 실제 DB 질의도 ResultSet 객체가 하게 된다. (단순히 질의 결과를 가지는 객체가 아님) + ResultSet rs = statement.executeQuery("SELECT * FROM users"); + while (rs.next()) { + System.out.println(rs.getString("name")); + } + } +} +``` +앞서 살펴봤듯이 DriverManager는 url, user, password값으로 DB Connection을 맺어주는 기능을 제공한다. +하지만 위 코드를 보면 알 수 있듯이 DriverManager는 DB 연결을 Util 클래스에 가깝다. +또한 매번 DB 접근을 위해 Connection을 맺고 끊어줘야 한다는 것도 DB 접근이 빈번한 Application 입장에서는 큰 낭비일 것이다. +실제로 DriverManager.getConnection(url, user, password) 수행속도를 확인해보니 부분의 10회 평균이 0.25초였다. +API 요청에서 DB 접근을 위한 Connection 생성에 0.25초를 소비한다면 그 API의 성능은.. 더 말하지 않아도 될 것 같다. +

+ +### (2) DataSource +```java +public interface DataSource extends CommonDataSource, Wrapper { + + Connection getConnection() throws SQLException; + + Connection getConnection(String username, String password) + throws SQLException; + + ... 생략 +} +``` +주석으로 DataSource 설명을 대신하자면 Datasource는 DB Connection을 생성하는 팩토리이다. +DriverManager의 대안으로 탄생했고 DB Connection을 획득하기 위한 메서드들이 정의되어 있다. +JDBC에서는 따로 구현체를 제공하지는 않는다. 때문에 개발자는 DataSource의 여러 구현체 중 원하는 걸 사용해 DB 접근 방식을 선택할 수 있다. +

+ +## HikariCP +--- +```text +Spring Boot uses the following algorithm for choosing a specific implementation: + +1. We prefer HikariCP for its performance and concurrency. If HikariCP is available, we always choose it. +2. Otherwise, if the Tomcat pooling DataSource is available, we use it. +3. Otherwise, if Commons DBCP2 is available, we use it. +4. If none of HikariCP, Tomcat, and DBCP2 are available and if Oracle UCP is available, we use it. + +(https://docs.spring.io/spring-boot/docs/current/reference/html/data.html#data.sql.datasource) +``` +HikariCP는 고성능 JDBC Connection Pool이자 Java 진영에서 DB Connection Pool을 사용할 때 가장 먼저 고려되는 library이다. +위 글은 spring boot 공식 문서인데 Default DataSource로 사용하는 것이 HikariCP이다. 1번 글만 읽어봐도 HikariCP를 얼마나 신뢰하는 지를 알 수 있다. +

+ + +```java +public static void main(String[] args) throws SQLException { + HikariConfig config = new HikariConfig(); + config.setJdbcUrl("jdbc:mysql://localhost:3306/study_db"); + config.setUsername("root"); + config.setPassword("1234"); + + try (HikariDataSource ds = new HikariDataSource(config)) { + Connection connection = ds.getConnection(); + + // 정적 SQL 실행을 위한 객체 + Statement statement = connection.createStatement(); + + // 질의 결과 테이블 객체 + // 실제 DB 질의도 ResultSet 객체가 하게 된다. (단순히 질의 결과를 가지는 객체가 아님) + ResultSet rs = statement.executeQuery("SELECT * FROM users"); + while (rs.next()) { + System.out.println(rs.getString("name")); + } + + } +} +``` +먼저 HikariCP 사용 코드부터 살펴보자. 이름에서도 알 수 있듯이 HikariCP는 DataSource 구현체인 HikariDataSource를 제공한다. +HikariDataSource는 DataSource의 구현체이지만 추가적으로 Closeable 인터페이스를 구현하고 있기도 하다. 때문에 위 코드처럼 try with resource 구문과 함께 사용할 수 있다. +HikariCP는 스스로를 빠르다고 소개하는데 정말 빠른 걸까? 10번을 실행해봤을 때 Connection connection = ds.getConnection()의 수행 시간은 평균 1 MilliSecond이다. +이는 DriverManager를 사용했을 때보다 250배 빨라진 수치이다. 어떻게 HikariCP는 DriverManager에 비해 250배 빠른 성능을 낼 수 있는 것일까? +

+ +### (1) Pooling 기법 +HikariCP의 CP는 Connection Pool의 약어이다. 말 그대로 Connection을 미리 생성해두고 Pool에 보관한 후 필요할 때 꺼내서 쓰는 방식이다. +이러한 방식은 DriverManger를 활용해 필요시에 DB와 Connection을 생성하고 사용 후 Connection을 닫는 방식에 비해 성능과 자원 사용 측면에서 모두 효율적이다. +

+ +### (2) Delegates 최적화 +대다수의 사람들이 HikariCP가 고성능인 이유는 Pooling 기법에 있다고 생각할 것이고 이는 틀린 말은 아니다. +하지만 다른 Connection Pool 기반의 DataSource와 비교했을 때에도 HikariCP가 뛰어나다는 건 다른 이유들도 분명 있다는 뜻일 것이다. +[Down the Rabbit Hole](https://github.com/brettwooldridge/HikariCP/wiki/Down-the-Rabbit-Hole) 글에서는 HikariCP가 어떻게 고성능을 달성했는지 설명해주며 +Connection, Statement 등을 감싼 Delegates의 최적화가 큰 역할을 한다고 말한다. 간단한 예시로 ConnectionProxy는 ArrayList\ 객체를 가지고 있는데 Statement를 생성하고 ArrayList에 담은 후 사용 후에는 제거를 해주게 된다. +이때 remove() 메서드는 Head to tail 순서로 원소를 찾는다. 하지만 대개 사용 직후 Statement가 제가된다는 것을 remove()를 Tail to head 순서로 구현한 FastList 자료 구조를 만들어 사용한다고 한다. +이러한 최적화는 큰 성능 개선은 아니라 말하지만 이정도 수준을 시작으로 JIT 컴파일러를 잘 활용할 수 있도록 바이트코드 수준의 엔지니어링까지 적용되어 고성능을 달성했다고 설명해준다. +

+ +## 정리 +--- +Spring Data JPA나 Spring Data JDBC처럼 개발자가 편하게 사용할 수 있는 라이브러리로 개발을 하다 보니 DB Connection과 그 주변부에 대해 생각하지 않고 개발을 해왔다는 생각이 든다. +게다가 회사 운영에서 DB Connection과 관련한 문제 상황을 겪어보지 못해 더 신경을 못썼던 것 같다. +하지만 JDBC, DataSource, HikariCP라는 DB 접근의 기반 기술을 알아보고 나니 개발했던 API들의 동작을 좀 더 세밀하게 알게된 것 같아 좋았고, 무엇보다 문제가 생겼을 떄 해결 과정에서 큰 힘이되지 않을까 싶다. + + + + +