Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
JDBC (Java Database Connectivity) é um padrão amplamente adotado que permite que aplicações clientes se liguem e trabalhem com dados provenientes de bases de dados e plataformas de big data.
O Driver Microsoft JDBC para Engenharia de Dados Fabric permite-lhe ligar, consultar e gerir cargas de trabalho Spark no Fabric com a fiabilidade e simplicidade do padrão JDBC. Construído sobre as APIs Livy da Fabric, o driver oferece conectividade Spark SQL segura e flexível para as suas aplicações Java e ferramentas de BI. Esta integração permite-lhe submeter e executar código Spark diretamente, sem necessidade de criar itens separados de definição de cadernos ou tarefas Spark. O driver é compatível com clientes JDBC populares como o DbVisualizer e o DBeaver, bem como com ferramentas de BI que suportam conectividade JDBC, incluindo o Tableau.
Principais características
- APIs do JDBC 4.2: Implementa as APIs do JDBC 4.2 para a conectividade do Spark SQL, com limitações do Spark e do Livy, como a ausência de transações JDBC e conjuntos de resultados apenas de avanço e apenas de leitura
- Autenticação Microsoft Entra ID: Múltiplos fluxos de autenticação, incluindo credenciais interativas de cliente e autenticação baseada em certificados
- Sessões de elevada concorrência: Partilha de sessões do Fabric, mediante adesão, para cargas de trabalho simultâneas
-
Agrupamento explícito de ligações: Escolha o HikariCP, um gestor de agrupamento padrão, ou
LivyBuiltInPooledDataSource; os pontos de entrada diretos nunca fazem agrupamento - Suporte nativo para consultas SQL do Spark: Execução direta de instruções SQL do Spark sem tradução
- Suporte Abrangente de Tipos de Dados: Suporte para todos os tipos de dados SQL Spark, incluindo tipos complexos (ARRAY, MAP, STRUCT)
- Pré-busca de Conjuntos de Resultados Assíncronos: Carregamento de dados em segundo plano para melhorar o desempenho
- Padrão de Disjuntor: Proteção contra falhas em cascata com repetição automática
- Reconexão Automática: Recuperação transparente de sessão em falhas de ligação
- Lógica Avançada de Reintento: Reintentar com recuperação exponencial e recuperação de sessão para melhorar a resiliência
- Suporte a Proxy: Configuração de proxy HTTP e SOCKS para ambientes empresariais
Pré-requisitos
Antes de usar o driver Microsoft JDBC para Fabric Data Engineering, certifique-se de que tem:
- Java Development Kit (JDK): Java 11, 17 e 21 (recomendado Java 21)
- Fabric Access: Acesso a um espaço de trabalho Fabric
- Credenciais Microsoft Entra ID: Credenciais adequadas para autenticação
- IDs de espaço de trabalho e casa do lago: identificadores GUID para o seu espaço de trabalho Fabric e casa do lago
Download e Instalação
O Microsoft JDBC Driver for Fabric Data Engineering versão 2.0.1 suporta Java 11, 17 e 21. Use a versão mais recente disponível.
- Descarregue o Microsoft JDBC Driver for Fabric Data Engineering (zip)
- Descarregar o Microsoft JDBC Driver for Fabric Data Engineering (tar)
- Descarregue o ficheiro zip ou tar dos links acima.
- Extrai o ficheiro descarregado para aceder aos ficheiros JAR do driver.
- Selecione o ficheiro JAR que corresponde à sua versão do JRE:
- Para Java 11:
ms-sparksql-jdbc-2.0.1.jre11.jar - Para Java 17:
ms-sparksql-jdbc-2.0.1.jre17.jar - Para Java 21:
ms-sparksql-jdbc-2.0.1.jre21.jar
- Para Java 11:
- Adicione o ficheiro JAR selecionado ao percurso de classes da sua aplicação.
- Para clientes JDBC, configure a classe do driver JDBC:
com.microsoft.spark.livy.jdbc.LivyDriver
Exemplo de Início Rápido
Este exemplo demonstra como se ligar ao Fabric e executar uma consulta utilizando o Microsoft JDBC Driver for Fabric Data Engineering. Antes de executar este código, certifique-se de cumprir os pré-requisitos e instalar o driver. Ao usar AuthFlow=2, o controlador usa DefaultAzureCredential. Para usar o CLI do Azure como origem das credenciais, instale o CLI do Azure e execute az login.
import java.sql.*;
public class QuickStartExample {
public static void main(String[] args) {
// Connection string with required parameters
String url = "jdbc:fabricspark://api.fabric.microsoft.com;" +
"FabricWorkspaceID=<workspace-id>;" +
"FabricLakehouseID=<lakehouse-id>;" +
"AuthFlow=2;" + // DefaultAzureCredential; Azure CLI can be one source
"LogLevel=INFO";
try (Connection conn = DriverManager.getConnection(url)) {
// Execute a simple query
try (Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT 'Hello from Fabric!' as message")) {
if (rs.next()) {
System.out.println(rs.getString("message"));
}
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
Formato de Cadeia de Conexão
Cadeia de Conexão Básica
O Microsoft JDBC Driver for Fabric Data Engineering utiliza o seguinte formato de cadeia de ligação:
jdbc:fabricspark://<hostname>[:<port>][;<parameter1>=<value1>;<parameter2>=<value2>;...]
Componentes da Corda de Ligação
| Componente | Description | Example |
|---|---|---|
| Protocol | Identificador do protocolo URL JDBC | jdbc:fabricspark:// |
| Nome do host | Nome do anfitrião do endpoint do Fabric | api.fabric.microsoft.com |
| Porto | Número de porta opcional (padrão: 443) | :443 |
| Parâmetros | Pares chave=valor separados por ponto e vírgula | FabricWorkspaceID=<guid> |
Exemplos de Cordas de Ligação
Ligação Básica (Autenticação Interativa Baseada em Navegador)
jdbc:fabricspark://api.fabric.microsoft.com;FabricWorkspaceID=<workspace-id>;FabricLakehouseID=<lakehouse-id>;AuthFlow=1
Com Configuração de Recursos Spark
jdbc:fabricspark://api.fabric.microsoft.com;FabricWorkspaceID=<workspace-id>;FabricLakehouseID=<lakehouse-id>;DriverCores=4;DriverMemory=4g;ExecutorCores=4;ExecutorMemory=8g;NumExecutors=2;AuthFlow=2
Com as Propriedades da Sessão Spark
jdbc:fabricspark://api.fabric.microsoft.com;FabricWorkspaceID=<workspace-id>;FabricLakehouseID=<lakehouse-id>;spark.sql.adaptive.enabled=true;spark.sql.shuffle.partitions=200;AuthFlow=2
Com modo de alta concorrência
O modo de alta concorrência (HC) está disponível para ligações ao Microsoft Fabric na versão 1.1.0 do controlador e posteriores. Adicione hcEnabled=true para obter uma sessão HC em vez de uma sessão Livy clássica:
jdbc:fabricspark://api.fabric.microsoft.com;FabricWorkspaceID=<workspace-id>;FabricLakehouseID=<lakehouse-id>;AuthFlow=2;hcEnabled=true
Pode, opcionalmente, identificar a carga de trabalho com uma tag de sessão e selecionar um ambiente Fabric:
jdbc:fabricspark://api.fabric.microsoft.com;FabricWorkspaceID=<workspace-id>;FabricLakehouseID=<lakehouse-id>;AuthFlow=2;hcEnabled=true;sessionTag=orders_etl;FabricEnvironmentID=<environment-id>
O modo HC é de adesão opcional. Se hcEnabled for omitido ou definido para false, o condutor utiliza o percurso clássico da sessão de Livy.
Consulte a secção Modo de elevada concorrência (HC) para obter orientações completas para a configuração.
Authentication
O Microsoft JDBC Driver for Fabric Data Engineering suporta múltiplos métodos de autenticação através do Microsoft Entra ID (anteriormente Azure Active Directory). A autenticação é configurada usando o AuthFlow parâmetro na cadeia de ligação.
Fluxos de Autenticação
| AuthFlow | Método de autenticação | Caso de uso |
|---|---|---|
| 1 | Navegador Interativo | Autenticação interativa do utilizador usando OAuth 2.0 |
| 2 | Cadeia de credenciais predefinida do Azure | Desenvolvimento e autenticação gerida de aplicações; CLI do Azure pode ser uma fonte de credencial |
| 3 | Credenciais Secretas do Cliente (Principal de Serviço) | Autenticação automatizada/serviço-para-serviço |
| 4 | Credencial de Certificado de Cliente | Autenticação do principal de serviço baseada em certificado |
| 5 | Token de Acesso | Token de acesso pré-adquirido ao portador |
Autenticação Interativa do Navegador
Melhor para: Desenvolvimento e aplicações interativas
String url = "jdbc:fabricspark://api.fabric.microsoft.com;" +
"FabricWorkspaceID=<workspace-id>;" +
"FabricLakehouseID=<lakehouse-id>;" +
"AuthFlow=1;" +
"LogLevel=INFO";
Connection conn = DriverManager.getConnection(url);
Parâmetros:
-
AuthFlow=1: Especifica autenticação interativa do navegador
Comportamento:
- Abre uma janela do navegador para autenticação do utilizador
- Armazena em cache as credenciais das ligações subsequentes até que expirem
- Adequado para aplicações de utilizador único
Credenciais do Cliente ou Autenticação do Principal de Serviço
Ideal para: Serviços automatizados e tarefas em segundo plano
String url = "jdbc:fabricspark://api.fabric.microsoft.com;" +
"FabricWorkspaceID=<workspace-id>;" +
"FabricLakehouseID=<lakehouse-id>;" +
"AuthFlow=3;" +
"AuthClientID=<client-id>;" +
"AuthClientSecret=<client-secret>;" +
"AuthTenantID=<tenant-id>;" +
"LogLevel=INFO";
Connection conn = DriverManager.getConnection(url);
Parâmetros Exigidos:
-
AuthFlow=3: Especifica a autenticação das credenciais do cliente -
AuthClientID: ID da aplicação (cliente) a partir do ID Microsoft Entra -
AuthClientSecret: Segredo do cliente do Microsoft Entra ID -
AuthTenantID: ID de inquilino Microsoft Entra
Melhores Práticas:
- Armazenar segredos de forma segura (Azure Key Vault, variáveis de ambiente)
- Use identidades geridas sempre que possível
- Alterne os segredos regularmente
Autenticação Baseada em Certificado
Ideal para: aplicações empresariais que requerem autenticação baseada em certificado
String url = "jdbc:fabricspark://api.fabric.microsoft.com;" +
"FabricWorkspaceID=<workspace-id>;" +
"FabricLakehouseID=<lakehouse-id>;" +
"AuthFlow=4;" +
"AuthClientID=<client-id>;" +
"AuthCertificatePath=/path/to/certificate.pem;" +
"AuthCertificatePassword=<certificate-password>;" +
"AuthTenantID=<tenant-id>;" +
"LogLevel=INFO";
Connection conn = DriverManager.getConnection(url);
Parâmetros Exigidos:
-
AuthFlow=4: Especifica autenticação baseada em certificado -
AuthClientID: ID da aplicação (cliente) -
AuthCertificatePath: Caminho para um ficheiro de certificado PEM -
AuthCertificatePassword: Palavra-passe do certificado -
AuthTenantID: ID de inquilino Microsoft Entra
Autenticação por Token de Acesso
Melhor para: cenários de autenticação personalizados
// Acquire token through custom mechanism
String accessToken = acquireTokenFromCustomSource();
String url = "jdbc:fabricspark://api.fabric.microsoft.com;" +
"FabricWorkspaceID=<workspace-id>;" +
"FabricLakehouseID=<lakehouse-id>;" +
"AuthFlow=5;" + // Access token authentication
"AuthAccessToken=" + accessToken + ";" +
"LogLevel=INFO";
Connection conn = DriverManager.getConnection(url);
Cache de autenticação
O driver armazena em cache os tokens de autenticação e atualiza-os com base na expiração do token. As propriedades analisadas AuthEnableCaching e AuthCacheTTLMS não controlam este comportamento na versão 2.0.0.
Parâmetros de Configuração
Parâmetros necessários
Estes parâmetros devem estar presentes em cada cadeia de conexão:
| Parâmetro | Tipo | Description | Example |
|---|---|---|---|
FabricWorkspaceID |
Identificador Único Universal (UUID) | Identificador de espaço de trabalho Fabric | <workspace-id> |
FabricLakehouseID |
Identificador Único Universal (UUID) | Identificador de Fabric lakehouse | <lakehouse-id> |
AuthFlow |
Número inteiro | Tipo de fluxo de autenticação (1-5) | 2 |
Parâmetros opcionais
Configuração da Versão API
| Parâmetro | Tipo | Predefinido | Description |
|---|---|---|---|
FabricVersion |
Cordão | v1 |
Versão da API Fabric |
LivyApiVersion |
Cordão | 2023-12-01 |
Versão da API do Livy |
Configuração do ambiente
| Parâmetro | Tipo | Predefinido | Description |
|---|---|---|---|
FabricEnvironmentID |
Identificador Único Universal (UUID) | Nenhum | Identificador de ambiente Fabric para referenciar o item de ambiente para a sessão do Spark |
Configuração de sessões de alta concorrência
Definir hcEnabled=true para usar o modo HC. As restantes propriedades HC são usadas apenas quando o modo HC está ativado.
| Parâmetro | Tipo | Predefinido | Description |
|---|---|---|---|
hcEnabled |
booleano | false |
Utiliza uma sessão Fabric de alta concorrência. |
sessionTag |
Cordão | Nenhum | Etiqueta de sessão opcional no servidor. Use as letras de 1 a 64, dígitos, sublinhados ou hífens. |
hcAcquireTimeoutSeconds |
Número inteiro | 300 |
Tempo máximo para esperar que a sessão de HC esteja pronta. Os valores válidos variam entre 120 e 3.600 segundos. |
hcAcquirePollingIntervalMs |
Número inteiro | 1000 |
Intervalo entre verificações de estado das sessões de HC. Os valores aceites variam de 50 até 30.000 milissegundos e são limitados em tempo de execução a um intervalo de 100 a 5.000 milissegundos. |
Example:
hcEnabled=true;sessionTag=interactive_reporting;hcAcquireTimeoutSeconds=600;hcAcquirePollingIntervalMs=2000;FabricEnvironmentID=<environment-id>
-
FabricEnvironmentIDAplica-se tanto às sessões HC como clássicas -
EnvironmentIDé também aceite como pseudónimo cross-driver. Os nomes das propriedades são indiferentes a maiúsculas minúsculas.
Importante
Use sessionTag apenas para etiquetas operacionais não sensíveis. Não inclua segredos, tokens de acesso, dados pessoais, identificadores de clientes ou texto de consulta.
Consulte a secção Modo de Alta Concorrência (HC) para obter instruções completas para a configuração.
Configuração do Spark
Configuração dos Recursos de Sessão
Configure os recursos da sessão Spark para um desempenho ótimo:
| Parâmetro | Tipo | Predefinido | Description | Example |
|---|---|---|---|---|
DriverCores |
Número inteiro | Spark predefinição | Número de núcleos de CPU para o driver | 4 |
DriverMemory |
Cordão | Spark predefinição | Alocação de memória para o driver | 4g |
ExecutorCores |
Número inteiro | Spark predefinição | Número de núcleos de CPU por executor | 4 |
ExecutorMemory |
Cordão | Spark predefinição | Alocação de memória por executor | 8g |
NumExecutors |
Número inteiro | Spark predefinição | Número de executores | 2 |
SessionName |
Cordão | Gerado automaticamente | Nome de sessão personalizado | MySparkSession |
Example:
DriverCores=4;DriverMemory=4g;ExecutorCores=4;ExecutorMemory=8g;NumExecutors=2; SessionName=MySparkSession
Propriedades Personalizadas da Sessão Spark
Qualquer parâmetro com o prefixo spark. é automaticamente aplicado à sessão Spark:
Exemplos de Configurações do Spark:
spark.sql.adaptive.enabled=true
spark.sql.adaptive.coalescePartitions.enabled=true
spark.sql.shuffle.partitions=200
spark.sql.autoBroadcastJoinThreshold=10485760
spark.dynamicAllocation.enabled=true
spark.dynamicAllocation.minExecutors=1
spark.dynamicAllocation.maxExecutors=10
spark.executor.memoryOverhead=1g
Motor de Execução Nativo (NEE):
spark.nee.enabled=true
Exemplo completo:
jdbc:fabricspark://api.fabric.microsoft.com;FabricWorkspaceID=<guid>;FabricLakehouseID=<guid>;DriverMemory=4g;ExecutorMemory=8g;NumExecutors=2;spark.sql.adaptive.enabled=true;spark.nee.enabled=true;AuthFlow=2
Definições de ligação ao cliente HTTP
Configure as ligações de transporte HTTP do driver para um desempenho de rede ótimo. Estas definições não configuram nem gerem o pooling de ligações JDBC:
| Parâmetro | Tipo | Predefinido | Description |
|---|---|---|---|
HttpMaxTotalConnections |
Número inteiro | 100 | Número máximo total de ligações HTTP |
HttpMaxConnectionsPerRoute |
Número inteiro | 20 | Ligações máximas por rota |
HttpConnectionTimeoutInSeconds |
Número inteiro | 30 | Tempo limite de conexão |
HttpSocketTimeoutInSeconds |
Número inteiro | 60 | Timeout de leitura do socket |
HttpReadTimeoutInSeconds |
Número inteiro | 60 | Tempo limite de leitura HTTP |
HttpConnectionRequestTimeoutSeconds |
Número inteiro | 10 | Pedido de ligação excedeu o tempo limite no pool |
HttpEnableKeepAlive |
booleano | true | Ativar HTTP keep-alive |
HttpKeepAliveTimeoutSeconds |
Número inteiro | 60 | Tempo limite de ligação ativa |
HttpFollowRedirects |
booleano | true | Seguir redirecionamentos HTTP |
HttpUseAsyncIO |
booleano | true | Utilizar E/S HTTP assíncrona |
Example:
HttpMaxTotalConnections=200;HttpMaxConnectionsPerRoute=100;HttpConnectionTimeoutInSeconds=60
Configuração do Proxy
Configure as definições de proxy HTTP e SOCKS para ambientes empresariais:
| Parâmetro | Tipo | Predefinido | Description |
|---|---|---|---|
UseProxy |
booleano | false | Ativar proxy |
ProxyTransport |
Cordão | http |
Tipo de transporte proxy (http/tcp) |
ProxyHost |
Cordão | Nenhum | Nome de host proxy |
ProxyPort |
Número inteiro | Nenhum | Porta proxy |
ProxyAuthEnabled |
booleano | false | Ativar autenticação por proxy |
ProxyUsername |
Cordão | Nenhum | Nome de utilizador de autenticação por proxy |
ProxyPassword |
Cordão | Nenhum | Palavra-passe de autenticação por proxy |
ProxyAuthScheme |
Cordão | basic |
Esquema de autenticação (básico/digest/ntlm) |
ProxySocksVersion |
Número inteiro | 5 | Versão SOCKS (4/5) |
Exemplo de Proxy HTTP:
UseProxy=true;ProxyTransport=http;ProxyHost=proxy.company.com;ProxyPort=8080;ProxyAuthEnabled=true;ProxyUsername=user;ProxyPassword=pass
Exemplo de Proxy SOCKS:
UseProxy=true;ProxyTransport=tcp;ProxyHost=socks.company.com;ProxyPort=1080;ProxySocksVersion=5
Configuração de registro em log
| Parâmetro | Tipo | Predefinido | Description |
|---|---|---|---|
LogLevel |
Cordão | WARN |
Nível de registro: TRACE, DEBUG, INFO, WARN, ERROR |
Example:
LogLevel=DEBUG
Localização do Registo Predefinido:
${user.home}/.microsoft/livy-jdbc-driver/logs/driver.log
Configuração do Log Personalizado: Utilize um ficheiro log4j2.xml ou logback.xml personalizado no teu classpath.
Modo de alta concorrência (HC)
O modo de alta concorrência (HC) foi concebido para aplicações JDBC que abrem múltiplas ligações ao mesmo espaço de trabalho Fabric e lakehouse. Em vez de provisionar uma sessão clássica Spark separada para cada ligação, o Fabric serve essas ligações com capacidade Spark partilhada e gerida pelo servidor.
O modo HC pode reduzir o tempo de arranque da ligação, evitar o provisionamento repetido das sessões Spark e utilizar a capacidade disponível de forma mais eficiente para cargas de trabalho concorrentes. Cada ligação JDBC continua a executar instruções SQL através do respetivo contexto atribuído na sessão HC.
O modo HC é de adesão opcional e complementa o agrupamento de ligações JDBC. O modo HC gere as sessões Fabric Spark no servidor, enquanto o pooling de conexões JDBC gere as ligações na aplicação cliente. Se não ativares o modo HC, o controlador cria uma sessão clássica do Livy.
Escolha entre o modo HC e o modo clássico
Use o modo HC quando:
- Um serviço de aplicações processa pedidos concorrentes que executam Spark SQL através de múltiplas ligações JDBC.
- Uma ferramenta de BI ou de relatórios abre várias ligações ao mesmo espaço de trabalho e à mesma casa do lago.
- Tarefas ETL paralelas ou trabalhos agendados criam rajadas de ligações JDBC.
- As ligações utilizam configurações Spark compatíveis e podem partilhar a capacidade Spark gerida pelo servidor.
- Reduzir o tempo de arranque da ligação e o provisionamento repetido das sessões Spark é importante.
Use o modo clássico quando:
- A sua aplicação utiliza apenas uma ou algumas ligações JDBC de longa duração.
- Cada ligação requer uma sessão Spark dedicada para carga de trabalho rigorosa ou isolamento de recursos.
- As ligações requerem configurações Spark ou ambientes Fabric substancialmente diferentes.
- O ponto final do Fabric Livy para o espaço de trabalho de destino e o armazém de dados não é compatível com o modo HC.
Ativar o modo de alta concorrência
O modo HC é de adesão voluntária. Se omitir hcEnabled ou o definir como false, o controlador utiliza o caminho clássico da sessão Livy. Defina hcEnabled como true para adquirir uma sessão HC:
hcEnabled=true;
Parâmetros necessários no modo HC
A ativação HC requer os seguintes identificadores válidos:
| Parâmetro | Observações |
|---|---|
WorkspaceId |
Tem de ser um GUID válido da área de trabalho do Fabric. |
LakehouseId |
Tem de ser um GUID válido da Fabric lakehouse. |
Inclui SessionTag porque influencia o matching do lado do servidor para sessões quentes.
Associação de sessões
O modo HC não garante que todas as ligações reutilizam uma sessão existente. Para cada solicitação de obtenção de sessão, o controlador envia:
- O valor
SessionTag. - A configuração efetiva do Spark, incluindo as definições de
conf.*eEnvironmentId.
O serviço Fabric Livy avalia estes valores e decide se deve ligar a ligação a uma sessão quente ou criar uma nova sessão. Para melhorar a reutilização da sessão, utilize valores consistentes entre as ligações que pretendam partilhar a capacidade do Spark gerido pelo servidor.
Desativar o modo HC
Pode desativar a obtenção de novas sessões HC sem voltar a implementar o driver, definindo a cadeia de ligação HC para false ou removendo os parâmetros HC:
hcEnabled=false;
Reversões de emergência: Para uma reversão de emergência, inicie a JVM com -Dcom.microsoft.fabric.jdbc.hc.disable=true. Esta opção de toda a JVM força o modo clássico mesmo quando uma cadeia de ligação contém hcEnabled=true.
Compreenda o comportamento em tempo de execução do HC
- A aquisição da sessão HC fica bloqueada até que a sessão esteja pronta ou
hcAcquireTimeoutSecondsexpire. - Fechar uma conexão enquanto a aquisição está em curso interrompe a aquisição e aciona a limpeza da sessão HC na medida do possível.
- Autenticação, execução de consultas, cancelamento, instruções preparadas, tratamento de resultados e
FabricEnvironmentIDfuncionam através das interfaces JDBC padrão em ambos os modos.
Exemplos de uso
Conexão Básica
import java.sql.*;
public class BasicConnectionExample {
public static void main(String[] args) {
String url = "jdbc:fabricspark://api.fabric.microsoft.com;" +
"FabricWorkspaceID=<workspace-id>;" +
"FabricLakehouseID=<lakehouse-id>;" +
"AuthFlow=2";
try (Connection conn = DriverManager.getConnection(url)) {
System.out.println("Connected successfully!");
System.out.println("Database: " + conn.getMetaData().getDatabaseProductName());
System.out.println("Driver: " + conn.getMetaData().getDriverName());
System.out.println("Driver Version: " + conn.getMetaData().getDriverVersion());
} catch (SQLException e) {
System.err.println("Connection failed: " + e.getMessage());
e.printStackTrace();
}
}
}
Conexão em modo de elevada concorrência
O exemplo seguinte abre uma ligação JDBC em modo HC, executa uma consulta e liberta a ligação automaticamente:
String url = "jdbc:fabricspark://api.fabric.microsoft.com;" +
"FabricWorkspaceID=<workspace-id>;" +
"FabricLakehouseID=<lakehouse-id>;" +
"AuthFlow=2;" +
"hcEnabled=true;" +
"sessionTag=dashboard_queries;" +
"FabricEnvironmentID=<environment-id>";
try (Connection conn = DriverManager.getConnection(url);
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT current_timestamp()")) {
while (rs.next()) {
System.out.println(rs.getTimestamp(1));
}
}
Executando consultas
Consulta simples
public void executeSimpleQuery(Connection conn) throws SQLException {
String sql = "SELECT current_timestamp() as now";
try (Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(sql)) {
if (rs.next()) {
Timestamp now = rs.getTimestamp("now");
System.out.println("Current timestamp: " + now);
}
}
}
Consulta com filtro
public void executeQueryWithFilter(Connection conn) throws SQLException {
String sql = "SELECT * FROM sales WHERE amount > 1000 ORDER BY amount DESC";
try (Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(sql)) {
while (rs.next()) {
int id = rs.getInt("id");
double amount = rs.getDouble("amount");
Date date = rs.getDate("sale_date");
System.out.printf("ID: %d, Amount: %.2f, Date: %s%n",
id, amount, date);
}
}
}
Consulta com Limite
public void executeQueryWithLimit(Connection conn) throws SQLException {
String sql = "SELECT * FROM customers LIMIT 10";
try (Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(sql)) {
ResultSetMetaData metaData = rs.getMetaData();
int columnCount = metaData.getColumnCount();
// Print column names
for (int i = 1; i <= columnCount; i++) {
System.out.print(metaData.getColumnName(i) + "\t");
}
System.out.println();
// Print rows
while (rs.next()) {
for (int i = 1; i <= columnCount; i++) {
System.out.print(rs.getString(i) + "\t");
}
System.out.println();
}
}
}
Trabalhar com Conjuntos de Resultados
Percorrer conjuntos de resultados
public void navigateResultSet(Connection conn) throws SQLException {
String sql = "SELECT id, name, amount FROM orders";
try (Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(sql)) {
while (rs.next()) {
System.out.printf(
"Order %d: %s, %.2f%n",
rs.getInt("id"),
rs.getString("name"),
rs.getDouble("amount"));
}
}
}
Os conjuntos de resultados são apenas para a frente e só de leitura. O driver não suporta métodos como first(), last(), e absolute().
Processamento de Grandes Conjuntos de Resultados
O driver pagina os resultados pelo tamanho da resposta. Configure LivyStatementPageSize no URL JDBC para definir o tamanho da página solicitado em bytes. O Statement.setFetchSize() método não controla a recuperação nem o uso de memória.
jdbc:fabricspark://api.fabric.microsoft.com;FabricWorkspaceID=<workspace-id>;FabricLakehouseID=<lakehouse-id>;AuthFlow=2;LivyStatementPageSize=1048576
public void processLargeResultSet(Connection conn) throws SQLException {
String sql = "SELECT * FROM large_table";
try (Statement stmt = conn.createStatement()) {
try (ResultSet rs = stmt.executeQuery(sql)) {
int rowCount = 0;
while (rs.next()) {
// Process row
processRow(rs);
rowCount++;
if (rowCount % 10000 == 0) {
System.out.println("Processed " + rowCount + " rows");
}
}
System.out.println("Total rows processed: " + rowCount);
}
}
}
private void processRow(ResultSet rs) throws SQLException {
// Process individual row
}
Utilização de Declarações Preparadas
public void usePreparedStatement(Connection conn) throws SQLException {
String sql = "SELECT * FROM products WHERE category = ? AND price > ?";
try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
// Set parameters
pstmt.setString(1, "Electronics");
pstmt.setDouble(2, 100.0);
try (ResultSet rs = pstmt.executeQuery()) {
while (rs.next()) {
String name = rs.getString("name");
double price = rs.getDouble("price");
System.out.printf("Product: %s, Price: $%.2f%n", name, price);
}
}
}
}
Operações em Lote
O driver não suporta transações JDBC. A execução em lote não é transacional e pode ter sucesso parcial. Uma falha posterior não reverte declarações anteriores bem-sucedidas.
public void executeBatchInsert(Connection conn) throws SQLException {
String sql = "INSERT INTO logs (timestamp, level, message) VALUES (?, ?, ?)";
int pendingStatements = 0;
try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
// Add multiple statements to batch
for (int i = 0; i < 1000; i++) {
pstmt.setTimestamp(1, new Timestamp(System.currentTimeMillis()));
pstmt.setString(2, "INFO");
pstmt.setString(3, "Log message " + i);
pstmt.addBatch();
pendingStatements++;
// Execute batch every 100 statements
if ((i + 1) % 100 == 0) {
pstmt.executeBatch();
pstmt.clearBatch();
pendingStatements = 0;
}
}
if (pendingStatements > 0) {
pstmt.executeBatch();
}
System.out.println("Batch insert completed successfully");
}
}
Escolha um proprietário de ligação
Escolha um componente para dominar o ciclo de vida da ligação. Não coloque um pool de ligação dentro de outro.
| Modelo de utilização | Ponto de entrada | Proprietário da piscina | Fechar um empréstimo Connection |
Responsável pelo desligamento |
|---|---|---|---|---|
| Direct |
DriverManager, LivyDriver ou LivyDataSource |
Nenhum | Fecha fisicamente a sua ligação Livy independente e sessão. | A aplicação fecha todas as ligações. Um direto LivyDataSource não tem um ciclo de vida próximo separado. |
| HikariCP Externo |
HikariDataSource apoiado por um URL JDBC ou LivyDataSource |
Apenas HikariCP | Devolve a ligação proxy do Hikari ao HikariCP. | A aplicação fecha os seus itens retidos HikariDataSource. |
| Pool explícito incorporado | LivyBuiltInPooledDataSource |
Uma criada LivyConnectionPool preguiçosamente para cada geração de fonte de dados configurada |
Cancela o contrato lógico e só reutiliza a sessão física após uma limpeza segura. | A aplicação fecha a sua fonte de dados incorporada retida. |
| SPI de agrupamento padrão |
LivyConnectionPoolDataSource cria PooledConnection objetos para um gestor de pools de nível intermédio |
O gestor de pool de nível intermédio, não a fábrica | Fecha o handle lógico e notifica sincronizadamente o gestor após a limpeza. | O gestor chama PooledConnection.close() para destruir cada ligação física. |
ConnectionPoolEnabled tem como valor por predefinição false tanto no código do controlador como nos ficheiros de propriedades distribuídos. Não é um interruptor opt-in para os pontos de entrada atuais. Utilize LivyBuiltInPooledDataSource quando o driver deverá gerir o pool, ou configure um pool externo, como o HikariCP. Os outros pontos de entrada criam ligações diretas, não proprietárias do pool.
Partilha de ligações com o HikariCP
O HikariCP pode criar ligações a partir de LivyDataSource ou do URL JDBC através de LivyDriver. Crie uma instância HikariCP, reutilize-a durante a vida útil da aplicação e use apenas um pool de ligação em cada configuração.
Dependência de Maven
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<version>5.0.1</version>
</dependency>
Utilize LivyDataSource
LivyDataSource cria ligações físicas independentes e não possui um pool de ligações nem um ciclo de vida próximo separado. Forneça diretamente à HikariCP para que a HikariCP seja a única proprietária da piscina:
import com.microsoft.spark.livy.jdbc.LivyDataSource;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public final class ConnectionPoolExample implements AutoCloseable {
private final HikariDataSource hikariDataSource;
public ConnectionPoolExample(String url) {
LivyDataSource configuredDataSource = new LivyDataSource();
configuredDataSource.setUrl(url);
HikariConfig config = new HikariConfig();
config.setDataSource(configuredDataSource);
config.setMaximumPoolSize(2);
config.setMinimumIdle(0);
config.setConnectionTimeout(900000); // Wait up to 15 minutes for a connection
config.setInitializationFailTimeout(-1); // Connect on demand
config.setIdleTimeout(600000); // 10 minutes
config.setMaxLifetime(1800000); // 30 minutes
config.setPoolName("FabricSparkPool");
hikariDataSource = new HikariDataSource(config);
}
public Connection getConnection() throws SQLException {
return hikariDataSource.getConnection();
}
@Override
public void close() {
hikariDataSource.close();
}
public static void main(String[] args) throws SQLException {
String url = "jdbc:fabricspark://api.fabric.microsoft.com;" +
"FabricWorkspaceID=<workspace-id>;" +
"FabricLakehouseID=<lakehouse-id>;" +
"AuthFlow=AZURE_CLI;" +
"hcEnabled=true;" +
"sessionTag=pooled_app;" +
"hcAcquireTimeoutSeconds=600";
try (ConnectionPoolExample pool = new ConnectionPoolExample(url);
Connection conn = pool.getConnection();
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT 'Pooled connection!' as message")) {
if (rs.next()) {
System.out.println(rs.getString("message"));
}
}
}
}
O exemplo ativa o modo HC no URL do JDBC. O HikariCP gere as ligações do lado do cliente, enquanto o modo HC gere sessões Spark partilhadas no Fabric. Remover hcEnabled e sessionTag se a aplicação exigir sessões clássicas.
Utilizar LivyDriver diretamente
Configure a URL JDBC e a classe do driver para que o HikariCP crie ligações físicas através de LivyDriver. Definir de forma explícita a classe do controlador é opcional quando a deteção automática do fornecedor de serviços JDBC está disponível. Esta configuração não instancia LivyDataSource, por isso o seu pool integrado não é utilizado:
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public final class DriverConnectionPoolExample {
public static HikariDataSource createPool(String url) {
HikariConfig config = new HikariConfig();
config.setDriverClassName("com.microsoft.spark.livy.jdbc.LivyDriver");
config.setJdbcUrl(url);
// Keep pool sizes small: each classic-mode physical connection owns a Livy session.
config.setMaximumPoolSize(2);
config.setMinimumIdle(0);
config.setConnectionTimeout(900000); // Wait up to 15 minutes to borrow a connection
config.setInitializationFailTimeout(-1); // Skip startup validation; connect on demand
config.setIdleTimeout(600000); // 10 minutes
config.setMaxLifetime(1800000); // 30 minutes
config.setPoolName("FabricSparkDriverPool");
return new HikariDataSource(config);
}
public static void main(String[] args) throws SQLException {
String url = "jdbc:fabricspark://api.fabric.microsoft.com;" +
"FabricWorkspaceID=<workspace-id>;" +
"FabricLakehouseID=<lakehouse-id>;" +
"AuthFlow=AZURE_CLI;" + // Uses the DefaultAzureCredential chain
"hcEnabled=true;" +
"sessionTag=pooled_app;" +
"hcAcquireTimeoutSeconds=600"; // Poll up to 10 minutes for HC readiness
// Reuse this pool for the application lifetime; main closes it at process exit.
try (HikariDataSource pool = createPool(url);
Connection conn = pool.getConnection();
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT 'Pooled LivyDriver connection!' as message")) {
if (rs.next()) {
System.out.println(rs.getString("message"));
}
}
}
}
Use as seguintes orientações ao configurar o pool:
| Ambiente ou comportamento | Guidance |
|---|---|
| Propriedade do pool |
LivyDataSource é apenas de acesso direto. Quando o forneces ao HikariCP, o HikariCP é o dono do pool. Use-o LivyBuiltInPooledDataSource em vez disso quando o condutor deveria ser dono da piscina. |
| Tamanho da piscina | Comece com um pool pequeno e aumente-o apenas depois de medir a concorrência da carga de trabalho e o uso de capacidade. No modo clássico, cada ligação física possui a sua própria sessão Livy. No modo HC, as ligações podem partilhar a capacidade Spark gerida pelo servidor. |
connectionTimeout |
Controla quanto tempo um chamador espera para pedir emprestada uma ligação, mas não cancela uma tentativa de ligação já em andamento. Para URLs HC, permita hcAcquireTimeoutSeconds; para o modo clássico, permita LivySessionTimeoutSeconds, autenticação, tentativas HTTP e validação. O HikariCP expressa esta definição em milissegundos. |
initializationFailTimeout |
Um valor negativo ignora a ligação inicial e a tentativa de validação. Falhas de conectividade surgem quando a aplicação solicita pela primeira vez uma ligação. Use um valor positivo se a aplicação tiver de verificar a conectividade durante o arranque. |
| Validação de ligação | O HikariCP utiliza Connection.isValid(). A sua duração efetiva é controlada pelas definições de timeout HTTP e de retentativa/backoff do driver, e não pelo validationTimeout do HikariCP. Não configure uma consulta de teste de ligação porque substitui a verificação de validação mais leve por uma instrução Spark. |
Para a lista completa de opções de configuração do HikariCP, veja:
Mapeamento de Tipos de Dados
O driver mapeia os tipos de dados SQL do Spark para tipos SQL JDBC e tipos Java:
| Tipo SQL Spark | Tipo SQL JDBC | Tipo Java | Observações |
|---|---|---|---|
BOOLEAN |
BOOLEAN |
Boolean |
|
BYTE |
TINYINT |
Byte |
|
SHORT |
SMALLINT |
Short |
|
INT |
INTEGER |
Integer |
|
LONG |
BIGINT |
Long |
|
FLOAT |
FLOAT |
Float |
|
DOUBLE |
DOUBLE |
Double |
|
DECIMAL |
DECIMAL |
BigDecimal |
Precisão e escala preservadas |
STRING |
VARCHAR |
String |
|
VARCHAR(n) |
VARCHAR |
String |
|
CHAR(n) |
CHAR |
String |
|
BINARY |
BINARY |
byte[] |
|
DATE |
DATE |
java.sql.Date |
|
TIMESTAMP |
TIMESTAMP |
java.sql.Timestamp |
|
ARRAY |
ARRAY |
String |
Recuperado como texto JSON; o tipo de metadados não garante suporte completo java.sql.Array aos acessores |
MAP |
JAVA_OBJECT |
String |
Consultado como texto JSON |
STRUCT |
STRUCT |
String |
Recuperado como texto JSON; o tipo de metadados não garante suporte completo java.sql.Struct aos acessores |