だから私はアセンブリでsbtを使用して、すべての依存関係をsparkジョブの単一のjarにパッケージ化しました。接続をセットアップするためにc3p0
を使用していたいくつかのジョブがあります情報をプールし、それをブロードキャストしてから、RDDでforeachPartition
を使用して接続を取得し、データベースにデータを挿入します。私のsbtビルドスクリプトには、
"mysql" % "mysql-connector-Java" % "5.1.33"
これにより、JDBCコネクタがジョブとともにパッケージ化されます。すべてがうまく機能します。
そこで最近、SparkSQLをいじり始め、データフレームを取得し、1.3.0
の新機能を使用してjdbcソースに保存する方がはるかに簡単であることに気付きました。
私は次の例外を受け取っています:
Java.sql.SQLException:Java.sqlのJava.sql.DriverManager.getConnection(DriverManager.Java:596)でjdbc:mysql://some.domain.com/myschema?user = user&password = passwordに適したドライバーが見つかりません。 DriverManager.getConnection(DriverManager.Java:233)
これをローカルで実行していたときに、設定して回避しました
SPARK_CLASSPATH=/path/where/mysql-connector-is.jar
最終的に私が知りたいのは、なぜそれをパッケージ化する必要があるときにジョブがドライバーを見つけることができないのですか?私の他の仕事にはこの問題はなかった。 c3p0
とデータフレームコードの両方がJava.sql.DriverManager
(私が伝えることができるものからすべてのインポートを処理する)を利用できるので、うまく動作するはずです。 Assemblyメソッドの動作を妨げる何かがある場合、この動作をさせるには何をする必要がありますか?
この人は同様の問題を抱えていました: http://Apache-spark-user-list.1001560.n3.nabble.com/How-to-use-DataFrame-with-MySQL-td22178.html
コネクタドライバーを最新バージョンに更新しましたか?また、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);
Spark/conf/spark-defaults.confでは、spark.driver.extraClassPathおよびspark.executor.extraClassPathをMySqlドライバー.jarのパスに設定することもできます
sparkドライバーとエグゼキューターはクラスパスにmysqlドライバーが必要なので、指定します
spark.driver.extraClassPath = <path>/mysql-connector-Java-5.1.36.jar
spark.executor.extraClassPath = <path>/mysql-connector-Java-5.1.36.jar
これらのオプションは spark docs :--driver-class-path postgresql-9.4.1207.jar --jars postgresql-9.4.1207.jar
私がしていた間違いは、アプリケーションのjarの後にこれらのオプションについて言及していたことです。
ただし、正しい方法は、spark-submitの直後にこれらのオプションを指定することです。
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
spark 2.2.0の場合、SparkSessionセッションの追加のクラスパス情報をpython script:
spark = SparkSession \
.builder \
.appName("Python Spark SQL basic example") \
.config("spark.driver.extraClassPath", "/path/to/jdbc/driver/postgresql-42.1.4.jar") \
.getOrCreate()
公式ドキュメントを参照してください https://spark.Apache.org/docs/latest/configuration.html
私の場合、sparkはcliコマンドからではなく、Django framework https://www.djangoproject.com/ =
spark.driver.extraClassPathはクライアントモードでは機能しません:
注:クライアントモードでは、ドライバーJVMがその時点で既に開始されているため、アプリケーションでSparkConfを介してこの構成を直接設定しないでください。代わりに、-driver-class-pathコマンドラインオプションまたはデフォルトのプロパティファイルで設定してください。
環境変数SPARK_CLASSPATHは、Spark 1.0+で非推奨になりました。
最初にjdbcドライバーjarを同じローカルファイルシステムパスの下の各エグゼキューターにコピーしてから、spark-submitで次のオプションを使用する必要があります。
--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"
たとえば、TeraDataの場合、terajdbc4.jarとtdgssconfig.jarの両方が必要です。
または、すべてのワーカーノードでcompute_classpath.shを変更します、Sparkドキュメントには次のように記載されています:
JDBCドライバークラスは、クライアントセッションおよびすべてのエグゼキューターの原始クラスローダーに表示される必要があります。これは、JavaのDriverManagerクラスがセキュリティチェックを行うため、接続を開いたときに原始クラスローダーに表示されないすべてのドライバーが無視されるためです。これを行う便利な方法の1つは、すべてのワーカーノードでcompute_classpath.shを変更してドライバーJARを含めることです。
問題を解決するための簡単なJavaトリックがあります。Class.forName()
インスタンスを指定する必要があります。例:
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)))
docs を確認してください
Jarファイルをspark-env.shのSPARK_CLASSPATHに追加すると、動作します。
export SPARK_CLASSPATH=$SPARK_CLASSPATH:/local/spark-1.6.3-bin-hadoop2.6/lib/mysql-connector-Java-5.1.40-bin.jar
シンプルで簡単な方法は、「mysql-connector-Java-5.1.47.jar」を「spark-2.4.3\jars \」ディレクトリにコピーすることです
クラスターモードでMesosクラスターを介してジョブを実行すると、同じ問題が発生しました。
JDBCドライバーを使用するには、フレームワーククラスパスではなくシステムクラスパスに依存関係を追加する必要があります。ファイルに依存関係を追加することでそれを行う方法が見つかりましたspark-defaults.conf
クラスターのすべてのインスタンス。
追加するプロパティはspark.driver.extraClassPath
およびspark.executor.extraClassPath
およびパスはローカルファイルシステムに存在する必要があります。