2015-04-28 15 views
10

में डेटाफ्रेम लोड करते समय कोई उपयुक्त ड्राइवर नहीं मिला स्पार्क एसक्यूएल में जेडीबीसी डेटाफ्रेम लोड करने का प्रयास करते समय मैं बहुत अजीब समस्या का सामना कर रहा हूं।java.sql.SQLException: स्पार्क एसक्यूएल

मैंने अपने लैपटॉप पर कई स्पार्क क्लस्टर - यार्न, स्टैंडअलोन क्लस्टर और छद्म वितरित मोड की कोशिश की है। यह स्पार्क 1.3.0 और 1.3.1 दोनों पर पुन: उत्पन्न होता है। समस्या spark-shell दोनों में होती है और spark-submit के साथ कोड निष्पादित करते समय होती है। मैंने सफलता के बिना MySQL & एमएस एसक्यूएल जेडीबीसी ड्राइवरों का प्रयास किया है।

val driver = "com.mysql.jdbc.Driver" 
val url = "jdbc:mysql://localhost:3306/test" 

val t1 = { 
    sqlContext.load("jdbc", Map(
    "url" -> url, 
    "driver" -> driver, 
    "dbtable" -> "t1", 
    "partitionColumn" -> "id", 
    "lowerBound" -> "0", 
    "upperBound" -> "100", 
    "numPartitions" -> "50" 
)) 
} 

अब तक तो अच्छा, स्कीमा ठीक से हल हो जाता है:

नमूना निम्नलिखित पर विचार करें

t1: org.apache.spark.sql.DataFrame = [id: int, name: string] 

लेकिन जब मैं DataFrame का मूल्यांकन:

t1.take(1) 

बाद अपवाद तब होता है:

15/04/29 01:56:44 WARN TaskSetManager: Lost task 0.0 in stage 0.0 (TID 0, 192.168.1.42): java.sql.SQLException: No suitable driver found for jdbc:mysql://<hostname>:3306/test 
    at java.sql.DriverManager.getConnection(DriverManager.java:689) 
    at java.sql.DriverManager.getConnection(DriverManager.java:270) 
    at org.apache.spark.sql.jdbc.JDBCRDD$$anonfun$getConnector$1.apply(JDBCRDD.scala:158) 
    at org.apache.spark.sql.jdbc.JDBCRDD$$anonfun$getConnector$1.apply(JDBCRDD.scala:150) 
    at org.apache.spark.sql.jdbc.JDBCRDD$$anon$1.<init>(JDBCRDD.scala:317) 
    at org.apache.spark.sql.jdbc.JDBCRDD.compute(JDBCRDD.scala:309) 
    at org.apache.spark.rdd.RDD.computeOrReadCheckpoint(RDD.scala:277) 
    at org.apache.spark.rdd.RDD.iterator(RDD.scala:244) 
    at org.apache.spark.rdd.MapPartitionsRDD.compute(MapPartitionsRDD.scala:35) 
    at org.apache.spark.rdd.RDD.computeOrReadCheckpoint(RDD.scala:277) 
    at org.apache.spark.rdd.RDD.iterator(RDD.scala:244) 
    at org.apache.spark.scheduler.ResultTask.runTask(ResultTask.scala:61) 
    at org.apache.spark.scheduler.Task.run(Task.scala:64) 
    at org.apache.spark.executor.Executor$TaskRunner.run(Executor.scala:203) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) 
    at java.lang.Thread.run(Thread.java:745) 

जब मैं निष्पादक पर JDBC कनेक्शन खोलने का प्रयास करें:

import java.sql.DriverManager 

sc.parallelize(0 until 2, 2).map { i => 
    Class.forName(driver) 
    val conn = DriverManager.getConnection(url) 
    conn.close() 
    i 
}.collect() 

यह पूरी तरह काम करता है:

res1: Array[Int] = Array(0, 1) 

जब मैं स्थानीय स्पार्क पर एक ही कोड चलाने के लिए, यह पूरी तरह भी काम करता है:

scala> t1.take(1) 
... 
res0: Array[org.apache.spark.sql.Row] = Array([1,one]) 

मैं स्पाड प्री-बिल्ट का उपयोग हैडोप 2.4 समर्थन के साथ कर रहा हूं।

/path/to/spark-shell --master spark://<hostname>:7077 --jars /path/to/mysql-connector-java-5.1.35.jar --driver-class-path /path/to/mysql-connector-java-5.1.35.jar 

वहाँ इस के आसपास काम करने के लिए एक रास्ता है:

समस्या पुन: पेश करने का सबसे आसान तरीका छद्म में स्पार्क start-all.sh स्क्रिप्ट और रन आदेश के बाद के साथ वितरित मोड शुरू करने के लिए है? यह एक गंभीर समस्या की तरह दिखता है, इसलिए यह अजीब बात है कि गुगलिंग यहां मदद नहीं करती है।

उत्तर

4

जाहिर है इस मुद्दे को हाल ही में सूचना दी गई है:

https://issues.apache.org/jira/browse/SPARK-6913

समस्या java.sql.DriverManager में है कि बूटस्ट्रैप classloader के अलावा अन्य ClassLoaders द्वारा लोड ड्राइवरों नहीं देखता।

अस्थायी कार्यवाही के रूप में निष्पादकों के बूट क्लासपाथ में आवश्यक ड्राइवर जोड़ना संभव है।

अद्यतन: https://github.com/apache/spark/pull/5782

अद्यतन 2:: इस पुल अनुरोध समस्या का समाधान होता ठीक स्पार्क 1.4

+0

अरे @Wildfire, कैसे आप संपादन कर निष्पादकों के बूट classpath के बारे में चले गए? मैंने mysql-connector-java jar जोड़ने के लिए यार्न कंटेनर क्लासपाथ को संशोधित करने का प्रयास किया, लेकिन यह त्रुटि को ठीक नहीं किया। धन्यवाद! – JKnight

+1

@JKnight मुझे पता नहीं लगा कि जेएआरबीसी ड्राइवर को यार्न पर क्लासपाथ बूट करने के लिए कैसे जोड़ा जाए, इसलिए मैं केवल पैच किए गए स्पार्क बिल्ड का उपयोग कर रहा हूं। – Wildfire

1

हम स्पार्क 1.3 (क्लाउडेरा 5.4) पर फंस रहे हैं और इसलिए मैं इस सवाल का और जंगल की आग का जवाब मिल गया विलय कर दिया सहायक क्योंकि यह मुझे दीवार के खिलाफ अपने सिर को टक्कर मारने की अनुमति देता है।

सोचा कि मैं साझा करूंगा कि हमें बूट क्लासपाथ में ड्राइवर कैसे मिला: हमने इसे बस /opt/cloudera/parcels/CDH-5.4.0-1.cdh5.4.0.p0 में कॉपी किया।सभी नोड्स पर 27/lib/hive/lib।

+0

हाय, क्या आपने उस फ़ोल्डर में ड्राइवर जोड़ने के बाद क्लौडेरा को पुनरारंभ किया था? धन्यवाद – SantiArias

+1

@ सैंटिया एरिया हाँ मुझे विश्वास है कि हमने क्लस्टर को पुनरारंभ किया है। –

3

MySQL

लिए डेटा लेखन चिंगारी 1.4.0 में के लिए, आप इसे में लिखने से पहले MySQL लोड करने के लिए है क्योंकि यह लोड समारोह पर ड्राइवरों को लोड करता है, लेकिन लिखने समारोह पर नहीं है। हमें प्रत्येक कार्यकर्ता नोड पर जार रखना होगा और प्रत्येक नोड पर स्पार्क-डिफ़ॉल्ट.कॉफ़ फ़ाइल में पथ सेट करना होगा। यह समस्या चिंगारी में तय किया गया है 1.5.0

https://issues.apache.org/jira/browse/SPARK-10036

0

मैं एसक्यूएल सर्वर के साथ चिंगारी 1.6.1 का उपयोग कर रहा है, अभी भी एक ही मुद्दे का सामना करना पड़ा। मुझे पुस्तकालय (sqljdbc-4.0.jar) को उदाहरण में और conf/spark-dfault.conf फ़ाइल में नीचे पंक्ति में lib में जोड़ना पड़ा।

spark.driver.extraClassPath lib/sqljdbc-4.0.jar

संबंधित मुद्दे