Spark SQL具有相同Row的不同分区

时间:2017-04-04 18:58:51

标签: java apache-spark apache-spark-sql

我尝试使用如下代码将Spark SQL Row值插入数据库:

final Broadcast<String> jdbcUrl = sc.broadcast(config.jdbcUrl());
df.foreachPartition((final Iterator<Row> it) -> {
    final Sql2o sql2o = new Sql2o(jdbcUrl.value(), null, null, new NoQuirks());
    try (final Connection conn = sql2o.beginTransaction()) {
        final String sql = "INSERT INTO Table (Id, Value) VALUES (:id, :value)";
        final Query query = conn.createQuery(sql, false);
        int batchSize = 0;
        while (it.hasNext()) {
            final Row row = it.next();
            query.addParameter("id", row.getLong(0))
                .addParameter("value", row.get(1));
                .addToBatch();
            if (++batchSize == 1000) {
                query.executeBatch();
                conn.commit();
                batchSize = 0;
            }
        }
        query.executeBatch();
        conn.commit();
    }
});

我收到了主要密钥违规错误:

  

java.sql.BatchUpdateException:违反PRIMARY KEY约束   &#39; PK_Table&#39 ;.无法在对象&#39;表&#39;中插入重复键。该   重复键值为42。

我添加了一些调试日志代码,并且我验证了两个不同的执行程序试图插入相同的行(具有相同的id和值)。

在Spark SQL开始插入Row值之前,表是空的。另外,我在调用DataFrame上的distinct()之前尝试拨打persist()foreachPartition(),我仍然遇到了问题。

同一DataFrame的不同分区是否应该有单独的数据?不要分区的人总是保证吗?

修改

我在DataFrame上运行df.groupBy(df.col("id")).count().filter(col("count").gt(1)).show();,并且没有ID分组到多个行的ID:

+--+-----+
|id|count|
+--+-----+
+--+-----+

从我可以看出,看起来在不同的执行器中同时迭代同一个分区。怎么样?

1 个答案:

答案 0 :(得分:0)

也许,列索引是错误的; “id”不在0列中。更好:

userow.getAs[Long]("id")

而不是row.getLong(0)