Title: BigQuery Locale: zh URL: https://sensorswave.cn/docs/data-center/pipeline/destinations/bigquery/ Description: 配置 Google BigQuery 导出数据流,将事件数据和用户数据定期同步到 BigQuery 数据仓库 BigQuery 连接器将 Sensors Wave 中的事件数据和用户数据定期批量同步到您的 Google BigQuery 数据仓库,帮助使用 Google Cloud 生态的数据团队在熟悉的 SQL 环境中进行深度分析,并与其他业务数据进行联合查询。 > **提示**:BigQuery 连接器目前**仅在海外集群提供**。如果您使用国内集群,请改用 Snowflake 或 ByteHouse 连接器。 典型使用场景: - 将用户行为事件同步到 BigQuery,与 Google Ads、GA4、CRM 数据进行 JOIN 分析 - 将用户画像数据导出,结合 Looker、dbt 构建数据模型与报表 - 保留 Sensors Wave 中的历史事件数据,满足合规或长期分析需求 BigQuery 连接器支持两种导出类型: - **事件数据导出**:将用户行为事件增量同步到 `sensorswave_events` 表(默认,可在创建时自定义) - **用户数据导出**:将用户画像属性增量同步到 `sensorswave_users` 表(默认,可在创建时自定义) 每种导出类型需要分别创建一条数据流。 ## 前提条件 在 Sensors Wave 中创建数据流之前,需要在您的 Google Cloud 账号下完成以下准备工作。建议为 Sensors Wave 创建专用的 Service Account,避免权限过大带来安全风险。 以下步骤使用如下对象名称作为示例,实际使用时请按贵司规范调整: | 对象 | 示例名称 | 说明 | |------|---------|------| | Dataset | `sensorswave` | BigQuery 中的数据集 | | Service Account | `sensorswave-user` | 数据流使用的服务账号 | ### 第 1 步:准备 GCP 项目与 Dataset 1. 在 [Google Cloud Console](https://console.cloud.google.com/) 选择或新建一个 GCP 项目。 2. 进入 **BigQuery → BigQuery Studio**,点击项目右侧的「︙」菜单,选择**创建数据集(Create dataset)**。 3. 填写: - **Dataset ID**:自定义,如 `sensorswave` - **Location**:根据贵司业务选择区域(如 `US`、`asia-east1`)。Dataset 创建后无法修改区域 4. 点击**创建数据集**完成。 > **注意**:BigQuery 数据流**不会自动创建 Dataset**。请确保 Dataset 在创建数据流前已存在。 ### 第 2 步:创建 Service Account 并授予 IAM 角色 Sensors Wave 通过 Service Account JSON Key 认证 BigQuery,需要授予以下两个预定义角色: | 角色 | 作用域 | 用途 | |------|--------|------| | `BigQuery Job User`(`roles/bigquery.jobUser`) | 项目级 | 创建 Load Job 与 Query Job | | `BigQuery Data Editor`(`roles/bigquery.dataEditor`) | Dataset 级 | 在目标 Dataset 内创建表、读写表数据、删除临时表 | 操作步骤: 1. 在 Google Cloud Console 进入 **IAM 和管理 → 服务账号**,点击**创建服务账号**。 2. 填写服务账号名称(如 `sensorswave-user`),点击**创建并继续**。 3. 在「向此服务账号授予对项目的访问权限」步骤,选择角色 **BigQuery Job User**,点击**完成**。 4. 进入 **BigQuery → BigQuery Studio**,找到目标 Dataset,点击「⋮」→ **共享**,将服务账号添加为「BigQuery Data Editor」。 > **提示**:如果贵司合规要求最小权限,可以创建自定义角色,仅授予下方所列原子权限: > > - 项目级:`bigquery.jobs.create` > - Dataset 级:`bigquery.datasets.get`、`bigquery.tables.create`、`bigquery.tables.get`、`bigquery.tables.getData`、`bigquery.tables.updateData`、`bigquery.tables.delete` ### 第 3 步:下载 Service Account JSON Key 1. 在服务账号列表中点击刚创建的账号。 2. 切换到**密钥**标签页,点击**添加密钥 → 创建新密钥**,选择 **JSON** 格式,点击**创建**。 3. 浏览器自动下载 JSON Key 文件,妥善保存以备下一步使用。 > **注意**:JSON Key 包含私钥,是敏感凭证。Sensors Wave 会对其加密存储,保存后不再回显。请勿提交到代码仓库或共享给非授权人员。 ### 关于网络访问 BigQuery API(`bigquery.googleapis.com`)默认通过 Google 公网公开访问,**通常无需配置 IP 白名单**。 如果您启用了 [VPC Service Controls](https://cloud.google.com/vpc-service-controls) 限制 BigQuery API 访问,需要将 Sensors Wave 海外集群出口 IP 加入访问策略: - **海外集群出口 IP**:`43.133.171.172` ## 创建导出数据流 完成 GCP 侧的准备工作后,在 Sensors Wave 中创建数据流。 1. 进入**数据中心 → 数据流**,点击**新建数据流**按钮。 2. 在弹出的对话框中,选择**导出数据流**,点击**下一步**。 3. 选择**目标类型**为 **BigQuery**。 4. 选择**数据源类型**: - **事件数据**:同步用户行为事件 - **用户数据**:同步用户信息与属性 5. 填写 BigQuery 连接配置(详见下方「配置参考」): - 将整个 Service Account JSON Key 文件内容粘贴到 **Service Account JSON** 字段,系统自动解析其中的 `project_id` / `client_email` / `private_key` 等字段 - 填写 **Dataset ID** 与 **Table ID** 6. 点击**测试连接**,等待 6 步验证全部通过。 7. 配置**执行频率**(详见下方「执行频率」)。 8. 如需仅同步特定事件,在**高级选项**中配置事件过滤(仅事件数据导出支持)。 9. 点击**保存**,数据流将立即启动,并自动在 BigQuery 中创建目标表。 ## 配置参考 ### 连接配置 | 字段 | 必填 | 说明 | 示例 | |------|------|------|------| | `Service Account JSON` | 是 | 完整粘贴下载的 Service Account JSON Key 文件内容;保存后不再回显 | `{"type": "service_account", "project_id": "...", "private_key": "..."}` | | `Dataset ID` | 是 | 目标 BigQuery Dataset 的 ID | `sensorswave` | | `Table ID` | 是 | 目标表名,可自定义;默认为 `sensorswave_events`(事件)或 `sensorswave_users`(用户),保存后系统自动创建 | `sensorswave_events` | ### 执行频率 **间隔执行**:每隔固定时长(1–23 小时)触发,从数据流创建时刻开始计算。 | 选项 | 适用场景 | |------|---------| | 每 1 小时(默认) | 适合大多数分析场景 | | 每 2 小时 | 数据量较大时降低频率 | | 每 6 小时 | 日常增量同步 | | 每 12 小时 | 用户数据等更新频率较低的场景 | | 每 24 小时 | 每日批量导出 | **定时执行**:在指定时区的固定时刻触发,适合需要在业务低峰期执行的场景。选择时区和执行时刻后,系统将每天在该时刻触发一次。时区仅影响触发时刻的计算,详见[时区说明](#时区说明)。 ## 数据模型 ### 事件表(默认 `sensorswave_events`) 事件数据导出到此表,按 `time` 列**按天分区**(`PARTITION BY DATETIME_TRUNC(time, DAY)`),便于分区裁剪降低查询成本。以下以默认表名为例。 | 列名 | 类型 | 说明 | |------|------|------| | `time` | `DATETIME` | 事件发生时间(墙钟,无时区) | | `distinct_id` | `STRING` | 客户端用户唯一标识 | | `trace_id` | `STRING` | 请求追踪 ID | | `ssid` | `INT64` | 服务端用户唯一标识(SSID) | | `anon_id` | `STRING` | 匿名 ID | | `login_id` | `STRING` | 登录 ID | | `event` | `STRING` | 事件名称,如 `$pageview`、`purchase` | | `properties` | `JSON` | 事件属性 | | `user_properties` | `JSON` | 事件触发时的用户属性快照 | | `received_at` | `DATETIME` | 服务端接收时间(墙钟) | 时间列与 `properties` / `user_properties` 内日期时间字段的时区、格式详见[时区说明](#时区说明)。 查询 `JSON` 类型属性的示例: ```sql -- 查询事件属性中的 order_id 和 total_amount 字段 SELECT time, event, JSON_VALUE(properties, '$."order_id"') AS order_id, CAST(JSON_VALUE(properties, '$."total_amount"') AS FLOAT64) AS total_amount FROM `my-gcp-project.sensorswave.sensorswave_events` WHERE event = 'purchase' AND time >= DATETIME '2026-04-01 00:00:00' LIMIT 100; ``` ### 用户表(默认 `sensorswave_users`) 用户数据导出到此表,按 `ssid` 聚簇(`CLUSTER BY ssid`),加速按用户 ID 的点查;采用 MERGE 写入模式(按 `ssid` 匹配,存在则更新、不存在则插入)。 | 列名 | 类型 | 说明 | |------|------|------| | `ssid` | `INT64` | 服务端用户唯一标识 | | `login_id` | `STRING` | 登录 ID | | `anon_id` | `STRING` | 匿名 ID | | `properties` | `JSON` | 用户属性,包含所有用户画像属性 | | `created_at` | `DATETIME` | 用户首次创建时间(墙钟) | | `updated_at` | `DATETIME` | 用户属性最近更新时间(墙钟) | 查询 `JSON` 类型用户属性的示例: ```sql -- 查询用户属性中的会员等级 SELECT ssid, login_id, JSON_VALUE(properties, '$."membership_level"') AS membership_level, updated_at FROM `my-gcp-project.sensorswave.sensorswave_users` WHERE JSON_VALUE(properties, '$."membership_level"') IS NOT NULL LIMIT 100; ``` ## 时区说明 BigQuery 数据流涉及多种时区语义,以下内容汇总了所有受时区影响的值与对应来源。 ### 时区影响速览 | 值 | 时区 | 由谁决定 | |----|------|---------| | 时间列(`time`、`received_at`、`created_at`、`updated_at`) | UTC(海外集群墙钟时区) | SensorsWave服务器,无法更改 | | `properties` / `user_properties` 中的日期时间属性 | UTC(与时间列一致) | 与时间列一致 | | 回填日期范围时区 | **项目时区** | 管理员在项目设置中配置 | | 定时执行触发时刻 | 用户配置时区 | 创建数据流时填写 | ### 时间列 BigQuery 中所有时间列(`time`、`received_at`、`created_at`、`updated_at`)使用 `DATETIME` 类型(墙钟时间,无时区元数据),存储 **UTC 墙钟**,**精确到毫秒**(与 `properties` / `user_properties` 中日期时间字段的精度一致)。BigQuery 数据流仅在海外集群提供,海外集群墙钟时区即 `UTC`。 **示例**:某事件发生在 UTC 时间 `2026-04-13 07:30:00.123`,BigQuery 中 `time` 列存储为 `2026-04-13 07:30:00.123`。 如需在查询侧转换到其他时区,先用 `TIMESTAMP(col, 'UTC')` 转为 `TIMESTAMP` 再用 `DATETIME(..., '')` 渲染: ```sql SELECT DATETIME(TIMESTAMP(time, 'UTC'), 'America/New_York') AS time_local FROM `my-gcp-project.sensorswave.sensorswave_events`; ``` ### JSON 属性中的日期时间字段 如果事件或用户属性本身是日期时间类型,序列化到 `properties` / `user_properties` 后以字符串形式存储: - **格式**:`YYYY-MM-DD HH:MM:SS.fff`(精确到毫秒,不含时区偏移) - **时区**:与时间列一致,为 UTC 墙钟 **示例**:`{"purchase_at": "2026-04-13 07:30:00.000"}` ### 回填日期范围时区 BigQuery 回填使用 **项目时区** 解释回填日期范围。项目时区由管理员在项目设置中配置;若未设置则使用系统默认时区 `UTC`。 回填日期范围按 **左闭右开** 区间 `[start, end)` 解释:包含 `start` 时刻、不包含 `end` 时刻——相邻两次回填可以在边界处无缝衔接,不会重复覆盖事件。 **示例 1:项目时区与时间列时区一致(项目时区 = `UTC`)** 回填 `2026-04-01 ~ 2026-04-03` 会被解释为: - `start = 2026-04-01 00:00:00`(UTC,开始日期当天 0 时) - `end = 2026-04-04 00:00:00`(UTC,结束日期次日 0 时) 由于 BigQuery `time` 列也以 UTC 墙钟存储,该区间正好覆盖 3 个自然日的事件。 **示例 2:项目时区与时间列时区不一致(项目时区 = `America/New_York`,时间列 = UTC)** 回填 `2026-04-01 ~ 2026-04-01` 会被解释为: - 按 **项目时区 `America/New_York`** 表示:`[2026-04-01 00:00:00 EDT, 2026-04-02 00:00:00 EDT)` - 按 BigQuery `time` 列存储的 **UTC 墙钟** 换算:`[2026-04-01 04:00:00, 2026-04-02 04:00:00)` 因此本次回填覆盖的 `time` 范围是 UTC 下的 `2026-04-01 04:00 ~ 2026-04-02 04:00`,**不是** UTC 下 4 月 1 日的全天数据。 > **注意**:回填日期范围的解释时区与时间列的存储时区可能不同。回填日期范围按项目时区解释,时间列固定以 UTC 墙钟存储。若两者不一致,回填实际覆盖的 `time` 范围会与「项目时区下的自然日」对齐,而非 UTC 下的自然日。 ### 定时执行触发时区 配置定时执行时需指定时区。例如配置 `America/New_York` 02:00,则每天纽约时间凌晨 2 点触发。该时区仅影响触发时刻计算,不影响时间列的存储值与回填日期范围的解释。 ## 事件过滤 事件过滤仅适用于**事件数据导出**,支持以下两种模式: - **包含事件(白名单)**:只导出列表中指定的事件,其余事件不导出 - **排除事件(黑名单)**:导出所有事件,但跳过列表中指定的事件 在**高级选项**中选择过滤模式并填写事件名称列表(如 `$pageview`、`purchase`)。 > **注意**:事件过滤修改后,在当前同步窗口完成后的下一个窗口生效,不会重新处理已导出的数据。 ## 测试连接 点击**测试连接**后,系统会端到端验证 BigQuery 配置(认证、Dataset 访问、建表权限、Load Job 权限、查询权限)。 ### 常见连接错误 | 错误提示 | 可能原因 | 解决方法 | |---------|---------|---------| | Service Account JSON 字段缺失 | 粘贴的 JSON 格式不完整或缺失关键字段 | 确认 JSON 包含 `project_id` / `private_key` / `client_email` / `token_uri` | | 认证失败 | `private_key` 无效,或服务账号已被禁用 / 删除 | 在 Cloud Console 检查服务账号状态,必要时重新生成 JSON Key | | Dataset 不存在或无访问权限 | Dataset 拼写错误,或服务账号未被授予 `BigQuery Data Editor` | 检查 Dataset 名称,确认服务账号已通过 Dataset 共享授权 | | 无 Job 创建权限 | 服务账号缺少 `BigQuery Job User` 项目级角色 | 在 IAM 页面为服务账号添加项目级 `BigQuery Job User` 角色 | ## 数据流管理与监控 ### 数据流状态 数据流的生命周期状态如下: ``` 新建 → 运行中 → 已停止(不可逆) ``` > **注意**:停止数据流是不可逆操作。停止后,所有调度将终止,不再产生新的同步任务。如需恢复导出,必须重新创建数据流。历史运行记录在停止后仍可查看。 ### 查看运行记录 在数据流详情页面的**运行记录**标签页,可以查看每次同步任务的执行情况: - **状态**:运行中(Running)/ 成功(Success)/ 失败(Failed) - **数据范围**:本次同步覆盖的时间窗口 - **导出行数**:本次成功写入 BigQuery 的行数 - **执行时间**:任务开始和结束时间 - **日志**:点击单条记录可展开查看详细执行日志 ### 查看统计指标 **指标**标签页展示数据流的整体运行状态(默认最近 30 天): - 成功 / 失败运行次数趋势图 - 每日导出行数趋势图 - 支持自定义时间范围筛选 ## 历史数据回填 ### 什么是回填 数据流创建后,增量同步仅处理从创建时刻起的新数据。如果需要将创建时刻之前的历史数据也导入 BigQuery,需要使用回填(Backfill)功能。 ### 操作步骤 1. 进入数据流详情页,切换到**回填**标签页。 2. 点击**发起回填**,选择需要补充的日期范围(开始日期和结束日期)。 3. 确认回填日期后,点击**确认执行**。 > **注意**:回填日期范围按 **项目时区** 解释为具体的开始/结束时刻,详见[时区说明](#时区说明)。 ### 回填与增量同步的关系 - 回填运行期间,该数据流的增量定时同步会**自动暂停**,不会丢失数据——回填完成或取消后,增量同步从上次的位置继续 - 同一数据流同时只允许一个回填任务在运行 - 回填中断(如服务重启)后,系统自动从上次完成的窗口继续,已完成的窗口不会重复执行 ### 取消回填 在回填进行中,可点击**取消**终止当前回填。取消操作在当前窗口执行完成后生效,不会中断正在进行的窗口。 ## 投递语义与数据一致性 | 数据类型 | 任务类型 | 写入方式 | 投递语义 | |---------|---------|---------|---------| | 事件数据 | 定时增量同步 | 追加 | at-least-once | | 事件数据 | 历史回填 | 多语句事务按窗口原子替换 | exactly-once(窗口内) | | 用户数据 | 定时增量同步 / 历史回填 | 按 `ssid` 匹配更新 | exactly-once | ## 注意事项 - **仅在海外集群提供**:本连接器目前不支持国内集群 - **Dataset 须预先创建**:数据流不会自动创建 Dataset,请在 GCP Console 中提前创建并指定 Location - **目标表自动创建**:保存数据流时,系统自动在 BigQuery 中创建目标表(含分区与聚簇配置),无需提前手动建表 - **Service Account JSON 安全**:JSON 中的 `private_key` 加密存储,保存后不再回显;编辑数据流时如未填新值则复用已存凭证 - **停止数据流不可逆**:停止后需重新创建数据流,历史运行记录保留 - **回填期间增量暂停**:回填运行期间定时增量同步暂停,回填完成后自动恢复,数据不丢失 - **时间列为 UTC 墙钟**:BigQuery 中的时间列存储 UTC 墙钟时间,跨时区分析时注意换算 - **事件重复行**:`sensorswave_events` 原始表中可能出现少量重复行。 **发生原因**:事件表的定时增量同步采用追加写入、at-least-once 投递语义,重复主要来自以下两个场景。 - **场景一:增量任务故障重试**。定时增量同步在写入过程中如遇节点故障、网络异常或 BigQuery Load Job 超时,会自动重试当前批次以保证不丢数据。Load Job 使用固定 Job ID 实现幂等,但部分边界场景仍可能在事件表中追加重复行。此场景偶发,影响范围小。 - **场景二:回填与增量叠加**。历史回填在自身窗口内是原子替换(重复执行同一窗口不会产生重复),但它与定时增量是两条独立链路,各自独立写入。事件的 `time` 字段记录事件实际发生时间,而增量同步按事件在服务端的入库时间推进,当两条链路覆盖到同一条迟到事件时就会产生重复。如果某事件发生于 `T`、延迟到 `T + N` 才上报入库: 1. 用户发起回填,回填按事件发生时间筛选数据,覆盖 `T`。此时该事件已在历史存储中(入库时间为 `T + N`),回填按事件时间 `T` 将其导出到 BigQuery。 2. 回填完成后,增量同步从上次的入库位点继续推进,到达 `T + N` 时再次将这条迟到事件导出。 用户数据无论是定时增量还是回填,都按 `ssid` 匹配更新,投递语义为 exactly-once,不存在上述问题。 **解决方案**:以下两种方式可任选其一,也可组合使用。 **方案一:创建去重视图(推荐作为日常查询入口)** 在 BigQuery 中创建去重视图,按事件唯一标识保留最新一行: ```sql CREATE VIEW `my-gcp-project.sensorswave.sensorswave_events_dedup` AS SELECT * EXCEPT (rn) FROM ( SELECT *, ROW_NUMBER() OVER ( PARTITION BY time, event, distinct_id, trace_id ORDER BY received_at DESC ) AS rn FROM `my-gcp-project.sensorswave.sensorswave_events` ) WHERE rn = 1; ``` **方案二:仅回填 7 天之前的数据** 服务端对迟到超过 7 天的事件不再允许入库,因此 7 天之前的时间窗口不会再有新的迟到事件通过增量同步进入 BigQuery。将回填的结束日期限制在「当前日期 - 7 天」之前,即可从源头避免重复。如需补齐最近 7 天内的数据,建议沿用方案一通过去重视图查询。 ## 常见问题 **Q:测试连接失败,提示「Dataset 不存在」,如何处理?** 确认 Service Account JSON 中的 `project_id` 与 BigQuery Dataset 所属项目一致;检查 Dataset 名称大小写;确认已为服务账号在 Dataset 上授予 `BigQuery Data Editor` 角色。 **Q:测试连接通过,但运行后报「permission denied on bigquery.jobs.create」,如何处理?** 服务账号缺少项目级 `BigQuery Job User` 角色。在 Cloud Console 进入 **IAM 和管理 → IAM**,找到对应服务账号,授予 `BigQuery Job User` 角色。 **Q:数据流已在「运行中」,能否修改连接配置或事件过滤?** 支持修改。进入数据流详情,点击**编辑**修改配置。修改在当前同步窗口完成后的下一个窗口生效;调度频率修改后立即生效。如果需要更换 Service Account JSON,重新粘贴整个 JSON 文件内容即可。 **Q:事件表中出现重复行怎么办?** 事件表采用 at-least-once 投递语义,重复主要来自两类场景:一是增量同步任务在故障重试时重复写入同一批次(偶发);二是回填覆盖了某条迟到事件的发生时间 `T`,回填按事件时间将其导出后,增量同步推进到入库时间 `T + N` 时再次导出。处理方式有两种: - **查询侧去重**:使用上方「注意事项」中的去重视图 `sensorswave_events_dedup` 作为日常查询入口,或按 `time`、`event`、`distinct_id`、`trace_id` 四个字段组合使用 `ROW_NUMBER()` 去重,保留 `received_at` 最新的记录。 - **回填侧规避**:仅回填「当前日期 - 7 天」之前的数据。 **Q:`properties` 和 `user_properties` 中的 `JSON` 数据如何查询?** BigQuery 原生支持 `JSON` 类型,使用 `JSON_VALUE` 提取标量字段、`JSON_QUERY` 提取嵌套对象或数组: ```sql -- 提取字符串类型字段 SELECT JSON_VALUE(properties, '$."page_url"') AS page_url FROM `my-gcp-project.sensorswave.sensorswave_events`; -- 提取数值类型字段(需 CAST) SELECT CAST(JSON_VALUE(properties, '$."item_count"') AS INT64) AS item_count FROM `my-gcp-project.sensorswave.sensorswave_events`; -- 提取嵌套对象 SELECT JSON_QUERY(properties, '$."address"') AS address FROM `my-gcp-project.sensorswave.sensorswave_events`; ``` **Q:BigQuery 中的 `time` 列是什么时区?** `time` 列使用 `DATETIME` 类型,存储 UTC 墙钟时间(不含时区元数据)。如需转换为其他时区: ```sql SELECT DATETIME(TIMESTAMP(time, 'UTC'), 'America/New_York') AS time_local FROM `my-gcp-project.sensorswave.sensorswave_events`; ``` **Q:是否需要为 BigQuery 配置 IP 白名单?** 通常不需要。BigQuery API 默认通过 Google 公网公开访问,仅在您启用 VPC Service Controls 限制访问时,才需要将 Sensors Wave 海外集群出口 IP `43.133.171.172` 加入访问策略。 **Q:BigQuery 数据流是否支持国内集群?** 暂不支持。BigQuery 连接器目前仅在海外集群提供。 --- **最后更新时间**:2026 年 5 月 6 日