簡體   English   中英

Spark:文本文件轉換為RDD [Byte]

[英]Spark: Text file to RDD[Byte]

我需要將文本文件加載到RDD中,以便可以對其中包含的數據運行任務。 Driver程序是用Scala編寫的,將在每個任務中執行的代碼都可以作為通過JNI訪問的本機動態庫獲得。

現在,我以這種方式創建RDD:

val rddFile : RDD[String] = sc.textFile(path);

我有用於任務的C本機代碼,盡管它在實際文件(即fgetc())上使用字節級操作。 我正在嘗試模擬相同類型的操作(以最大程度地減少代碼重構),但避免在磁盤上寫入要由所述本機庫處理的數據片段,這會影響性能。

這是本機函數的定義以及我的調用方式:

natFunction(data : Array[String])
rddFile.glom().foreach(elem=>natFunction(elem))

但是,調用textFile()生成的RDD包含String對象,需要在JNI的本機端將其轉換為有效的C字符串。 我相信上述轉換對文件每一行的性能影響可能是巨大的,但仍不及對文件進行操作。

我還認為更兼容的類型是RDD [Byte],這樣我就可以將字節數組發送到本機端,可以以更中間的方式將其轉換為C字符串。

這些假設是正確的嗎? 如果是這樣,將文本文件作為RDD [Byte]加載的有效方法是什么?

歡迎任何其他解決此問題的建議。

您可以通過執行rdd.flatMap(s => s.getBytes)RDD[String]獲取RDD[Byte] ,但是請注意-很有可能String的每個字符有2個字節(我猜這取決於語言環境設置)。

同樣,當您擁有RDD [Byte]時,您將需要調用,例如, mapPartitions將數據以Array[Byte]提供給C代碼。 在這種情況下,您將有相當大的數組傳遞給C代碼,但是對於每個分區,C應用程序將僅被調用一次。 另一種方法是使用rdd.map(s => s.getBytes)在這種情況下,您將具有RDD[Array[Byte]] ,因此每個分區將運行多個C應用程序。

我認為您可以嘗試使用pipe() API啟動C代碼,並將RDD元素通過管道傳遞到C代碼,並獲取C應用程序的輸出以進行進一步處理。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM