sqlserver - Spark No se puede encontrar el controlador JDBC
microsoft jdbc driver java 6 (10)
Agrego el archivo jar a SPARK_CLASSPATH en spark-env.sh, funciona.
export SPARK_CLASSPATH=$SPARK_CLASSPATH:/local/spark-1.6.3-bin-hadoop2.6/lib/mysql-connector-java-5.1.40-bin.jar
Así que he estado usando sbt con ensamblaje para empaquetar todas mis dependencias en un solo contenedor para mis trabajos de chispa.
Tengo varios trabajos en los que estaba usando
c3p0
para configurar la información del grupo de conexiones, transmitirla y luego usar
foreachPartition
en el RDD para luego tomar una conexión e insertar los datos en la base de datos.
En mi script de compilación sbt, incluyo
"mysql" % "mysql-connector-java" % "5.1.33"
Esto asegura que el conector JDBC esté empaquetado con el trabajo. Todo funciona muy bien.
Así que recientemente comencé a jugar con SparkSQL y me di cuenta de que es mucho más fácil simplemente tomar un marco de datos y guardarlo en una fuente jdbc con las nuevas características en
1.3.0
Recibo la siguiente excepción:
java.sql.SQLException: No se encontró un controlador adecuado para jdbc: mysql: //some.domain.com/myschema? user = user & password = password en java.sql.DriverManager.getConnection (DriverManager.java:596) en java.sql. DriverManager.getConnection (DriverManager.java:233)
Cuando estaba ejecutando esto localmente, lo solucioné configurando
SPARK_CLASSPATH=/path/where/mysql-connector-is.jar
En última instancia, lo que quiero saber es, ¿por qué el trabajo no es capaz de encontrar el controlador cuando debería empaquetarse con él?
Mis otros trabajos nunca tuvieron este problema.
Por lo que puedo decir, tanto
c3p0
como el código del marco de datos hacen uso del
java.sql.DriverManager
(que maneja la importación de todo por lo que puedo decir), ¿entonces debería funcionar bien?
Si hay algo que impide que el método de ensamblaje funcione, ¿qué debo hacer para que esto funcione?
Con spark 2.2.0, el problema se corrigió para mí al agregar información de ruta de clase adicional para la sesión SparkSession en el script de Python:
spark = SparkSession /
.builder /
.appName("Python Spark SQL basic example") /
.config("spark.driver.extraClassPath", "/path/to/jdbc/driver/postgresql-42.1.4.jar") /
.getOrCreate()
Consulte la documentación oficial https://spark.apache.org/docs/latest/configuration.html
En mi caso, spark no se inicia desde el comando cli, sino desde django framework https://www.djangoproject.com/
Esta persona tenía un problema similar: http://apache-spark-user-list.1001560.n3.nabble.com/How-to-use-DataFrame-with-MySQL-td22178.html
¿Ha actualizado sus controladores de conector a la versión más reciente? ¿También especificó la clase de controlador cuando llamó a load ()?
Map<String, String> options = new HashMap<String, String>();
options.put("url", "jdbc:mysql://localhost:3306/video_rcmd?user=root&password=123456");
options.put("dbtable", "video");
options.put("driver", "com.mysql.cj.jdbc.Driver"); //here
DataFrame jdbcDF = sqlContext.load("jdbc", options);
En spark / conf / spark-defaults.conf, también puede establecer spark.driver.extraClassPath y spark.executor.extraClassPath en la ruta de su controlador MySql .jar
Estaba enfrentando el mismo problema cuando intentaba ejecutar el comando spark-shell desde mi máquina Windows. La ruta que pasa por la ubicación del controlador, así como por el jar que usaría, debe estar entre comillas dobles; de lo contrario, se malinterpretará y no obtendrá el resultado exacto que desea.
también debería instalar el controlador JDBC para el servidor SQL desde el enlace: Controlador JDBC
He utilizado el siguiente comando para que esto funcione bien en mi máquina Windows:
spark-shell --driver-class-path "C: / Archivos de programa / Microsoft JDBC Driver 6.0 para SQL Server / sqljdbc_6.0 / enu / jre8 / sqljdbc42.jar" --jars "C: / Archivos de programa / Microsoft JDBC Driver 6.0 para SQL Server / sqljdbc_6.0 / enu / jre8 / sqljdbc42.jar "
Estas opciones se mencionan claramente en
spark docs
:
--driver-class-path postgresql-9.4.1207.jar --jars postgresql-9.4.1207.jar
El error que estaba cometiendo fue mencionar estas opciones después del jar de mi aplicación.
Sin embargo, la forma correcta es especificar estas opciones inmediatamente después del envío de chispa:
spark-submit --driver-class-path /somepath/project/mysql-connector-java-5.1.30-bin.jar --jars /somepath/project/mysql-connector-java-5.1.30-bin.jar --class com.package.MyClass target/scala-2.11/project_2.11-1.0.jar
Existe un simple truco de Java para resolver su problema.
Debe especificar la instancia de
Class.forName()
.
Por ejemplo:
val customers: RDD[(Int, String)] = new JdbcRDD(sc, () => {
Class.forName("com.mysql.jdbc.Driver")
DriverManager.getConnection(jdbcUrl)
},
"SELECT id, name from customer WHERE ? < id and id <= ?" ,
0, range, partitions, r => (r.getInt(1), r.getString(2)))
Consulta los docs
Tanto el controlador de chispa como el ejecutor necesitan un controlador mysql en la ruta de clase, así que especifique
spark.driver.extraClassPath = <path>/mysql-connector-java-5.1.36.jar
spark.executor.extraClassPath = <path>/mysql-connector-java-5.1.36.jar
Tuve el mismo problema al ejecutar trabajos en un clúster de Mesos en modo de clúster.
Para usar un controlador JDBC es necesario agregar la dependencia al classpath del sistema, no al classpath del framework.
Solo encontré la forma de hacerlo agregando la dependencia en el archivo
spark-defaults.conf
en cada instancia del clúster.
Las propiedades para agregar son
spark.driver.extraClassPath
y
spark.executor.extraClassPath
y la ruta debe estar en el sistema de archivos local.
Una forma simple y sencilla es copiar " mysql-connector-java-5.1.47.jar " en el directorio "spark-2.4.3 / jars /"
spark.driver.extraClassPath no funciona en modo cliente:
Nota: En modo cliente, esta configuración no debe establecerse a través de SparkConf directamente en su aplicación, porque el controlador JVM ya se inició en ese punto. En su lugar, configúrelo a través de la opción de línea de comando --driver-class-path o en su archivo de propiedades predeterminado.
La variable Env SPARK_CLASSPATH ha quedado en desuso en Spark 1.0+.
Primero debe copiar los archivos jar del controlador jdbc en cada ejecutor bajo la misma ruta del sistema de archivos local y luego usar las siguientes opciones en su envío de chispa:
--driver-class-path "driver_local_file_system_jdbc_driver1.jar:driver_local_file_system_jdbc_driver2.jar"
--class "spark.executor.extraClassPath=executors_local_file_system_jdbc_driver1.jar:executors_local_file_system_jdbc_driver2.jar"
Por ejemplo, en el caso de TeraData, necesita tanto terajdbc4.jar como tdgssconfig.jar.
Alternativamente, modifique compute_classpath.sh en todos los nodos de trabajo, la documentación de Spark dice:
La clase de controlador JDBC debe ser visible para el cargador de clases primordial en la sesión del cliente y en todos los ejecutores. Esto se debe a que la clase DriverManager de Java realiza una comprobación de seguridad que hace que ignore todos los controladores no visibles para el cargador de clases primordial cuando se abre una conexión. Una forma conveniente de hacer esto es modificar compute_classpath.sh en todos los nodos de trabajo para incluir sus JAR de controlador.