Compartir a través de


Controlador JDBC de Microsoft para ingeniería de datos de Microsoft Fabric (versión preliminar)

Nota:

Esta característica se encuentra en versión preliminar.

JDBC (Conectividad de bases de datos java) es un estándar ampliamente adoptado que permite a las aplicaciones cliente conectarse a datos de bases de datos y plataformas de macrodatos y trabajar con ellos.

Microsoft JDBC Driver for Fabric Data Engineering le permite conectarse, consultar y administrar cargas de trabajo de Spark en Microsoft Fabric con la confiabilidad y simplicidad del estándar JDBC. Basado en las API de Livy de Microsoft Fabric, el controlador proporciona conectividad de Spark SQL segura y flexible a las aplicaciones java y las herramientas de BI. Esta integración le permite enviar y ejecutar código Spark directamente sin necesidad de crear artefactos independientes como notebooks o definiciones de trabajos de Spark.

Características clave

  • Compatible con JDBC 4.2: implementación completa de la especificación JDBC 4.2
  • Autenticación de Id. de Entra de Microsoft: varios flujos de autenticación, como las credenciales interactivas, las credenciales de cliente y la autenticación basada en certificados
  • Agrupación de conexiones empresariales: agrupación de conexiones integrada con supervisión de estado y recuperación automática
  • Compatibilidad con consultas nativas de Spark SQL: ejecución directa de instrucciones SQL de Spark sin traducción
  • Compatibilidad completa con tipos de datos: compatibilidad con todos los tipos de datos de Spark SQL, incluidos tipos complejos (ARRAY, MAP, STRUCT)
  • Captura previa del conjunto de resultados asincrónico: carga de datos en segundo plano para mejorar el rendimiento
  • Patrón Circuit Breaker: Protección contra errores en cascada con reintento automático
  • Reconexión automática: recuperación de sesión transparente en errores de conexión
  • Compatibilidad con proxy: configuración de proxy HTTP y SOCKS para entornos empresariales

Prerrequisitos

Antes de usar Microsoft JDBC Driver for Microsoft Fabric Data Engineering, asegúrese de que tiene:

  • Kit de desarrollo de Java (JDK):versión 11 o posterior (se recomienda Java 21)
  • Microsoft Fabric Access: acceso a un área de trabajo de Microsoft Fabric
  • Credenciales de id. de Azure Entra: credenciales adecuadas para la autenticación
  • Identificadores de área de trabajo y Lakehouse: identificadores GUID para tu área de trabajo de Fabric y Lakehouse

Descarga e instalación

Microsoft JDBC Driver for Microsoft Fabric Data Engineering versión 1.0.0 es la versión preliminar pública y admite Java 11, 17 y 21. Estamos mejorando continuamente la compatibilidad con la conectividad de Java y le recomendamos que trabaje con la versión más reciente del controlador JDBC de Microsoft.

  1. Descargue el archivo zip o tar de los vínculos anteriores.
  2. Extraiga el archivo descargado para acceder a los archivos JAR del controlador.
  3. Seleccione el archivo JAR que coincida con la versión de JRE:
    • Para Java 11: ms-sparksql-jdbc-1.0.0.jre11.jar
    • Para Java 17: ms-sparksql-jdbc-1.0.0.jre17.jar
    • Para Java 21: ms-sparksql-jdbc-1.0.0.jre21.jar
  4. Agregue el archivo JAR seleccionado a la ruta de clase de la aplicación.
  5. Para los clientes JDBC, configure la clase de controlador JDBC: com.microsoft.spark.livy.jdbc.LivyDriver

Ejemplo de inicio rápido

En este ejemplo se muestra cómo conectarse a Microsoft Fabric y ejecutar una consulta mediante microsoft JDBC Driver for Microsoft Fabric Data Engineering. Antes de ejecutar este código, asegúrese de que ha completado los requisitos previos e instalado el controlador.

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;" +  // Interactive browser authentication
                     "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 cadena de conexión

Cadena de conexión básica

Microsoft JDBC Driver for Microsoft Fabric Data Engineering usa el siguiente formato de cadena de conexión:

jdbc:fabricspark://<hostname>[:<port>][;<parameter1>=<value1>;<parameter2>=<value2>;...]

Componentes de cadena de conexión

Componente Description Example
Protocolo Identificador del protocolo de dirección URL de JDBC jdbc:fabricspark://
Nombre de host Nombre de host del punto de conexión de Microsoft Fabric api.fabric.microsoft.com
Puerto Número de puerto opcional (valor predeterminado: 443) :443
Parámetros Pares clave=valor separados por punto y coma FabricWorkspaceID=<guid>

Cadenas de conexión de ejemplo

Conexión básica (autenticación interactiva)

jdbc:fabricspark://api.fabric.microsoft.com;FabricWorkspaceID=<workspace-id>;FabricLakehouseID=<lakehouse-id>;AuthFlow=2

Con la configuración de recursos de 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

Con las propiedades de la sesión de 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

Autenticación

Microsoft JDBC Driver for Microsoft Fabric Data Engineering admite varios métodos de autenticación a través de Microsoft Entra ID (anteriormente Azure Active Directory). La autenticación se configura mediante el AuthFlow parámetro en la cadena de conexión.

Flujos de autenticación

AuthFlow Método de autenticación Caso de uso
0 Credencial de la CLI de Azure Desarrollo mediante la CLI de Azure
1 Credenciales de cliente (Principal del servicio) Autenticación automatizada o de servicio a servicio
2 Explorador interactivo Autenticación interactiva de usuarios (valor predeterminado)
3 SPN Autenticación de la entidad de servicio
4 Basado en certificados Autenticación de entidad de servicio basada en certificados
5 Token de acceso Token de acceso adquirido previamente

Autenticación interactiva del explorador

Ideal para: Desarrollo e aplicaciones interactivas

String url = "jdbc:fabricspark://api.fabric.microsoft.com;" +
             "FabricWorkspaceID=<workspace-id>;" +
             "FabricLakehouseID=<lakehouse-id>;" +
             "AuthFlow=2;" +  // Interactive browser authentication
             "AuthTenantID=<tenant-id>;" +  // Optional
             "LogLevel=INFO";

Connection conn = DriverManager.getConnection(url);

Parámetros:

  • AuthFlow=2: especifica la autenticación interactiva del explorador.
  • AuthTenantID (opcional): Identificador de inquilino de Azure
  • AuthClientID (opcional): Id. de aplicación (cliente)

Comportamiento:

  • Abre una ventana del explorador para la autenticación de usuario
  • Las credenciales se almacenan en caché para las conexiones posteriores hasta que expiran.
  • Adecuado para aplicaciones de usuario único

Autenticación de credenciales de cliente

Mejor para: Servicios automatizados y trabajos en segundo plano

String url = "jdbc:fabricspark://api.fabric.microsoft.com;" +
             "FabricWorkspaceID=<workspace-id>;" +
             "FabricLakehouseID=<lakehouse-id>;" +
             "AuthFlow=1;" +  // Client credentials authentication
             "AuthClientID=<client-id>;" +
             "AuthClientSecret=<client-secret>;" +
             "AuthTenantID=<tenant-id>;" +
             "LogLevel=INFO";

Connection conn = DriverManager.getConnection(url);

Parámetros necesarios:

  • AuthFlow=1: especifica la autenticación de credenciales de cliente.
  • AuthClientID: ID de aplicación (cliente) de Microsoft Entra ID
  • AuthClientSecret: secreto de cliente de Microsoft Entra ID
  • AuthTenantID: identificador de inquilino de Azure

Procedimientos recomendados:

  • Almacenamiento de secretos de forma segura (Azure Key Vault, variables de entorno)
  • Uso de identidades administradas siempre que sea posible
  • Rotación periódica de secretos

Autenticación basada en certificados

Mejor para: Aplicaciones empresariales que requieren autenticación basada en certificados

String url = "jdbc:fabricspark://api.fabric.microsoft.com;" +
             "FabricWorkspaceID=<workspace-id>;" +
             "FabricLakehouseID=<lakehouse-id>;" +
             "AuthFlow=4;" +  // Certificate-based authentication
             "AuthClientID=<client-id>;" +
             "AuthCertificatePath=/path/to/certificate.pfx;" +
             "AuthCertificatePassword=<certificate-password>;" +
             "AuthTenantID=<tenant-id>;" +
             "LogLevel=INFO";

Connection conn = DriverManager.getConnection(url);

Parámetros necesarios:

  • AuthFlow=4: especifica la autenticación basada en certificados.
  • AuthClientID: ID de aplicación (cliente)
  • AuthCertificatePath: ruta de acceso al archivo de certificado PFX/PKCS12
  • AuthCertificatePassword: contraseña de certificado
  • AuthTenantID: identificador de inquilino de Azure

Autenticación de la entidad de servicio

Mejor para: Entornos sin interfaz gráfica y sesiones remotas

String url = "jdbc:fabricspark://api.fabric.microsoft.com;" +
             "FabricWorkspaceID=<workspace-id>;" +
             "FabricLakehouseID=<lakehouse-id>;" +
             "AuthFlow=3;" +  // Device code authentication
             "AuthClientID=<client-id>;" +
             "AuthTenantID=<tenant-id>;" +
             "LogLevel=INFO";

Connection conn = DriverManager.getConnection(url);

Comportamiento:

  • Muestra un código de dispositivo y una dirección URL en la consola
  • El usuario visita la dirección URL y escribe el código.
  • La autenticación se completa después de la comprobación del usuario

Autenticación de token de acceso

Mejor para: Escenarios de autenticación 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);

Almacenamiento en caché de autenticación

El controlador almacena automáticamente en caché los tokens de autenticación para mejorar el rendimiento:

// Enable/disable caching (enabled by default)
String url = "jdbc:fabricspark://api.fabric.microsoft.com;" +
             "FabricWorkspaceID=<workspace-id>;" +
             "FabricLakehouseID=<lakehouse-id>;" +
             "AuthFlow=2;" +
             "AuthEnableCaching=true;" +  // Enable token caching
             "AuthCacheTTLMS=3600000";    // Cache TTL: 1 hour

Connection conn = DriverManager.getConnection(url);

Parámetros de configuración

Parámetros requeridos

Estos parámetros deben estar presentes en cada cadena de conexión:

Parámetro Tipo Description Example
FabricWorkspaceID Identificador Único Universal (UUID) Identificador del área de trabajo de Microsoft Fabric <workspace-id>
FabricLakehouseID Identificador Único Universal (UUID) Identificador de lakehouse de Microsoft Fabric <lakehouse-id>
AuthFlow Integer Tipo de flujo de autenticación (0-5) 2

Parámetros opcionales

Configuración de la versión de API

Parámetro Tipo Predeterminado Description
FabricVersion String v1 Versión de la API de Microsoft Fabric
LivyApiVersion String 2023-12-01 Versión de livy API

Configuración del entorno

Parámetro Tipo Predeterminado Description
FabricEnvironmentID Identificador Único Universal (UUID) Ninguno Identificador de entorno de Fabric para hacer referencia al elemento de entorno para la sesión de Spark

Configuración de Spark

Configuración de recursos de sesión

Configure los recursos de sesión de Spark para obtener un rendimiento óptimo:

Parámetro Tipo Predeterminado Description Example
DriverCores Integer Valor predeterminado de Spark Número de núcleos de CPU para el controlador 4
DriverMemory String Valor predeterminado de Spark Asignación de memoria para el controlador 4g
ExecutorCores Integer Valor predeterminado de Spark Número de núcleos de CPU por ejecutor 4
ExecutorMemory String Valor predeterminado de Spark Asignación de memoria por ejecutor 8g
NumExecutors Integer Valor predeterminado de Spark Número de ejecutores 2

Example:

DriverCores=4;DriverMemory=4g;ExecutorCores=4;ExecutorMemory=8g;NumExecutors=2

Propiedades personalizadas de la sesión de Spark

Cualquier parámetro con el prefijo spark. se aplica automáticamente a la sesión de Spark:

Configuraciones de Spark de ejemplo:

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 ejecución nativo (NEE):

spark.nee.enabled=true

Ejemplo 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

Configuración del grupo de conexiones HTTP

Configure la agrupación de conexiones HTTP para obtener un rendimiento de red óptimo:

Parámetro Tipo Predeterminado Description
HttpMaxTotalConnections Integer 100 Número máximo de conexiones HTTP totales
HttpMaxConnectionsPerRoute Integer 50 Número máximo de conexiones por ruta
HttpConnectionTimeoutInSeconds Integer 30 Tiempo de espera de conexión
HttpSocketTimeoutInSeconds Integer 60 Tiempo de espera de lectura del socket
HttpReadTimeoutInSeconds Integer 60 Tiempo de espera de lectura HTTP
HttpConnectionRequestTimeoutSeconds Integer 30 Tiempo de espera de solicitud de conexión del grupo
HttpEnableKeepAlive Boolean true Habilitación de HTTP keep-alive
HttpKeepAliveTimeoutSeconds Integer 60 Tiempo de espera de mantenimiento activo
HttpFollowRedirects Boolean true Seguimiento de redirecciones HTTP
HttpUseAsyncIO Boolean false Uso de E/S HTTP asincrónica

Example:

HttpMaxTotalConnections=200;HttpMaxConnectionsPerRoute=100;HttpConnectionTimeoutInSeconds=60

Configuración del proxy

Configure las opciones de proxy HTTP y SOCKS para entornos empresariales:

Parámetro Tipo Predeterminado Description
UseProxy Boolean false Habilitación del proxy
ProxyTransport String http Tipo de transporte de proxy (http/tcp)
ProxyHost String Ninguno Nombre de host del proxy
ProxyPort Integer Ninguno Puerto de proxy
ProxyAuthEnabled Boolean false Habilitación de la autenticación de proxy
ProxyUsername String Ninguno Nombre de usuario de autenticación de proxy
ProxyPassword String Ninguno Contraseña de autenticación de proxy
ProxyAuthScheme String basic Esquema de autenticación (basic/digest/ntlm)
ProxySocksVersion Integer 5 Versión SOCKS (4/5)

Ejemplo de proxy HTTP:

UseProxy=true;ProxyTransport=http;ProxyHost=proxy.company.com;ProxyPort=8080;ProxyAuthEnabled=true;ProxyUsername=user;ProxyPassword=pass

Ejemplo de proxy SOCKS:

UseProxy=true;ProxyTransport=tcp;ProxyHost=socks.company.com;ProxyPort=1080;ProxySocksVersion=5

Configuración de registro

Parámetro Tipo Predeterminado Description
LogLevel String INFO Nivel de registro: TRACE (RASTRO), DEBUG (DEPURACIÓN), INFO (INFORMACIÓN), WARN (ADVERTENCIA), ERROR (ERROR)

Example:

LogLevel=DEBUG

Ubicación de registro predeterminada:

${user.home}/.microsoft/livy-jdbc-driver/driver.log

Configuración de registro personalizada: Use un archivo log4j2.xml o logback.xml personalizado en su ruta de clase.


Ejemplos de uso

Conexión 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();
        }
    }
}

Ejecución de consultas

Consulta simple

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 con 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 con límite

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();
        }
    }
}

Trabajar con conjuntos de resultados

public void navigateResultSet(Connection conn) throws SQLException {
    String sql = "SELECT id, name, amount FROM orders";
    
    try (Statement stmt = conn.createStatement(
            ResultSet.TYPE_SCROLL_INSENSITIVE,
            ResultSet.CONCUR_READ_ONLY);
         ResultSet rs = stmt.executeQuery(sql)) {
        
        // Move to first row
        if (rs.first()) {
            System.out.println("First row: " + rs.getString("name"));
        }
        
        // Move to last row
        if (rs.last()) {
            System.out.println("Last row: " + rs.getString("name"));
            System.out.println("Total rows: " + rs.getRow());
        }
        
        // Move to specific row
        if (rs.absolute(5)) {
            System.out.println("Row 5: " + rs.getString("name"));
        }
    }
}

Procesamiento de grandes conjuntos de resultados

public void processLargeResultSet(Connection conn) throws SQLException {
    String sql = "SELECT * FROM large_table";
    
    try (Statement stmt = conn.createStatement()) {
        // Set fetch size for efficient memory usage
        stmt.setFetchSize(1000);
        
        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
}

Uso de instrucciones 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);
            }
        }
    }
}

Operaciones por lotes

public void executeBatchInsert(Connection conn) throws SQLException {
    String sql = "INSERT INTO logs (timestamp, level, message) VALUES (?, ?, ?)";
    
    try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
        conn.setAutoCommit(false);  // Disable auto-commit for batch
        
        // 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();
            
            // Execute batch every 100 statements
            if (i % 100 == 0) {
                pstmt.executeBatch();
                pstmt.clearBatch();
            }
        }
        
        // Execute remaining statements
        pstmt.executeBatch();
        conn.commit();
        
        System.out.println("Batch insert completed successfully");
    } catch (SQLException e) {
        conn.rollback();
        throw e;
    } finally {
        conn.setAutoCommit(true);
    }
}

Asignación de tipos de datos

El controlador asigna los tipos de datos de Spark SQL a los tipos sql de JDBC y a los tipos de Java:

Tipo de SQL de Spark Tipo de SQL JDBC Tipo de Java Notas
BOOLEAN BOOLEAN Boolean
BYTE TINYINT Byte
SHORT SMALLINT Short
INT INTEGER Integer
LONG BIGINT Long
FLOAT FLOAT Float
DOUBLE DOUBLE Double
DECIMAL DECIMAL BigDecimal Precisión y escala conservadas
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 VARCHAR String Serializado como JSON
MAP VARCHAR String Serializado como JSON
STRUCT VARCHAR String Serializado como JSON