JDBC

JDBC

Pinot는 broker 라우팅 SQL 쿼리를 위한 표준 JDBC 인터페이스를 제공해요. 이는 JDBC 드라이버를 기대하는 SQL 도구와 JVM 애플리케이션에 Pinot를 통합하기 더 쉽게 만들어요.

출처: 문서

본문

설치

JDBC 의존성을 코드에 다음과 같이 포함할 수 있어요.

<dependency>
    <groupId>org.apache.pinot</groupId>
    <artifactId>pinot-jdbc-client</artifactId>
    <version>1.4.0</version>
</dependency>
implementation "org.apache.pinot:pinot-jdbc-client:1.4.0"

JDBC 코드를 JAR로 컴파일해 JAR를 애플리케이션의 Drivers 디렉토리에 넣을 수도 있어요.

드라이버는 애플리케이션 시작 시 자동으로 등록되므로 수동으로 등록할 필요가 없어요.

사용 방법

pinot-jdbc-client를 쿼리에 사용하는 예시예요. JDBC URL은 broker가 아닌 controller를 가리켜요.

String dbUrl = "jdbc:pinot://localhost:9000";

try (Connection conn = DriverManager.getConnection(dbUrl);
     Statement statement = conn.createStatement();
     ResultSet rs = statement.executeQuery(
         "SELECT UPPER(playerName) AS name FROM baseballStats LIMIT 10")) {
  while (rs.next()) {
    String playerName = rs.getString("name");
    System.out.println(playerName);
  }
}

드라이버는 자동 등록되므로 수동 DriverManager.registerDriver(...) 호출은 필요 없어요.

연결 URL과 라우팅

현재 드라이버는 두 가지 JDBC 스킴을 인식해요.

  • jdbc:pinot://<controller-host>:<controller-port> — HTTP 쿼리 경로
  • jdbc:pinotgrpc://<controller-host>:<controller-port> — broker gRPC 쿼리 경로

라우팅에 영향을 주는 선택적 URL 및 속성 키:

Key Default Notes
tenant DefaultTenant broker 발견을 하나의 Pinot tenant로 제한
brokers None broker-1:8099;broker-2:8099 같은 세미콜론 구분 broker 재정의. HTTP 경로에 있을 때 드라이버는 controller broker 조회 대신 제공된 broker를 사용.
scheme http controller와 broker HTTP 전송을 HTTPS로 전환

예시:

String dbUrl =
    "jdbc:pinot://controller.example.com:9000?tenant=DefaultTenant&brokers=broker-1:8099;broker-2:8099";
Connection conn = DriverManager.getConnection(dbUrl);

PreparedStatement도 사용할 수 있어요. 자리 표시자 파라미터는 ?로 표현돼요.

Connection conn = DriverManager.getConnection(DB_URL);
PreparedStatement statement = conn.prepareStatement("SELECT UPPER(playerName) AS name FROM baseballStats WHERE age = ?");
statement.setInt(1, 20);

ResultSet rs = statement.executeQuery();
Set<String> results = new HashSet<>();

while(rs.next()){
 String playerName = rs.getString("name");
 results.add(playerName);
}

conn.close();

gRPC 연결

JDBC에서 broker gRPC 전송을 사용하려면 스킴을 jdbc:pinot://에서 jdbc:pinotgrpc://로 전환하세요.

Properties connectionProperties = new Properties();
connectionProperties.setProperty("usePlainText", "false");
connectionProperties.setProperty("tls.truststore.path", "/path/to/grpc-truststore.jks");
connectionProperties.setProperty("tls.truststore.password", "changeit");

Connection conn = DriverManager.getConnection(
    "jdbc:pinotgrpc://localhost:9000?blockRowSize=10000&encoding=JSON&compression=ZSTD",
    connectionProperties);

pinotgrpc 드라이버는 다음 gRPC 전송 속성을 JDBC URL 쿼리 문자열 또는 DriverManager.getConnection(...)에 전달된 Properties 객체를 통해 받아들여요. TLS 설정은 pinot.broker.tls.* 같은 broker 측 키가 아니라 tls.* 네임스페이스를 사용해요.

Property Default Notes
usePlainText true 일반 텍스트 gRPC 전송 사용. TLS를 활성화하려면 false로 설정.
maxInboundMessageSizeBytes 134217728 (128 MB) 클라이언트가 수락하는 최대 인바운드 gRPC 메시지 크기.
channelKeepAliveTimeSeconds -1 (disabled) Keepalive ping 간격. keepalive를 활성화하려면 양수 값 설정.
channelKeepAliveTimeoutSeconds 20 keepalive 승인을 기다리는 타임아웃.
channelKeepAliveWithoutCalls true 활성 RPC가 없어도 keepalive ping 허용.
channelShutdownTimeoutSeconds 10 종료 시 클라이언트가 gRPC 채널 종료를 기다리는 시간.
tls.keystore.type JVM 기본 keystore 유형 (KeyStore.getDefaultType()) 상호 TLS용 클라이언트 keystore 유형.
tls.keystore.path None 상호 TLS용 클라이언트 keystore 경로.
tls.keystore.password None 클라이언트 keystore 비밀번호.
tls.truststore.type JVM 기본 keystore 유형 (KeyStore.getDefaultType()) broker 인증서를 검증하는 데 사용되는 truststore 유형.
tls.truststore.path None broker 인증서를 검증하는 데 사용되는 truststore 경로.
tls.truststore.password None Truststore 비밀번호.
tls.ssl.provider JDK gRPC 클라이언트 SSL 컨텍스트를 구축할 때 사용되는 SSL 공급자.
tls.insecure false broker 인증서 검증 건너뛰기. 비프로덕션 테스트에만 적합.
tls.protocols JVM TLS 기본값 TLSv1.2,TLSv1.3 같은 쉼표 구분 TLS 프로토콜 허용 목록.

JDBC gRPC 경로는 URL 쿼리 문자열이나 연결 속성에 나타날 때 다음 요청별 설정도 전달해요.

  • 메타데이터 옵션: blockRowSize, encoding, compression, Authorization
  • 헤더 접두사 메타데이터: headers.<name>
  • 쿼리 옵션: enableNullHandling, useMultistageEngine

인증

Pinot는 기본 HTTP 인증을 지원하며 구성으로 클러스터에 활성화할 수 있어요. JDBC 드라이버는 다음을 통해 인증을 지원해요.

  • headers.Authorization
  • user 및 password URL 파라미터
  • user 및 password 연결 속성

현재 드라이버의 인증 우선순위:

  1. headers.Authorization
  2. JDBC URL의 user 및 password
  3. Properties 객체의 user 및 password

명시적 인증 헤더 예시:

final String username = "admin";
final String password = "verysecret";

// 사용자 이름과 비밀번호를 연결하고 base64로 인코딩
String plainCredentials = username + ":" + password;
String base64Credentials = new String(Base64.getEncoder().encode(plainCredentials.getBytes()));

// 인증 헤더 생성
String authorizationHeader = "Basic " + base64Credentials;
Properties connectionProperties = new Properties();
connectionProperties.setProperty("headers.Authorization", authorizationHeader);

// 새 Pinot JDBC 드라이버 등록
DriverManager.registerDriver(new PinotDriver());

// 클라이언트 연결을 얻고 인코딩된 인증 헤더 설정
Connection connection = DriverManager.getConnection(DB_URL, connectionProperties);

// 쿼리가 성공적으로 인증되는지 테스트
Statement statement = connection.createStatement();
ResultSet rs = statement.executeQuery("SELECT count(*) FROM baseballStats LIMIT 1;");

while (rs.next()) {
    String result = rs.getString("count(*)");
    System.out.println(result);
}

동일한 인증 흐름은 jdbc:pinotgrpc://...에서도 동작해요. gRPC 경로에서 드라이버는 Authorization을 gRPC 요청 메타데이터로 전달해요.

연결 속성

JDBC 드라이버는 현재 다음 연결 속성을 읽어요.

Property Default Used by Notes
tenant DefaultTenant HTTP and gRPC JDBC controller broker 발견을 하나의 tenant로 제한
brokers None HTTP and gRPC JDBC 세미콜론 구분 broker 재정의
scheme http HTTP broker 전송 및 controller 전송 TLS 활성화 controller 및 HTTP broker용으로 https로 설정
headers.<name> None HTTP and gRPC JDBC headers.Authorization 같은 기본 헤더 또는 메타데이터 추가
user None HTTP and gRPC JDBC 명시적 인증 헤더가 없을 때 기본 인증에 사용
password None HTTP and gRPC JDBC 명시적 인증 헤더가 없을 때 기본 인증에 사용
brokerConnectTimeoutMs 2000 HTTP broker 전송 broker 연결 타임아웃(밀리초)
brokerReadTimeoutMs 60000 HTTP broker 전송 broker 읽기 타임아웃(밀리초)
brokerHandshakeTimeoutMs 2000 HTTP broker 전송 broker TLS 핸드셰이크 타임아웃
controllerConnectTimeoutMs 2000 Controller 전송 controller 연결 타임아웃(밀리초)
controllerReadTimeoutMs 60000 Controller 전송 controller 읽기 타임아웃(밀리초)
controllerHandshakeTimeoutMs 2000 Controller 전송 controller TLS 핸드셰이크 타임아웃
controllerTlsV10Enabled false Controller 전송 controller 요청에 TLSv1.0 재활성화
pinot.jdbc.tls.* None HTTP broker 전송 및 controller 전송 JDBC 드라이버가 소비하는 TLS 구성 네임스페이스

예시:

String dbUrl =
    "jdbc:pinot://controller.example.com:9000?scheme=https&brokerReadTimeoutMs=10000&controllerReadTimeoutMs=10000";

제한 사항

JDBC 클라이언트는 데이터베이스 제한 때문에 INSERT, DELETE, UPDATE 문을 지원하지 않아요. 클라이언트는 데이터베이스를 쿼리하는 데만 사용할 수 있어요. 또한 드라이버는 완전히 ANSI SQL 92를 준수하지 않아요.

JDBC로 Pinot를 통합한다면 소비 도구에서 Connection.getMetaData()와 다른 DatabaseMetaData 메서드를 확인하세요. Pinot는 OLAP 데이터베이스이며 ANSI SQL 도구가 기대하는 일부 JDBC 기능은 의도적으로 지원되지 않아요.

더 알아보기 (Learn more)