[英]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.