文章/2026 年 Google Cloud DLP API 实操:inspect vs deidentify、自定义 infoType、按 GB 计费的陷阱
工具评测

2026 年 Google Cloud DLP API 实操:inspect vs deidentify、自定义 infoType、按 GB 计费的陷阱

Cloud DLP(现在叫 Sensitive Data Protection)官方文档把 API 写清楚了,但跳过了开发者一定要踩的几个坑:自定义 infoType 的 RE2 正则、429 配额、按 GB 计费撞上 BigQuery 大表那一刀。

2026年5月25日阅读时间: 12 分钟0 个主题标签
阅读过渡

上面是文章摘要,下面进入正文深读。可以配合目录逐段阅读,不会丢掉上下文。

工具评测8 个章节

上一个 sprint 我给一个 fintech 团队搭 PII 脱敏层,把客服 ticket 喂给微调任务前先洗一遍——Google Cloud DLP 是 GCP 原生方案里唯一一个能在 project 内闭环跑的 inline 脱敏选项。第一天就把 content.inspect 跑通了。第二天给客户的内部账号 ID 格式写了个自定义 infoType,对照一份明知有十处命中的样本跑——返回零 findings。第三天我学到了什么是 RE2。

如果你是从 "cloud data loss prevention api" 这种查询跳进来的,那个自定义正则的坑大概率是你第一周要撞的墙。这篇围绕 Cloud DLP API(改名但没改 API 的 Sensitive Data Protection)讲文档跳过的几层:inspect 和 deidentify 和 storage job 分别该什么时候用,自定义 infoType 怎么写才能真匹配,定价数学在量上来之后怎么变难看,哪些 transformation 能反推回去。

改名是文档问题,不是产品问题

Google 在 2023 年某时候把 Cloud Data Loss Prevention 改成了 Sensitive Data Protection,2026 年这个 rollout 还是参差不齐。Console 里产品页写"Sensitive Data Protection",但作为开发者你碰到的所有东西还是 "DLP":

触面 2026 年实际叫法
营销页、Console UI Sensitive Data Protection
API endpoint dlp.googleapis.com
gcloud 命令 gcloud dlp ...
Python 客户端 google-cloud-dlp
Service account 角色 roles/dlp.user, roles/dlp.admin
账单条目 "Sensitive Data Protection"
Stack Overflow 标签 google-cloud-dlp

实战影响:搜新名字适合找产品总览和定价页,搜老名字适合找代码示例。两个名字最终落到同一份文档,但首页搜索结果会分裂,不知道是同一个东西的话能空跑半小时。

四个 API surface 分别怎么选

DLP 的端点比大多数团队意识到的要多,挑错一个不是慢就是贵或者两个都中。决策树主要看你的数据是 inline 还是 at rest:

Surface 端点 同步? 什么时候用
Content inspect projects.content.inspect 单个 payload < 0.5MB 的 inline 扫描(聊天消息、ticket、表单提交)
Content deidentify projects.content.deidentify 同上,但在路过的时候顺手脱敏
Content reidentify projects.content.reidentify 反推 deterministic 或者 FPE 脱敏
Storage job projects.dlpJobs.createINSPECT_JOB 类型) 审计整个 GCS bucket / BigQuery 表 / Datastore kind
Discovery projects.discoveryConfigs.create 跨多个数据集的持续画像

容易踩坑的分歧是 inline 和 at-rest 计费模型不一样。Content 端点按请求里发的 GB 数算钱。Storage job 按它原地扫的 source 数据 GB 算。Discovery 是另一档更低的费率做定期画像。一个团队用循环跑 content.inspect 扫一百万行 BigQuery,付的钱大约是用一次 dlpJobs.create 扫同一张表的 100 倍——因为 content 路径每个请求都计费,job 是按表扫一次摊销的。

二十行跑通 content.inspect

最小可用的 inspect 调用,用 Python 客户端:

from google.cloud import dlp_v2

PROJECT_ID = "your-project"

client = dlp_v2.DlpServiceClient()
parent = f"projects/{PROJECT_ID}/locations/global"

inspect_config = {
    "info_types": [
        {"name": "EMAIL_ADDRESS"},
        {"name": "PHONE_NUMBER"},
        {"name": "CREDIT_CARD_NUMBER"},
    ],
    "min_likelihood": dlp_v2.Likelihood.POSSIBLE,
    "include_quote": True,
    "limits": {"max_findings_per_request": 100},
}

response = client.inspect_content(
    request={
        "parent": parent,
        "inspect_config": inspect_config,
        "item": {"value": "Reach me at user@example.com or 415-555-0142."},
    }
)

for f in response.result.findings:
    print(f"{f.info_type.name}: {f.quote} ({f.likelihood.name})")

输出:

EMAIL_ADDRESS: user@example.com (LIKELY)
PHONE_NUMBER: 415-555-0142 (LIKELY)

三件事要记住:

  1. min_likelihood 是最重要的旋钮。 DLP 用五级置信度报 findings:VERY_UNLIKELYUNLIKELYPOSSIBLELIKELYVERY_LIKELY。设 POSSIBLE 能抓到大部分真 PII,代价是会有些假阳性(一串随机数字被识别成电话)。设 LIKELY 噪声少但漏部分命中。默认是 POSSIBLE
  2. include_quote: True 默认开,但要知道它在干嘛。 quote 字段返回匹配的子串,调 infoType 选型时是关键调试信息,但它本身就是敏感数据,会被打进日志。生产路径上只需要 count 不需要 value 的时候关掉。
  3. parentlocations/global DLP 也支持区域端点(比如 locations/us-central1)把请求保持在单一区域内做数据驻留。global 在临时扫描时更快,但不给区域保证。

自定义 infoType:regex(RE2)、字典、hotword

150+ 内建 infoType 覆盖了常见标识符(信用卡号、政府 ID、姓名、地址、医疗代码),但每个项目最终都会需要至少一个自定义。三种类型:

正则。 一个让 DLP 在内容里匹配的 pattern。坑在于 DLP 用的是 RE2,不是 PCRE 也不是 Python re。RE2 没有 lookbehind、lookahead、backreference。pattern 用了这些会静默返回零 findings——没有语法错误,没有警告,就是空结果。症状:你的测试样本里明明有命中,API 坚持说没有。

custom_info_types = [
    {
        "info_type": {"name": "ACCOUNT_ID"},
        "regex": {"pattern": r"ACC-[0-9]{8}"},
        "likelihood": dlp_v2.Likelihood.LIKELY,
    }
]

调试技巧:把 pattern 贴到 regex101.com 把 flavor 切到 RE2 (Go),或者本地 re2 包编一下。那里编不过,DLP 里也不会匹配。

字典。 一组精确匹配的词或短语。DLP 可以接 inline 数组(word_list),也可以接 GCS 上的文件(cloud_storage_path)。inline 上限大约 50KB。更大的列表(员工名、产品 SKU、客户 ID)就把一词一行的文本文件丢 GCS 上引用。

Hotword(邻近规则)。 在某个 "hot word" 出现在 N 字节内时调整另一个 infoType 的 likelihood。典型用法是抓"SSN" 旁边的 9 位数字——单独的数字是 POSSIBLE,靠近 "SSN" 的就升到 VERY_LIKELYproximity 字段是按字节算的,不是字符,UTF-8 下中文一个字 3 字节,写规则要记得乘。

Deidentify:在上规模之前先选好可逆性

Deidentify transformation 分单向和可逆两组。选错了后期改贵——所有历史脱敏数据都按第一天选的方式编码了。

Transformation 可逆? 什么时候用
ReplaceConfig "把 EMAIL 替换成 [REDACTED_EMAIL]" 最简单
RedactConfig 整段删掉,不留占位
MaskConfig "每位数字替换为 X",保形不保值
CryptoHashConfig(HMAC) 跨次运行稳定的伪 ID,但不能还原
CryptoDeterministicConfig join key 用的 tokenize——同输入同 token
CryptoReplaceFfxFpeConfig(FPE) 保留格式(16 位输入 → 16 位输出),下游有格式校验时
DateShiftConfig 部分 按 context 偏移日期;偏移量即密钥
BucketingConfig 年龄换成 30-39 这种区间

CryptoReplaceFfxFpeConfig(FPE)是团队反复讨论的一个。FPE 保持输出字母表和输入一致——一张被 FPE 脱敏的信用卡号还是 16 位、还能过 Luhn 校验(如果开了的话)、还能塞进 VARCHAR(16) 列。代价是运维:FPE 需要一个 key wrapper(通常是 Cloud KMS 包过的 AES 密钥),密钥轮换的方案要你自己设计。

如果脱敏数据的下游消费者只是模型或者 dashboard,CryptoDeterministicConfig 一般够用——产出 token 稳定但不保格式,schema 能存就行。

量上来之后的定价数学

Cloud DLP 定价是那种单价低、量一上来很惨的服务。按 Google 公开定价(架构定型前请到 Sensitive Data Protection pricing 页确认当前费率):

操作 按 Google 定价(约)
content.inspect 超出每月 1GB 免费层 约 $1.00/GB 内容
content.deidentify / reidentify 约 $0.50/GB
Storage job inspect 约 $1.00/GB 源数据
Discovery profile 约 $0.03/GB(前 1TB),阶梯递减

[community-verified,具体档次费率会变——sizing 前先到定价页拉当前数字]

三个粗算锚定场景:

  • 聊天 app 每条消息 inline 脱敏。 平均一条 200 字节,每天 100 万条。日量 200MB,1GB 免费层之内——免费。
  • 每天审计一张 100GB 的 BigQuery 表。 Storage job:每天约 $100,每月约 $3,000。Discovery 同样数据集:初次 profile 约 $3,之后随表增长增量计费。Discovery 便宜两个数量级。
  • 一次性扫一份 10TB 历史日志归档。 Storage job:约 $10,240。躲不掉,启动前显式预算这一项。

几乎每个团队都犯过一次的错是用循环跑 content.inspect 扫 BigQuery 行,因为代码比配 job 短。100GB 表用 content 端点逐行扫,账单会比一次 storage job 高一个数量级——因为还要付每请求开销,不只是 GB 量。

配额 429 与退避

DLP 在 project 层级对每个 surface 收配额。生产里常见的几条:

配额 默认(按 Google 文档,撰文时) 触发症状
content.inspect 每分钟每 project 600 429 RESOURCE_EXHAUSTED
dlpJobs.create 每分钟每 project 个位数 提交 job 时 429
单请求内容大小 0.5MB raw / 1MB structured 400 INVALID_ARGUMENT
单请求 findings 数 3000 硬上限 findings 被截断,不报错

撞 429 的正确反应是带 jitter 的指数退避,Google Cloud 客户端库默认带——调用时传 retry=DEFAULT_RETRY。错误的反应是同线程立刻重试,反而把每请求计数顶得更高、没有进展。

600 RPM 真的成为瓶颈的时候(一般不会,高吞吐实时脱敏才会撞),可以拉的杆是批处理:用 table 字段一次 inspect_content 多条结构化记录,按一次请求计配额,处理量到 structured 1MB 上限。

接下来怎么用这篇

打开 Cloud DLP API 目录页拿端点清单,把上面那二十行 inspect_content 跑在自己的 GCP project 上。能拿到 findings 之后,API 后面就是 infoType 和 transformation 的排列组合——面广但 pattern 重复。接下来要设计的是自定义 infoType 策略:GCS 上的字典文件、RE2 兼容的正则、依赖上下文的 hotword 邻近规则。再之后判断你的真实负载是 inline(content 端点)还是 at-rest(job 和 Discovery),在账单教训你之前先把钱路由对。

分享文章

文章概览

读完前先看这几项

分类
工具评测
阅读时间
12 分钟
提到的工具
0
返回文章列表 →

下一步

读完后可以继续回到工具目录,对比具体产品。

去看工具