4. Azure Data Lake Storage Gen2基础

Azure Data Lake Storage Gen2(简称 ADLS Gen2)并不是一个独立于 Azure Storage 之外的新服务,而是在 Azure Blob Storage 之上启用了分层命名空间(Hierarchical Namespace,HNS)后形成的一套面向大数据分析的存储能力。理解这一点非常关键:它既保留了 Blob 存储的海量、低成本、多协议访问优势,又通过目录语义补齐了传统对象存储在“重命名、原子目录操作、细粒度权限”上的短板。对于数据仓库与商业分析工程而言,ADLS Gen2 通常承担的是“数据湖落地层”的角色,向上支撑 Synapse、Databricks、Data Factory 等计算与分析服务。

存储账户:ADLS Gen2 的载体

使用 ADLS Gen2 的第一步是创建一个启用了分层命名空间的存储账户。在 Azure 门户中创建存储账户时,需要关注几个决定后续能力的参数:

  • 账户类型:应选择 StorageV2(通用 v2),这是支持 HNS 的账户类型。
  • 性能层:Standard 适合大多数分析场景,Premium 主要用于低延迟块 Blob 场景。
  • 冗余:LRS、ZRS、GRS、GZRS 决定副本范围,分析型数据湖常用 LRS 或 ZRS 控制成本。
  • 分层命名空间:必须勾选“启用分层命名空间”,一旦启用后不可关闭。

需要特别注意的是,HNS 是创建时的一次性决策。如果先建了普通 Blob 账户再想启用,只能新建账户并迁移数据。因此在实际项目中,建议在命名规范阶段就明确哪些账户用于数据湖、哪些用于普通对象存储。

容器、目录与文件的三层结构

启用 HNS 后,ADLS Gen2 的路径模型从 Blob 的“容器 + Blob 名”演变为更接近文件系统的三层结构:

https://<account>.dfs.core.windows.net/<container>/<directory>/<file>

示例:
https://stdatalake01.dfs.core.windows.net/raw/sales/2024/06/orders.parquet

其中 container 是顶层隔离单元,directory 可以多级嵌套,file 是最终的数据对象。与普通 Blob 不同,这里的目录是真实存在的元数据实体,而不是靠前缀模拟出来的“伪目录”。这带来两个直接好处:一是重命名或删除整个目录是原子操作,不需要逐个对象遍历;二是可以对目录直接设置访问控制,而不必对每个文件单独授权。

访问 ADLS Gen2 时有两个端点:blob.core.windows.net 用于 Blob API,dfs.core.windows.net 用于 Data Lake API(支持目录操作)。分析类工具通常使用 dfs 端点。

分层命名空间带来的能力差异

为了更直观地理解 HNS 的价值,可以用下面的对比来把握它与普通 Blob 存储的核心区别:

能力普通 Blob(无 HNS)ADLS Gen2(启用 HNS)
目录语义前缀模拟,非真实目录真实目录,支持原子操作
重命名目录需逐个复制删除单次原子重命名
权限粒度容器级为主目录/文件级 POSIX ACL
典型访问协议Blob REST、SMBBlob REST、DFS REST、ABFS
分析引擎适配可用但效率一般为大数据分析优化

这张对比表说明:如果只是存放静态文件,普通 Blob 足够;但只要涉及大规模分析、频繁的目录级操作和细粒度权限,ADLS Gen2 就是更合适的选择。

访问控制:RBAC 与 ACL 的配合

ADLS Gen2 的访问控制是两层机制叠加的结果,理解它们的先后关系是避免“权限明明给了却访问不了”的关键。

第一层是 Azure RBAC,作用于管理平面和账户/容器级别。常见角色包括:

  • Storage Blob Data Owner:完全控制,包括设置 ACL。
  • Storage Blob Data Contributor:读写数据,但不能管理 ACL。
  • Storage Blob Data Reader:只读数据。

第二层是 POSIX 风格 ACL,作用于目录和文件级别,包含访问 ACL 和默认 ACL。访问 ACL 决定“当前对象谁能访问”,默认 ACL 决定“在该目录下新建的子项继承什么权限”。ACL 条目形如 user:<objectId>:rwx,其中 r 读、w 写、x 执行(对目录而言表示可遍历)。

RBAC 与 ACL 是“与”关系:即使 ACL 给了读写权限,如果调用者在 RBAC 层面没有 Storage Blob Data Reader/Contributor 等数据角色,仍然无法访问。排障时应先查 RBAC,再查 ACL。

一个常见的授权示例是:给分析团队授予容器级 Storage Blob Data Contributor,然后在 /curated 目录上设置默认 ACL,使新建文件自动继承 group:analysts:r-x,从而保证团队既能读又能写,而其他组只能读 /raw。

数据组织策略:分区与目录设计

目录结构直接决定查询性能和治理成本。ADLS Gen2 中最常见的组织方式是按时间与业务维度分区,例如:

/raw/source=sales/ingest_date=2024-06-01/part-0001.parquet
/curated/fact_orders/year=2024/month=06/day=01/part-0001.parquet
/sandbox/user=zhangsan/experiment_01/

这种 key=value 形式的目录名可以被 Spark、Synapse 等引擎自动识别为分区列,从而在查询时进行分区裁剪,只扫描相关目录。设计时应遵循几条原则:

  1. 分层清晰:raw / curated / sandbox 分离,避免原始数据与加工数据混放。
  2. 分区粒度适中:按天分区通常合适,过细(如按小时)会产生大量小文件,过粗则裁剪效果差。
  3. 避免小文件:大量小文件会拖慢目录列举和查询规划,应定期合并。
  4. 命名规范统一:统一使用小写、连字符或下划线,避免大小写和特殊字符带来的兼容问题。

下面的示意图把存储账户、容器、目录、文件以及 RBAC/ACL 两层访问控制放在同一张图中,帮助建立整体结构认知:

ADLS Gen2 存储结构与访问控制 存储账户 StorageV2(启用 HNS) stdatalake01.dfs.core.windows.net · Standard_LRS · 分层命名空间 = 已启用 容器 Container raw · curated · sandbox (顶层隔离单元) 目录 Directory(真实元数据实体,支持原子重命名) /raw/source=sales/ ingest_date=2024-06-01/ /curated/fact_orders/ year=2024/month=06/day=01/ /sandbox/user=zhangsan/ experiment_01/ 文件 File part-0001.parquet · orders.parquet · _success(Parquet / CSV / JSON 等) RBAC(账户/容器级) Storage Blob Data Reader / Contributor / Owner POSIX ACL(目录/文件级) user:<id>:rwx · group:<id>:r-x · 默认 ACL 继承

在实际落地时,建议把“账户—容器—目录—文件”的层级与“RBAC—ACL”的控制层级一起纳入数据湖设计文档。账户和容器决定隔离与成本边界,目录结构决定查询效率与分区裁剪效果,而 RBAC 与 ACL 共同决定谁能看到什么、能改什么。只有把结构设计与权限设计同步考虑,ADLS Gen2 才能真正成为可靠、可治理的分析数据底座。