我希望将火花用于某些ETL,其主要包括"更新"语句(列是一个集合,附加到,因此简单的插入可能不起作用)。因此,似乎发布CQL查询以导入数据是最佳选择。使用Spark Cassandra Connector,我发现我可以这样做:
现在我不想打开一个会话并为源中的每一行关闭它(我是不是想要这个?通常,我有一个会话用于整个过程,并继续在&中使用它#34;普通"应用程序)。但是,它说连接器是可序列化的,但会话显然不是。因此,将整个导入包装在单个" withSessionDo"好像它会导致问题。我在考虑使用这样的东西:
class CassandraStorage(conf:SparkConf) {
val session = CassandraConnector(conf).openSession()
def store (t:Thingy) : Unit = {
//session.execute cql goes here
}
}
这是一个好方法吗?我是否需要担心会议结束?我最喜欢的地方/方式是什么?任何指针都表示赞赏。
答案 0 :(得分:1)
您确实希望使用withSessionDo
,因为它实际上无法在每次访问时打开和关闭会话。在引擎盖下,withSessionDo
访问JVM级会话。这意味着您将只有一个会话对象PER群集配置PER节点。
这意味着像
这样的代码val connector = CassandraConnector(sc.getConf)
sc.parallelize(1 to 10000000L).map(connector.withSessionDo( Session => stuff)
每个执行程序JVM上只会生成1个集群和会话对象,无论每台计算机有多少核心。
为了提高效率,我仍然建议使用mapPartitions来最小化缓存检查。
sc.parallelize(1 to 10000000L)
.mapPartitions(it => connector.withSessionDo( session =>
it.map( row => do stuff here )))
此外,会话对象还使用了一个准备缓存,它允许您在序列化代码中缓存预准备语句,并且每个jvm只会准备一次(所有其他调用都将返回缓存引用。)