【问题标题】:Databricks tables/schemas deploymentDatabricks 表/模式部署
【发布时间】:2020-08-27 13:41:04
【问题描述】:

目标

我们使用 Databricks 集群进行 ETL 流程,使用 Databricks Notebooks 进行 DS、ML 和 QA 活动。

目前,我们不使用 Databricks 目录或外部 Hive Metastore。我们以 Spark StructType 格式以编程方式定义模式,并且硬编码路径如下:

tables/some_table.py

class SomeTable(TableBase):

   PATH = os.getenv('SOME_TABLE_PATH', /some_folder/some_subfolder/) # actually it's passed as constructor arg

   SCHEMA = {
       "type": "struct",
       "fields": [
          {
              "name": "some_field",
              "type": "string",
              "nullable": true
          },
          ...
       ]

   def schema() -> StructType:
       return StructType.fromJson(self.SCHEMA)

   def save(df: DataFrame):
       df.write.parquet(self.PATH)

   def read(year: str, month: str, day: str) -> DataFrame:
       return self.spark \
           .read \
           .parquet(self.PATH) \
           .filter((F.col('YEAR') == year) & ...)

问题

我们不时进行一些重构,更改表的路径、架构或分区。这是一个问题,因为 Databricks 是开发人员、QA 和数据科学家之间的共享平台。每次更改时,我们都必须在多个位置更新所有笔记本和文档。

我还想在未来使用分桶(集群)、表统计、Delta Lake、SQL 语法数据探索、视图和一些安全功能。这些功能还需要 Databricks 可访问的表定义。

问题

您通常如何部署 Databricks 架构及其更新?我应该使用在集群启动时由基础设施即代码工具自动执行的 SQL 脚本吗?还是有更简单/更好的解决方案?

可以使用df.write.saveAsTable('some_table') 创建使用 Databricks/Spark 编写的数据帧架构。但这不是最好的解决方案,因为:

  1. 我想在第一次写入之前进行架构定义。例如,我将 500 列的数据集转换为 100 列,并希望根据架构定义仅选择所需的列。

  2. 存在使用其他工具(如 ADF 或 Nifi)摄取(写入)的只读数据集

更新

我喜欢使用 AWS Glue(EMR 用作 Hive Metastore)并通过 Cloud Formation 进行部署的体验。我想 Databricks 有类似甚至更简单的经验,只是想知道最佳实践是什么。

更新 #2

回答问题加分 - 如何在 Databricks 目录(或外部 Hive Meta Store)和我们的代码库之间不重复 shcema 定义?

如果我们使用 SQL 语法来描述我们的模式,我们将无法在单元测试中重用它们。 是否有任何基于上述格式部署模式的干净解决方案(参见代码 sn-p)?

PS:目前我们使用 Azure 云

【问题讨论】:

  • 这是显而易见的事情吗?为什么要投反对票?

标签: apache-spark databricks


【解决方案1】:

对于 AWS 上的 Databricks,AWS Glue Catalog 是一种强大的方法,可以将您的元存储集中到您的所有计算中,并且查询引擎可以使用相同的数据定义。 Glue Catalog 提倡云范围的数据策略,避免使用产品特定的数据目录和访问控制创建数据孤岛。 有关更多信息,请参阅此 Databricks 博客文章:https://docs.databricks.com/data/metastores/aws-glue-metastore.html

在性能方面,通过定义架构,您会看到提升,并且您将能够在元存储中收集表和列统计信息。 Delta Lake 将在 Delta Transaction 日志中收集文件级统计信息,从而实现数据跳过。 一致使用 Glue 目录将防止模式重复。

Spark 可以在读取 Parquet 或 Delta Lake 表时找出架构。 对于 Parquet 和 JSON 表,您可以通过为 Spark 提供一个文件来推断架构,然后在下一次传递中读取整个文件夹来加速架构推断。元存储可以避免这种麻烦并加快您的查询速度。

【讨论】:

  • 感谢您的回答!抱歉,我没有澄清,目前我使用 Azure 云
  • 在 Azure 上,您可以创建一个外部数据库并将其用作 Meta Store。这对于在 HD Insights 和多个 Azure Databricks 工作区之间共享数据集很有用。
  • 是的,但是如何在那里部署模式?每个模式是否应该有两个版本:一个用于单元测试的 StructType 代码定义和另一个用于 Metastore 的 Hive 或 SQL 定义?并始终检查它们是否同步?
  • 我还没有考虑过所有的单元测试、集成测试场景。如果是单元测试,它应该是自包含的吗?那么您可能需要模式对象的本地副本。如果是集成测试,那么您可以从元存储中提取模式。 spark.read.table("my_table").schema
猜你喜欢
  • 2022-08-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-17
  • 1970-01-01
相关资源
最近更新 更多