【问题标题】:The best way to Update the database table through a pyspark job通过 pyspark 作业更新数据库表的最佳方法
【发布时间】:2020-05-19 09:30:58
【问题描述】:

我有一个 Spark 作业,它从多个来源获取数据并将数据聚合到一个表中。只有当有新数据时,作业才应该更新表。

我能想到的一种方法是从现有表中获取数据,并与传入的新数据进行比较。比较发生在 spark 层中。

我想知道是否有更好的比较方法,可以提高比较性能。

如果有人对此有任何建议,请告诉我。

提前非常感谢。

【问题讨论】:

  • 您也可以将新数据写入临时表,然后使用 Bigquery Merge 更新目标表。
  • 答案将基于意见。请查看我在项目中所做的工作

标签: dataframe apache-spark pyspark google-bigquery bigdata


【解决方案1】:

我能想到的一种方法是从现有的 表,并与进来的新数据进行比较

恕我直言,整个数据与加载新数据相比性能不佳。

选项 1:

相反,您可以创建 分区表并创建一个分区列来加载数据,并且在加载新数据时您可以检查新数据是否具有相同的分区列。 在 hive 或 bigquery 中点击分区级别的数据比选择整个数据并在 spark 中进行比较更有用/更有效。

同样适用于 hive。

看到这个Creating partitioned tables 要么 Creating and using integer range partitioned tables


选项 2:

另一种选择是 GOOGLE bigquery 我们有合并语句,如果您的要求是合并数据而不进行比较,那么您可以继续使用 MERGE 语句。 . 请参阅下面的文档链接 A MERGE statement is a DML statement that can combine INSERT, UPDATE, and DELETE operations into a single statement and perform the operations atomically.

使用它,我们可以提高性能,因为所有三个操作(INSERT、UPDATE 和 DELETE)都是一次性执行的。我们不需要编写单独的语句来更新目标表中的更改。

【讨论】:

  • 谢谢你,拉姆。即使我按时间时间戳对表进行分区,我也会遇到同样的问题,对吧?例如,我今天创建表,并用今天的数据更新表。明天运行作业时,如果它是相同的数据,那么数据是否仍会复制到表中,除非它将位于不同的分区中。如果我的理解在这里不正确,请纠正我。谢谢!
  • 可能不是基于时间戳的分区,例如类别(例如)。通过检查类别项目(如果不存在),您可以加载数据...否则您可以忽略新数据...类似这样的事情....通过这样做基本上您不会将所有数据与所有类别进行比较新的一个。您将通过不将所有数据加载到火花内存中来比较单个类别项目(仅单个分区列)以进行比较..
  • 非常感谢,拉姆。让我试试这个想法。 :)
  • 如果您没事,请注意以所有者的身份接受答案。谢谢
【解决方案2】:

有很多方法可以解决这个问题,其中一种成本更低、性能更高且可扩展的方法是使用文件系统上的数据存储来确定真正的新数据。

  1. 当数据第一次进入时,将其写入 2 个位置 - 数据库和文件(例如在 s3 中)。如果数据已经在数据库中,那么您需要使用表数据初始化本地/s3 文件。
  2. 随着数据第二次进入,根据本地/s3 文件的存在检查它是否是新的。
  3. 将增量数据标记为新的或更新的。将此作为插入或更新导出到数据库。

随着时间的推移,这个文件会越来越大。定义一个日期范围,超过该范围的更新数据将不会出现。定期截断此文件以将数据保留在该时间范围内。 您还可以对这些数据进行存储和分区。您也可以使用 deltalake 来维护它。

一个缺点是,每当更新数据库时,可能需要根据相关数据是否正在更改来更新此文件。您可以在数据库表上维护一个标记来表示同步日期。也索引该列。根据此列读取更改的记录并更新文件/deltalake。

这样,您的 sparl 应用程序将减少对数据库的依赖。数据库操作的可扩展性不是很好,因此最好让它们远离关键路径

【讨论】:

    【解决方案3】:

    您的数据库中不应该有最后一次更新时间吗?您使用的方法听起来不可扩展,因此如果您有办法为表中的每一行设置更新时间,它将解决问题。

    【讨论】:

    • 谢谢你,伊利亚。读入 Spark 作业的新数据来自多个来源。没有时间戳。我可以在我正在创建的表中添加更新时间戳,但我仍然需要读取数据并进行比较。正确的?例如,该作业可以运行,它仍然可以看到昨天看到的相同数据。如果我误解了您的建议,请纠正我。
    • 您好,如果您没有时间戳数据......您可以使用任何其他东西作为分区列来查询数据。明智地读取分区 - 比较优于读取整个数据进行比较。请看我的回答
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-15
    • 2013-11-19
    • 1970-01-01
    • 2016-03-16
    相关资源
    最近更新 更多