2016-08-19 13 views
5

के माध्यम से थोक डेटा माइग्रेशन मैं वर्तमान में स्पार्क एसक्यूएल के माध्यम से एक बहुत बड़ी MySQL तालिका की सामग्री को माइक्रेट करने की कोशिश कर रहा हूं। लेकिन ऐसा करने पर मैं जल्दी से स्मृति से बाहर चला जाता हूं, भले ही ड्राइवर की मेमोरी सीमा अधिक हो (मैं स्थानीय मोड में स्पार्क का उपयोग कर रहा हूं)। उदाहरण कोड:स्पार्क एसक्यूएल

Dataset<Row> ds = spark.read() 
    .format("jdbc") 
    .option("url", url) 
    .option("driver", "com.mysql.jdbc.Driver") 
    .option("dbtable", "bigdatatable") 
    .option("user", "root") 
    .option("password", "foobar") 
    .load(); 

ds.write().mode(SaveMode.Append).parquet("data/bigdatatable"); 

ऐसा लगता है स्पार्क स्मृति में पूरे तालिका सामग्री, जो बहुत अच्छी तरह से बाहर काम करने के लिए नहीं जा रहा है पढ़ने का प्रयास की तरह। तो, स्पार्क एसक्यूएल के माध्यम से थोक डेटा माइग्रेशन करने का सबसे अच्छा तरीका क्या है?

+0

आप ओओएम प्राप्त करना क्योंकि स्पार्क गलत कॉन्फ़िगर किया गया है, आपको शायद ड्राइवर में स्ट्रीमिंग सक्षम करना चाहिए: http://stackoverflow.com/a/2448019/2439539 – r90t

उत्तर

3

आपके समाधान में, स्पार्क लिखने से पहले एक तालिका में पूरी तालिका सामग्री को पढ़ेगा। एक तरह से आपको लगता है कि बच सकते हैं पढ़ने हिस्सा विभाजन है, लेकिन यह स्रोत डेटा में संख्यात्मक अनुक्रमिक स्तंभ की आवश्यकता है:

Dataset<Row> ds = spark.read() 
    .format("jdbc") 
    .option("url", url) 
    .option("driver", "com.mysql.jdbc.Driver") 
    .option("dbtable", "bigdatatable") 
    .option("user", "root") 
    .option("password", "foobar") 
    .option("partitionColumn", "NUMERIC_COL") 
    .option("lowerBound", "1") 
    .option("upperBound", "10000") 
    .option("numPartitions", "64") 
    .load(); 

उपरोक्त उदाहरण में, स्तंभ "NUMERIC_COL" डेटा में मौजूद हैं और यह चाहिए आदर्श रूप से, 1 से 10000 तक समान रूप से भिन्न होना चाहिए। बेशक, यह बहुत सारी आवश्यकताएं हैं और ऐसा स्तंभ संभवतः मौजूद नहीं होगा, इसलिए आपको डेटाबेस में उस तरह के कॉलम के साथ एक दृश्य बनाना चाहिए, या आप इसे जोड़ना चाहिए क्वेरी में (ध्यान दें कि मैंने एक सामान्य एसक्यूएल सिंटैक्स का उपयोग किया है, आपको अपने डीबीएमएस के लिए अनुकूलित करना होगा):

String query = "(select mod(row_number(), 64) as NUMERIC_COL, * from bigdatatable) as foo" 

Dataset<Row> ds = spark.read() 
    .format("jdbc") 
    .option("url", url) 
    .option("driver", "com.mysql.jdbc.Driver") 
    .option("dbtable", query) 
    .option("user", "root") 
    .option("password", "foobar") 
    .option("partitionColumn", "NUMERIC_COL") 
    .option("lowerBound", "0") 
    .option("upperBound", "63") 
    .option("numPartitions", "64") 
    .load(); 
+0

यह अच्छा लग रहा है। धन्यवाद @ डैनियल –

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