【发布时间】: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 编写的数据帧架构。但这不是最好的解决方案,因为:
-
我想在第一次写入之前进行架构定义。例如,我将 500 列的数据集转换为 100 列,并希望根据架构定义仅选择所需的列。
-
存在使用其他工具(如 ADF 或 Nifi)摄取(写入)的只读数据集
更新
我喜欢使用 AWS Glue(EMR 用作 Hive Metastore)并通过 Cloud Formation 进行部署的体验。我想 Databricks 有类似甚至更简单的经验,只是想知道最佳实践是什么。
更新 #2
回答问题加分 - 如何在 Databricks 目录(或外部 Hive Meta Store)和我们的代码库之间不重复 shcema 定义?
如果我们使用 SQL 语法来描述我们的模式,我们将无法在单元测试中重用它们。 是否有任何基于上述格式部署模式的干净解决方案(参见代码 sn-p)?
PS:目前我们使用 Azure 云
【问题讨论】:
-
这是显而易见的事情吗?为什么要投反对票?