본문 바로가기
SingleStoreDB/Support Bulletin

HikariCP, SingleStore 연동 테스트 - [Support Bulletin 14]

by 에이플랫폼 [Team SingleStore Korea] 2025. 8. 21.

안녕하세요! 에이플랫폼 Support Bulletin의 열네 번째 이야기입니다. 😊

최근 SingleStore를 도입하는 기업이 늘면서, 기존 애플리케이션 코드와의 호환성에 대한 문의도 자연스럽게 증가하고 있습니다.

특히, 자바 개발자라면 효율적인 커넥션 관리를 위해 HikariCP를 표준처럼 사용하고 계실 텐데요.

그래서 많은 분들이 궁금해하십니다. "SingleStore에서 HikariCP의 세부 옵션들이 문제없이 작동할까?"

결론부터 말씀드리면, 호환됩니다.

오늘, 이 글에서는 keepaliveTime, connectionTimeout 같은 핵심 옵션들이 SingleStore 환경에서 어떻게 동작하는지 실제 테스트를 통해 명확하게 보여드리겠습니다.

 


1. 데이터베이스 연결, 왜 비싼 작업일까요?

애플리케이션이 데이터베이스와 통신하려면 먼저 '연결(Connection)'이라는 과정을 거쳐야 합니다.

이는 단순히 선을 꽂는 것 이상으로, 네트워크 통신, 인증, 세션 설정 등 여러 단계가 포함된 복잡하고 비용이 큰 작업입니다.

Mysql의 공식문서에 따르면, 일반적인 INSERT 쿼리 실행 비용을 분석했을 때 '연결' 과정이 가장 큰 비중을 차지합니다.

MySQL 쿼리 비용 분석 (비율)

  • Connecting: (3)
  • Sending query to server: (2)
  • Parsing query: (2)
  • Inserting row: (1 × size of row)
  • Inserting indexes: (1 × number of indexes)
  • Closing: (1)

요청이 있을 때마다 이 비싼 연결 과정을 반복한다면 애플리케이션 성능에 병목이 될 수밖에 없습니다.

이러한 문제를 해결하기 위해 등장한 기술이 바로 '커넥션 풀(Connection Pool)'입니다.


2. 최고의 커넥션 풀, HikariCP를 사용하는 이유

커넥션 풀은 데이터베이스 연결을 미리 정해진 개수만큼 생성해두고, 필요할 때마다 빌려주고 반납받는 방식으로 동작하는 기술입니다. 매번 연결을 새로 만드는 비용을 없애 애플리케이션의 응답 속도와 처리량을 획기적으로 개선합니다.

수많은 커넥션 풀 라이브러리 중에서도 HikariCP는 자바 환경에서 사실상 표준으로 자리 잡았습니다.

그 이유는 압도적인 성능 때문입니다.

HikariCP의 성능은 다음 벤치마크 자료를 통해 확인할 수 있습니다.

출처:  https://github.com/brettwooldridge/HikariCP?tab=readme-ov-file

HikariCP의 핵심 철학은 '제로 오버헤드(Zero-Overhead)'입니다.

바이트 코드 수준까지 최적화하여 불필요한 동작을 최소화하고, 여러 스레드가 동시에 커넥션을 요청하는 상황에서도 지연 없이 안정적으로 커넥션을 제공합니다.


3. 실전 테스트

이제 가장 중요한 질문에 답할 차례입니다. "HikariCP의 핵심 기능들이 SingleStore에서도 정말 잘 작동할까?”

저는 두 가지 핵심 옵션을 직접 테스트하여 호환성을 검증했습니다.

테스트 환경

  • 커넥션 풀: HikariCP (버전 5.1.0)
  • 데이터베이스: SingleStore (On-premise, VM)
  • JDBC 드라이버: singlestore-jdbc-client (버전 1.2.8)

테스트 옵션 상세

  • connectionTimeout: 커넥션 풀이 비어있을 때, 애플리케이션이 커넥션을 얻기 위해 대기하는 최대 시간입니다. 이 시간이 지나면 예외가 발생하여 시스템이 무한정 대기하는 것을 방지합니다.
  • keepaliveTime: 커넥션이 오랫동안 사용되지 않아도(유휴 상태) 네트워크 방화벽 등에 의해 끊어지는 것을 방지하기 위해, 주기적으로 간단한 쿼리를 보내 연결이 살아있는지 확인하고 유지하는 기능입니다.

SingleStore JDBC 의존성 설정 (pom.xml)

<dependency>
    <groupId>com.singlestore</groupId>
    <artifactId>singlestore-jdbc-client</artifactId>
    <version>1.2.8</version>
</dependency>
 

테스트 결과 요약

(전체 테스트 코드는 에이플랫폼 Github에서 확인하실 수 있습니다.)

👉에이플랫폼 Github👈

기본 연결 및 CRUD 테스트

  • 결과: 성공
  • HikariCP를 통해 SingleStore에 정상적으로 연결되었으며, 테이블 생성(Create), 데이터 삽입(Insert), 조회(Select), 수정(Update), 삭제(Drop) 등 모든 기본 작업이 완벽하게 수행되는 것을 확인했습니다.
private static void testBasicConnection() {
        HikariConfig config = new HikariConfig();
        config.setJdbcUrl("jdbc:singlestore://{Host ip}:{Port}/{DB Name}"); 
        config.setUsername("{root}");
        config.setPassword("{PASSWD}");

        try (HikariDataSource ds = new HikariDataSource(config)) {
            System.out.println("HikariCP connection pool successfully initialized.");

            try (Connection conn = ds.getConnection();
                 Statement stmt = conn.createStatement()) {
                stmt.execute("CREATE TABLE IF NOT EXISTS users (id INT PRIMARY KEY, name VARCHAR(50))");
                System.out.println("Table 'users' created or already exists.");
                stmt.executeUpdate("INSERT INTO users (id, name) VALUES (1, 'Alice')");
                System.out.println("Record inserted.");
                ResultSet rs = stmt.executeQuery("SELECT * FROM users");
                while(rs.next()) {
                    System.out.println("ID: " + rs.getInt("id") + ", Name: " + rs.getString("name"));
                }
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
    
# 결과 로그
--- 기본 연결 테스트 시작 ---
HikariCP connection pool successfully initialized.
Table 'users' dropped if it existed.
Table 'users' created.
Record inserted: Alice (ID: 1)
--- First SELECT ---
Retrieved: ID: 1, Name: Alice
Record updated: Alice -> Bob (ID: 1)
--- Second SELECT (after update) ---
Retrieved: ID: 1, Name: Bob
Table 'users' dropped.

 

connectionTimeout 옵션 테스트

  • 결과: 성공 (의도된 예외 발생)
  • 모든 커넥션을 사용 중인 상태에서 새로운 커넥션을 요청하자, 설정한 connectionTimeout(1초)이 지난 후 예상대로 Connection is not available, request timed out 예외가 발생하는 것을 확인했습니다. 이는 해당 옵션이 SingleStore 환경에서 정확히 동작함을 의미합니다.
private static void testConnectionTimeout() {
        HikariConfig config = new HikariConfig();
        config.setJdbcUrl("jdbc:singlestore://{Host ip}:{Port}/{DB Name}");
        config.setUsername("{root}");
        config.setPassword("{PASSWD}");
        
        config.setMaximumPoolSize(1);
        config.setConnectionTimeout(1000); 

        try (HikariDataSource ds = new HikariDataSource(config)) {
            Connection conn1 = ds.getConnection();
            System.out.println("첫 번째 커넥션 확보.");

            Connection conn2 = ds.getConnection();
            System.out.println("두 번째 커넥션 확보.");

            conn1.close();
            conn2.close();
        } catch (SQLException e) {
            System.out.println("예상된 예외 발생: " + e.getMessage());
        }
    }
  
# 결과 로그
--- connectionTimeout 옵션 테스트 시작 ---
첫 번째 커넥션 확보.
예상된 예외 발생: HikariPool-2 - Connection is not available, request timed out after 1000ms (total=1, active=1, idle=0, waiting=0)

 

keepaliveTime 옵션 테스트

  • 결과: 성공
  • 커넥션을 받은 후 keepaliveTime으로 설정한 시간보다 오래 대기해도, 커넥션이 끊기지 않고 안정적으로 유지되는 것을 확인했습니다. 이로써 예기치 않은 커넥션 단절 문제를 효과적으로 방지할 수 있습니다.
private static void testKeepaliveTime() {
        HikariConfig config = new HikariConfig();
        config.setJdbcUrl("jdbc:singlestore://{Host ip}:{Port}/{DB Name}");
        config.setUsername("{root}");
        config.setPassword("{PASSWD}");
        
        config.setKeepaliveTime(10000);
        config.setIdleTimeout(30000); 

        try (HikariDataSource ds = new HikariDataSource(config)) {
            Connection conn = ds.getConnection();
            System.out.println("커넥션 확보. keepaliveTime이 지나도록 대기...");

            Thread.sleep(15000);

            try (Statement stmt = conn.createStatement()) {
                ResultSet rs = stmt.executeQuery("SELECT 1");
                while(rs.next()) {
                    System.out.println("커넥션은 여전히 활성 상태이며 정상 작동합니다.");
                }
            }
            conn.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
 
# 결과 로그
--- keepaliveTime 옵션 테스트 시작 ---
커넥션 확보. keepaliveTime이 지나도록 대기...
커넥션은 여전히 활성 상태이며 정상 작동합니다.
 

이번 테스트를 통해 SingleStore는 고성능 커넥션 풀인 HikariCP와 호환된다는 사실을 확인했습니다.

HikariCP를 사용하시는 개발자분들은 안심하고 SingleStore의 강력한 성능과 안정성을 활용하여 애플리케이션을 구축하실 수 있습니다.

관련 테스트 코드나 SingleStore 사용에 대해 궁금한 점이 있다면 언제든지 문의해주세요!

감사합니다.