2. Azure存储与数据湖基础

在Azure上做数据建模与分析工程,第一步往往不是写SQL或建模型,而是把数据“放对地方”。Azure提供了两类最常用的存储底座:Azure Blob Storage与Azure Data Lake Storage Gen2(ADLS Gen2)。理解它们的差异、层级命名空间的作用、分区与文件格式的选型,以及如何把本地数据迁移上云,是后续所有分析工作的地基。

Blob Storage与ADLS Gen2:同源但不同能力

Blob Storage是Azure的对象存储服务,以“容器/Blob”两级结构组织数据,适合存放图片、日志、备份、非结构化文件。它按块(Block)、追加(Append)、页(Page)三种Blob类型区分写入方式,其中Block Blob最常用于分析场景。ADLS Gen2并不是另一套独立存储,而是在Blob Storage之上启用了层级命名空间(Hierarchical Namespace, HNS)。启用HNS后,存储账户中的对象从“扁平键值”变为“目录+文件”的树形结构,目录成为真实实体,重命名、删除目录变成原子操作,而不是对每个对象逐个改写。

这一差异直接影响分析性能。在未启用HNS的Blob中,重命名一个“目录”实际上是对该前缀下所有Blob逐个复制再删除,数据量大时耗时且可能产生中间状态;启用HNS后,一次目录重命名只改元数据,近乎瞬时。此外,ADLS Gen2支持POSIX风格的ACL权限,可在目录级设置访问控制,配合Azure RBAC实现细粒度安全。因此,面向大数据分析、需要目录语义和细粒度权限的场景,应优先选择ADLS Gen2;纯对象存储、静态资源托管等场景,普通Blob即可。

Blob Storage 与 ADLS Gen2 结构对比 Blob Storage(扁平命名空间) 容器 / Blob 键值对,无真实目录 容器:raw-data sales/2024/01/data.parquet sales/2024/02/data.parquet sales/2024/03/data.parquet 重命名“sales”目录 = 逐个复制+删除所有Blob 无目录级ACL,权限只能到容器或Blob “/”只是键名中的普通字符 ADLS Gen2(层级命名空间) 目录为真实实体,支持原子操作与ACL 文件系统:raw-data 📁 sales/ → 📁 2024/ → 📁 01/ 📁 sales/ → 📁 2024/ → 📁 02/ 📁 sales/ → 📁 2024/ → 📁 03/ 重命名“sales”目录 = 一次元数据原子操作 支持目录级POSIX ACL + Azure RBAC “/”是真实目录分隔符

层级命名空间带来的目录语义

启用HNS后,ADLS Gen2的路径形如 abfss://<文件系统>@<账户>.dfs.core.windows.net/<目录>/<文件>。注意协议头是 abfss(安全)或 abfs,端点使用 dfs.core.windows.net,而普通Blob使用 blob.core.windows.net。在Spark、Synapse、Databricks中读取ADLS Gen2时,通常使用 abfss:// 路径。目录语义让分区管理更自然:可以按 year=2024/month=01/day=15/ 这样的Hive风格目录组织数据,查询引擎能自动进行分区裁剪,只扫描相关目录,显著减少I/O。

数据分区策略

分区是把大表按某列切分成多个子目录,使查询只读取必要部分。分区键的选择要匹配查询过滤条件。常见做法是按时间分区(年/月/日),因为分析查询大多带时间范围。分区粒度需要权衡:分区太粗,单分区数据量大,扫描慢;分区太细,小文件过多,元数据开销和打开文件成本上升。经验上,单个分区文件建议在128MB~1GB之间。若某列基数极高(如用户ID),不适合直接做分区键,可考虑分桶或Z-Order优化。

分区目录命名推荐使用 列名=值 形式,例如 region=cn-east/year=2024/month=06/,这样Spark和Synapse能自动推断分区列。避免在分区值中使用空格、特殊字符或中文,统一用小写和连字符,减少跨工具兼容问题。

文件格式选型

分析场景的文件格式选择直接影响存储成本与查询性能。常见格式对比如下:

格式存储方式压缩适用场景是否可拆分
CSV行式文本需外挂gzip等交换、小数据、人工可读gzip不可拆
JSON行式文本需外挂半结构化、嵌套数据视压缩而定
Parquet列式内置Snappy等分析主力,列裁剪+谓词下推可拆分
ORC列式内置ZLIB等Hive生态,高压缩比可拆分
Avro行式内置流式写入、Schema演进可拆分

结论很明确:面向分析的数据湖落地层,优先使用Parquet。它列式存储、自带Schema、压缩率高、支持谓词下推,Spark、Synapse、Power BI都能高效读取。原始接入层可保留CSV/JSON作为“原始区”,经清洗后转为Parquet写入“精炼区”。

从本地数据到云存储的迁移

把本地数据搬到Azure,常用工具有AzCopy、Azure Storage Explorer、Azure Data Factory和Azure Storage Mover。小规模一次性迁移用AzCopy命令行最直接。以下示例把本地目录上传到ADLS Gen2:

azcopy login --tenant-id <tenant-id>

azcopy copy "C:\data\sales\*" \
  "https://mystorageaccount.dfs.core.windows.net/raw-data/sales/" \
  --recursive --preserve-smb-info=false

# 仅同步新增或变更文件
azcopy sync "C:\data\sales" \
  "https://mystorageaccount.dfs.core.windows.net/raw-data/sales/" \
  --recursive

迁移时需注意:ADLS Gen2的端点用 dfs.core.windows.net;若账户启用了HNS,AzCopy会自动使用目录语义。对于TB级以上或需要调度、增量、监控的场景,应使用Azure Data Factory的Copy Activity,配合自托管集成运行时访问本地网络,并设置调度触发器实现周期性增量同步。

迁移前先规划目标目录结构:原始区(raw)、精炼区(curated)、消费区(serving)分层存放。原始区保留源格式,精炼区转Parquet并按时间分区,消费区面向具体报表或模型。这样后续建模时路径清晰,权限也易于按层分配。
启用层级命名空间是存储账户创建时的选项,账户创建后无法在普通Blob与ADLS Gen2之间直接切换。若计划用于大数据分析,应在创建账户时就启用HNS,避免后期迁移重建。

掌握存储底座的结构差异、分区与格式选型、以及迁移工具的使用,就为后续的数据建模、ETL编排和性能调优打下了可靠基础。下一阶段的工作,都将建立在这些目录、文件和权限约定之上。