使用Spark DataFrame将数据插入Cassandra表

时间:2016-12-20 17:42:18

标签: scala apache-spark spark-cassandra-connector

我使用的是Scala版本2.10.5 Cassandra 3.0和Spark 1.6。我想将数据插入cassandra所以我尝试了基本的例子

scala> val collection = sc.parallelize(Seq(("cat", 30), ("fox", 40)))
scala> collection.saveToCassandra("test", "words", SomeColumns("word", "count"))

哪些Works和能够将数据插入到Cassandra中。所以我有一个csv文件,我想通过匹配模式插入到Cassandra表中

val person = sc.textFile("hdfs://localhost:9000/user/hduser/person")
import org.apache.spark.sql._
val schema =  StructType(Array(StructField("firstName",StringType,true),StructField("lastName",StringType,true),StructField("age",IntegerType,true)))
val rowRDD = person.map(_.split(",")).map(p => org.apache.spark.sql.Row(p(0),p(1),p(2).toInt))
val personSchemaRDD = sqlContext.applySchema(rowRDD, schema)
 personSchemaRDD.saveToCassandra

当我使用SaveToCassndra时,我获取saveToCassandra不属于personSchemaRDD。所以教会以不同的方式尝试

 df.write.format("org.apache.spark.sql.cassandra").options(Map( "table" -> "words_copy", "keyspace" -> "test")).save()

但是无法连接到ip上的cassandra:port.can任何人告诉我最好的方法。我需要定期从文件中将数据保存到cassandra。

2 个答案:

答案 0 :(得分:7)

sqlContext.applySchema(...)返回DataFrameDataFrame没有saveToCassandra方法。

您可以使用.write方法:

val personDF = sqlContext.applySchema(rowRDD, schema)
personDF.write.format("org.apache.spark.sql.cassandra").options(Map( "table" -> "words_copy", "keyspace" -> "test")).save()

如果我们想使用savetoCassandra方法,最好的方法是使用案例类来获得模式感知的RDD。

case class Person(firstname:String, lastName:String, age:Int)
val rowRDD = person.map(_.split(",")).map(p => Person(p(0),p(1),p(2).toInt)
rowRDD.saveToCassandra(keyspace, table)

Dataframe write方法应该有效。检查您是否正确配置了上下文。

答案 1 :(得分:0)

我将代码放在此处,以使用Spark Java将Spark数据集保存到Cassandra表中。

private static void readBigEmptable(SparkSession sparkSession) {
   String cassandraEmpColumns= "id,name,salary,age,city";
    Dataset<Row> bigDataset = sparkSession.sql("select * from big_emp");
    // Generate the schema for output row
    List<StructField> fields = new ArrayList<>();
    for (String fieldName : cassandraEmpColumns.split(",")) {
        StructField field = DataTypes.createStructField(fieldName, DataTypes.StringType, true);
        fields.add(field);
    }
    StructType schemaStructure = DataTypes.createStructType(fields);
    // Converting big dataset to RDD to perform operation on Row field
    JavaRDD<Row> bigRDD = bigDataset.toJavaRDD();
    JavaRDD<Row> resultRDD = bigRDD .map(new Function<Row, Row>() {

        /**
         * 
         */
        private static final long serialVersionUID = 1L;

        @Override
        public Row call(Row row) throws Exception {
            // return compareField(row).iterator();
            Row outputRow = RowFactory.create(row.getAs("id"), row.getAs("name"), row.getAs("salary"),
                    row.getAs("age"), row.getAs("city"));
            return outputRow;
        }
    });
    Dataset<Row> empDs = sparkSession.createDataFrame(resultRDD, schemaStructure);
    empDs.show();
    writeToCassandraTable(empDs);

}

private static void writeToCassandraTable(Dataset<Row> dataset) {
    Map<String, String> tableProperties = new HashMap();
    tableProperties.put("keyspace", "test_keyspace");
    tableProperties.put("table", "emp_test");
    tableProperties.put("confirm.truncate", "true");
    dataset.write().format("org.apache.spark.sql.cassandra").options(tableProperties).mode(SaveMode.Overwrite)
            .save();
}

注意::如果我们使用的是 mode(SaveMode.Overwrite),则应该使用 tableProperties.put(“ confirm.truncate”,“ true”) ; ,否则我们将收到错误消息。

SaveMode.Append

  • 附加模式意味着将DataFrame保存到数据源时, 如果数据/表已经存在,则期望数据框的内容 附加到现有数据中。

SaveMode.ErrorIfExists

  • ErrorIfExists模式意味着将DataFrame保存到数据时 源,如果已经存在数据,则预计会出现异常 抛出。

SaveMode。忽略

  • 忽略模式意味着在将DataFrame保存到数据源时,如果已经存在数据,则预期保存操作不会保存DataFrame的内容并且不会更改现有数据。

保存模式。覆盖

  • 覆盖模式意味着将DataFrame保存到数据源时, 如果数据/表已经存在,则现有数据应为 被DataFrame的内容覆盖。