繁体   English   中英

spark job(scala)将类型Date写入Cassandra

[英]spark job (scala) write type Date to Cassandra

我正在使用DSE 5.1(Spark 2.0.2.6和cassandra 3.10.0.1652)

我的Cassandra表:

CREATE TABLE ks.tbl (
   dk int,
   date date,
   ck int,
   val int,
PRIMARY KEY (dk, date, ck)
) WITH CLUSTERING ORDER BY (date DESC, ck ASC);

具有以下数据:

 dk | date       | ck | val
----+------------+----+-----
  1 | 2017-01-01 |  1 | 100
  1 | 2017-01-01 |  2 | 200

我的代码必须读取此数据并编写相同的内容,但是要有昨天的日期(它可以成功编译):

package com.datastax.spark.example

import com.datastax.spark.connector._
import com.datastax.spark.connector.cql.CassandraConnector
import org.apache.spark.sql.hive.HiveContext
import org.apache.spark.{SparkConf, SparkContext}
import com.github.nscala_time.time._
import com.github.nscala_time.time.Imports._

object test extends App {

  val conf = new SparkConf().setAppName("DSE calculus app TEST")
  val sc = new SparkContext(conf)

  val yesterday= (DateTime.now - 1.days).toString(StaticDateTimeFormat.forPattern("yyyy-MM-dd"))

  val tbl = sc.cassandraTable("ks","tbl").select("dk","date","ck","val").where("dk=1")

  tbl.map(row => (row.getInt("dk"),yesterday,row.getInt("ck"),row.getInt("val"))).saveToCassandra("ks","tbl")

  sc.stop()
  sys.exit(0)
}

当我运行此应用程序时:

dse spark-submit --class com.datastax.spark.example.test test-assembly-0.1.jar

无法正确写入Cassandra。 似乎日期变量未正确插入地图中。 我得到的错误是:

Error:
WARN  2017-05-08 22:23:16,472 org.apache.spark.scheduler.TaskSetManager: Lost task 0.0 in stage 0.0 (TID 0, <IP of one of my nodes>): java.io.IOException: Failed to write statements to ks.tbl.
        at com.datastax.spark.connector.writer.TableWriter$$anonfun$writeInternal$1.apply(TableWriter.scala:207)
        at com.datastax.spark.connector.writer.TableWriter$$anonfun$writeInternal$1.apply(TableWriter.scala:175)
        at com.datastax.spark.connector.cql.CassandraConnector$$anonfun$withSessionDo$1.apply(CassandraConnector.scala:112)
        at com.datastax.spark.connector.cql.CassandraConnector$$anonfun$withSessionDo$1.apply(CassandraConnector.scala:111)
        at com.datastax.spark.connector.cql.CassandraConnector.closeResourceAfterUse(CassandraConnector.scala:145)
        at com.datastax.spark.connector.cql.CassandraConnector.withSessionDo(CassandraConnector.scala:111)
        at com.datastax.spark.connector.writer.TableWriter.writeInternal(TableWriter.scala:175)
        at com.datastax.spark.connector.writer.TableWriter.insert(TableWriter.scala:162)
        at com.datastax.spark.connector.writer.TableWriter.write(TableWriter.scala:149)
        at com.datastax.spark.connector.RDDFunctions$$anonfun$saveToCassandra$1.apply(RDDFunctions.scala:36)
        at com.datastax.spark.connector.RDDFunctions$$anonfun$saveToCassandra$1.apply(RDDFunctions.scala:36)
        at org.apache.spark.scheduler.ResultTask.runTask(ResultTask.scala:70)
        at org.apache.spark.scheduler.Task.run(Task.scala:86)
        at org.apache.spark.executor.Executor$TaskRunner.run(Executor.scala:274)
        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:748)

但是,当我按如下所示直接在map语句中插入日期(字符串)时,代码确实正确插入了数据:

tbl.map(row => (row.getInt("dk"),"2017-02-02",row.getInt("ck"),row.getInt("val"))).saveToCassandra("ks","tbl")

如果我将昨天设置为整数(自纪元以来的天数),它也可以正确插入数据。 这将是最佳选择,但不能使“昨天”以这种方式运行

编辑:实际上,这不能正确插入数据。 无论我将“昨天”设置为1还是1亿,它总是插入纪元('1970-01-01)

失败的代码可以正常运行,就像我在DSE Spark控制台中所期望的那样。

我只是不知道我在做什么错。 欢迎任何帮助。

EDIT2: 准分子0 stderr日志确实表明它试图在列日期中插入Null值,这显然是不可能的,因为它是一个群集列。

在为Spark Job编写代码时,重要的是要意识到何时设置了特定变量以及何时对其进行了序列化。 让我们来看看App trait文档中的注释

注意事项

应该注意的是,此特性是使用DelayedInit功能实现的,这意味着在执行main方法之前,不会初始化对象的字段。

这意味着在实际运行代码时,可能不会在执行程序上初始化对App主体中使用的变量的引用。

我的猜测是您编写的lambda包含对val的引用,该引用在App类的Delayed init部分中初始化。 这意味着未运行Main方法的执行程序上的代码的序列化版本将获得值的未初始​​化版本(空)。

将常量切换为lazy val (或将其移动到单独的对象或类中)将通过确保值是远程初始化(惰性val)或简单地序列化初始化(单独的类/对象)来解决此问题。

我想我知道你的问题是什么。
您可能会看到完整的日志文件。 您只需附加一部分...
今天有类似的错误,当使用replication_factor创建密钥空间时:3当我只有一个cassandra实例时。

所以我改变它,问题就解决了。

ALTER KEYSPACE "some_keyspace_name" WITH REPLICATION =
  { 'class' : 'SimpleStrategy', 'replication_factor' : 1 };

这是我的error.log文件

日志的重要部分:

Logging.scala[logError]:72) - Failed to execute: com.datastax.spark.connector.writer.RichBoundStatement@4746499f
com.datastax.driver.core.exceptions.UnavailableException: Not enough replicas available for query at consistency LOCAL_QUORUM (2 required but only 1 alive)

暂无
暂无

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

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