0

我正在尝试更新一个大 mysql 表的每一行的几个字段(接近500百万行)。该表没有任何主键(或具有字符串主键,如 UUID)。我没有足够的执行程序内存来​​一次读取和保存整个数据。任何人都可以让我知道我处理此类表格的选项是什么。

下面是架构

CREATE TABLE Persons ( Personid varchar(255) NOT NULL, LastName varchar(255) NOT NULL, FirstName varchar(255) DEFAULT NULL, Email varchar(255) DEFAULT NULL, Age int(11) DEFAULT NULL) ) ENGINE=InnoDB DEFAULT CHARSET=latin1;

Spark代码就像

 SparkSession spark = SparkSession.builder().master("spark://localhost:7077").appName("KMASK").getOrCreate();
DataFrame rawDataFrame = spark.read().format("jdbc").load();
rawDataFrame.createOrReplaceTempView("data");
//encrypt is UDF
String sql = "select Personid, LastName, FirstName, encrypt(Email), Age from data";
Dataset newData = spark.sql(sql);
newData.write().mode(SaveMode.Overwrite).format("jdbc").options(options).save();

这张表有大约150百万条记录,数据大小约为6GB. 我的执行者记忆只是2 gb. 我可以使用 Spark - jdbc 处理此表吗?

4

1 回答 1

0

理想情况下,您可以更改 spark jdbcfetchsize选项以减少/增加每次获取和处理的记录数。

对数据进行分区还可以帮助减少洗牌和额外的开销。因为你有Age一个数字字段。您还可以在由 Age 确定的分区中处理数据。首先确定最小和最大年龄并使用Spark JDBC 选项

尤其:

  • partitionColumnAge
  • lowerBound:您确定的最小年龄
  • upperBound:您确定的最大年龄
  • numPartitions:真的取决于核心和工作节点的数量,但这里有更多提示和链接

您还可以使用自定义查询来仅选择和更新一些可以通过该query选项保存在内存中的记录。注意。使用query选项时,您不应该使用dbtable选项。

于 2021-04-17T03:05:59.897 回答