2016-02-05 45 views
4

嗨我想從文本文件中使用spark讀取特定的行。如何從sparkContext讀取特定行

SparkConf conf = new SparkConf().setAppName(appName).setMaster(master); 
sc = new JavaSparkContext(conf); 
JavaRDD<String> lines = sc.textFile("data.txt"); 
String firstLine = lines.first(); 

它可以使用.first()命令來獲取data.text文檔的第一行。我如何訪問文檔的第N行?我需要Java解決方案。

回答

4

Apache Spark RDD並不打算用於查找。獲得n th線的最「有效」的方式是lines.take(n + 1).get(n)。每當你這樣做,它會讀取文件的第一行n行。您可以運行lines.cache以避免這種情況發生,但它仍然會通過網絡以非常低效的舞蹈移動第一條線路上的第一條n線路。

如果數據可以放在一臺機器上,只收集一次,並在本地訪問:List<String> local = lines.collect(); local.get(n);

如果數據不適合一臺機器,則需要一個支持高效查找的分佈式系統。流行的例子是HBase和Cassandra。

也有可能您的問題可以通過Spark高效解決,但不能通過查找解決。如果你在一個單獨的問題中解釋更大的問題,你可能會得到這樣的解決方案。 (查找在單機應用非常普遍,但分佈式算法有不同的想法。)

+0

如果你使用DataFrames進行獲取路線,我認爲你需要'lines.take(n).apply(n-1)' –

+0

謝謝,我以某種方式解決了這個問題。假設「'n'th」是基於零的:)。 'lines'應該是'JavaRDD',所以'take'會返回一個Java'List ',因此'get'而不是'apply'。 –

1

我覺得這是快,因爲它得到

def getNthLine(n: Long) = 
    lines.zipWithIndex().filter(_._2 == n).first 
1

像@Daniel Darabos說,RDDS沒有索引的線看起坐,所以另一種方法是給它一個指標:

lines.zipWithIndex.filter(_._2==n).map(_._1).first() 

給它一個索引,然後第一個再次使用火花背景下,但這種方法有些什麼效率低下,傻時的大小你RDD很小。但是,當RDD的大小非常大時,將其收集到主人會變得效率低下(並且可能會限制內存),並且此方法將成爲更好的選擇。