繁体   English   中英

在Spark中读取CSV文件并将其写入Cassandra

[英]Read CSV File in Spark and Write it to Cassandra

我正在尝试使用Spark读取CVS文件,然后将其保存到Cassandra。 当我使用琐碎的值时,保存到Cassandra是可行的。

我有一个具有以下值的文件:

id,name,tag1|tag2|tag3

我想将其存储在cassandra表中:

id bigint, name varchar, tags set

我为此定义了一个案例类:

case class Item(id:Integer,name:String,tag:Set[String])

然后我使用此表达式将RDD移出CVS文件

val items = sc.textFile("items.csv").map(l => l.split(",") match {case Array (a,b,c) => Item(Integer.parseInt(a),b,c.split("\\\\|").toSet)})

现在,当我对项目调用collectsaveToCassandra (开始处理)时,出现以下错误:

org.apache.spark.SparkException: Job aborted due to stage failure: Task 1 in stage 29.0 failed 1 times, most recent failure: Lost task 1.0 in stage 29.0 (TID 38, localhost): scala.MatchError: [Ljava.lang.String;@6030bbe6 (of class [Ljava.lang.String;) at $iwC$$iwC$$iwC$$iwC$$iwC$$iwC$$iwC$$iwC$$iwC$$iwC$$iwC$$iwC$$anonfun$2.apply(<console>:33) at $iwC$$iwC$$iwC$$iwC$$iwC$$iwC$$iwC$$iwC$$iwC$$iwC$$iwC$$iwC$$anonfun$2.apply(<console>:33) at scala.collection.Iterator$$anon$11.next(Iterator.scala:328) at org.apache.spark.storage.MemoryStore.unrollSafely(MemoryStore.scala:249) at org.apache.spark.CacheManager.putInBlockManager(CacheManager.scala:172) at org.apache.spark.CacheManager.getOrCompute(CacheManager.scala:79) at org.apache.spark.rdd.RDD.iterator(RDD.scala:242) at org.apache.spark.scheduler.ResultTask.runTask(ResultTask.scala:61) at org.apache.spark.scheduler.Task.run(Task.scala:64) at org.apache.spark.executor.Executor$TaskRunner.run(Executor.scala:203) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at java.lang.Thread.run(Thread.java:745)

如前所述,问题在于在某些输入上进行拆分会生成一个数组,该数组具有少于或大于匹配中使用的3个元素的数组。

partialFuntion用来做匹配可用于对符合上述标准匹配的元素进行筛选。 rdd.collect{partialFunction}就是为了这个目的:

val data = sc.textFile("items.csv")
val arrayData = data.map(l => l.split(","))
val items = arrayData.collect{case Array (a,b,c) => Item(Integer.parseInt(a),b,c.split("\\|").toSet)})
 items.saveToCassandra(...)
  • 注意1:您还应防止脏值。 例如parseInt的值不是int数,...)
  • 注意2: rdd.collect{partialFunc} (使用部分函数的过滤器/地图数据)不应与rdd.collect (将数据返回给驱动程序)混淆。

如果您输入的不是 3个条目的数组,则会出现匹配错误,例如

String("a,b").split(",") match {
   case Array(a,b,c) => ....
}

因此,我怀疑这是一些输入数据问题,因此您需要在match

我在下面使用保存我的CSV文件“ |” 分离到cassandra DB。 希望这会有所帮助

package com
import java.io.FileInputStream
import java.util.Properties
import org.apache.log4j.LogManager
import org.apache.spark.{SparkConf, SparkContext}

object CsvLoad {
  def main(args: Array[String]): Unit = {
    val log = LogManager.getRootLogger

    log.info("**********JAR EXECUTION STARTED**********")
    val properties: Properties = new Properties
    properties.load(new FileInputStream(args(0)))

    val sparkConf = new SparkConf()
      .setAppName(getClass.getName)
      .set("spark.cassandra.connection.host", properties.getProperty("CASSANDRA_HOST"))
      .set("spark.cassandra.connection.port", properties.getProperty("CASSANDRA_PORT"))
      .setMaster("local[*]")
      .set("spark.cassandra.auth.username", properties.getProperty("CASSANDRA_USERNAME"))
      .set("spark.cassandra.auth.password", "Jcloud@1357")
      .set("spark.cassandra.output.concurrent.writes", "32")
      .set("spark.cassandra.output.consistency.level", "ONE")
      .set("spark.cassandra.input.split.size_in_mb","67108864")
      .set("spark.cassandra.output.batch.grouping.key", "none")

     val sc=new SparkContext(sparkConf)
    val spark = new org.apache.spark.sql.SQLContext(sc)
    val data = spark.read.format("csv").option("header", "true").option("delimiter", "|").option("inferSchema", "true").
      load("D:\\data.csv")

    val output = data.write.format("org.apache.spark.sql.cassandra").options(Map("table" -> "mytable", "keyspace" -> "test", "cluster" -> "Test Cluster"))
    output.save()
  }

}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM