web-dev-qa-db-ja.com

Spark Scala rdd.foreachPartitionからデータを取り戻す

私はこのようないくつかのコードを持っています:

      println("\nBEGIN Last Revs Class: "+ distinctFileGidsRDD.getClass)
      val lastRevs = distinctFileGidsRDD.
        foreachPartition(iter => {
          SetupJDBC(jdbcDriver, jdbcUrl, jdbcUser, jdbcPassword)
          while(iter.hasNext) {
            val item = iter.next()
            //println(item(0))
            println("String: "+item(0).toString())
            val jsonStr = DB.readOnly { implicit session =>
              sql"SELECT jsonStr FROM lasttail WHERE fileGId = ${item(0)}::varchar".
                map { resultSet => resultSet.string(1) }.single.apply()
            }
            println("\nJSON: "+jsonStr)
          }
        })
      println("\nEND Last Revs Class: "+ lastRevs.getClass)

コードは(大幅な編集を加えて)次のように出力します。

BEGIN Last Revs Class: class org.Apache.spark.rdd.MapPartitionsRDD
String: 1fqhSXPE3GwrJ6SZzC65gJnBaB5_b7j3pWNSfqzU5FoM
JSON: Some({"Struct":{"fileGid":"1fqhSXPE3GwrJ6SZzC65gJnBaB5_b7j3pWNSfqzU5FoM",... )
String: 1eY2wxoVq17KGMUBzCZZ34J9gSNzF038grf5RP38DUxw
JSON: Some({"Struct":{"fileGid":"1fqhSXPE3GwrJ6SZzC65gJnBaB5_b7j3pWNSfqzU5FoM",... )
...
JSON: None()
END Last Revs Class: void

質問1:lastRevs値をJSON文字列/ nullのような便利な形式またはSome/Noneのようなオプションにするにはどうすればよいですか?

質問2:私の好み:IS(イテレータ形式ではなく)RDDのような形式のデータをパーティションで取得する別の方法はありますか?

dstream.foreachRDD { (rdd, time) =>
  rdd.foreachPartition { partitionIterator =>
    val partitionId = TaskContext.get.partitionId()
    val uniqueId = generateUniqueId(time.milliseconds, partitionId)
    // use this uniqueId to transactionally commit the data in partitionIterator
  } 
}

から http://spark.Apache.org/docs/latest/streaming-programming-guide.html#performance-tuning

質問3:私が使用しているデータを取得する方法は(上記のリンクをたどっていれば)正しい方法ですか? (これが現在scalikejdbcシステムJDBCであるという事実は別として。これは、このプロトタイプ以外のタイプのキー、バリューストアになるでしょう。)

7
codeaperature

エグゼキュータにローカルなリソース(DBやネットワーク接続など)を使用するトランスフォーメーションを作成するには、rdd.mapPartitionsを使用する必要があります。これにより、一部のコードをエグゼキュータに対してローカルで初期化し、それらのローカルリソースを使用してパーティション内のデータを処理できます。

コードは次のようになります。

 val lastRevs = distinctFileGidsRDD.
        mapPartitions{iter => 
          SetupJDBC(jdbcDriver, jdbcUrl, jdbcUser, jdbcPassword)
          iter.map{ element => 
            DB.readOnly { implicit session =>
              sql"SELECT jsonStr FROM lasttail WHERE fileGId = ${element(0)}::varchar"
              .map { resultSet => resultSet.string(1) }.single.apply()
            }
          }
        }
5
maasg