目前,这就是我将Cassandrarow RDD转换为数据帧的方式:
val ssc = new StreamingContext(sc, Seconds(15))
val dstream = new ConstantInputDStream(ssc, ssc.cassandraTable("db", "table").select("createdon"))
import sqlContext.implicits._
dstream.foreachRDD{ rdd =>
val dataframeJobs = rdd.map(w => (w.dataAsString)).map(_.split(":")).map(x =>(x(1))).map(_.split(" ")).map(x =>(x(1))).toDF("ondate")
}
正如您所看到的,我首先将cassandraRow rdd转换为字符串,然后映射到我想要的格式。我发现这个方法变得复杂,因为当rdd包含多个coloumns而不是一个(createdon)时,如示例所示。
还有其他替代方法可以将cassandraRow RDD转换为数据帧吗?
我的build.sbt如下:
scalaVersion := "2.11.8"
libraryDependencies ++= Seq(
"com.datastax.spark" %% "spark-cassandra-connector" % "2.0.1",
"org.apache.spark" %% "spark-core" % "2.0.2" % "provided",
"org.apache.spark" %% "spark-sql" % "2.0.2",
"org.apache.spark" %% "spark-streaming" % "2.0.2"
)
答案 0 :(得分:0)
我想出了一种可以有效处理任意数量的coloumns的替代方法:
rdd.keyBy(row =>(row.getString(" createdon")))。map(x => x._1).toDF(" ondate")
答案 1 :(得分:0)
引用SparkContextFunctions的scaladoc(删除隐式参数):
cassandraTable [T](keyspace:String,table:String):CassandraTableScanRDD [T] 以CassandraRDD形式返回Cassandra表的视图。通过导入
,可以在SparkContext上使用此方法com.datastax.spark.connector._
根据传递给cassandraTable的类型参数,每行都会转换为以下之一:
- 一个CassandraRow对象(默认情况下,如果没有给出类型)
- 包含列值的元组与CassandraRDD选择的列的顺序相同#select
- 用户定义的类的对象,由适当的ColumnMapper填充
所以,我建议使用以下内容:
ssc.cassandraTable[String]("db", "table").select("createdon")
这应该为您提供了根据文档访问createdon
的最简单方法。
我也想知道为什么你没有像Datasets中所描述的那样使用spark-cassandra-connector支持的DataFrame。这样你的代码可能会变得更简单。
您可以尝试使用Spark SQL的Structured Streaming替换Spark Streaming(几乎正式废弃):
结构化流是一个基于Spark SQL引擎的可扩展且容错的流处理引擎。您可以像表达静态数据的批处理计算一样表达流式计算。 Spark SQL引擎将负责逐步和连续地运行它,并在流数据继续到达时更新最终结果。
我不确定Cassandra Spark Connector是否支持它。