查询 Cloud Bigtable 数据

本页介绍如何使用 BigQuery 查询 Cloud Bigtable 中存储的数据。

Cloud Bigtable 是 Google 推出的一种稀疏填充的 NoSQL 数据库,它可扩容到数十亿行和数千列,支持存储 PB 级的数据。Cloud Bigtable 具有与 Apache HBase 类似的数据模型,提供与 HBase 兼容的客户端库。如需了解 Cloud Bigtable 数据模型,请参阅存储模型

支持的区域和地区

目前只有以下区域和地区支持查询 Cloud Bigtable 中的数据:
区域 地区
us-central1

us-central1-a

us-central1-b

us-central1-c

us-central1-f

europe-west1

europe-west1-b

europe-west1-c

europe-west1-d

检索 Cloud Bigtable URI

如需为 Cloud Bigtable 数据源创建外部表,您必须提供 Cloud Bigtable URI。检索 Cloud Bigtable URI 的方法如下:

  1. 打开 Cloud Bigtable 控制台。

    打开 Cloud Bigtable 控制台

  2. 检索有关 Cloud Bigtable 数据源的如下详细信息:

    • 您的项目 ID
    • 您的 Cloud Bigtable 实例 ID
    • 您的 Cloud Bigtable 表的名称
  3. 使用以下格式撰写 Cloud Bigtable URI,各变量含义如下:

    • project_id 是包含您的 Cloud Bigtable 实例的项目
    • instance_id 是 Cloud Bigtable 实例 ID
    • table_name 是您要查询的表的名称

    https://googleapis.com/bigtable/projects/project_id/instances/instance_id/tables/table_name

访问控制和范围

永久外部表的访问权限控制

您可以共享对链接到 Cloud Bigtable 数据源的永久外部表的访问权限,但不能共享对临时外部表的访问权限。

您可以与用户(包括服务帐号)或组共享对永久外部表的访问权限。如需查询外部表,(至少)需要为用户或组授予以下角色:

  • 数据集级别或更高级别的 bigquery.dataViewer 角色,可访问包含外部表的数据集
  • 项目级别或更高级别的 bigquery.user 角色,可运行查询作业
  • Cloud Bigtable 中的 bigtable.reader 角色,可提供对元数据和表的只读权限

Compute Engine 实例的范围

创建 Compute Engine 实例时,您可以为该实例指定一个范围列表。这些范围用于控制实例对 Google Cloud 产品(包括 Cloud Bigtable)的访问权限。在虚拟机上运行的应用使用服务帐号来调用 Google Cloud APIs。

如果您将某个 Compute Engine 实例设置为以服务帐号身份运行,并且该服务帐号访问一个链接到 Cloud Bigtable 数据源的外部表,则您必须为该实例添加 Cloud Bigtable 只读数据访问权限范围 (https://www.googleapis.com/auth/bigtable.data.readonly)。如需了解详情,请参阅为 Cloud Bigtable 创建 Compute Engine 实例

如需了解如何将范围应用于 Compute Engine 实例,请参阅更改实例的服务帐号和访问权限范围。如需详细了解 Compute Engine 服务帐号,请参阅服务帐号

永久外部表与临时外部表

您可以使用永久表或临时表在 BigQuery 中查询外部数据源。永久表是在数据集中创建的表,该表链接到外部数据源。由于该表是永久性的,因此您可以使用访问权限控制与其他同样有权访问底层外部数据源的人员共享该表,还可以随时查询该表。

使用临时表查询外部数据源时,您需要提交一条含有查询的命令,并创建一个链接到外部数据源的非永久表。使用临时表时,不会在任何 BigQuery 数据集内创建表。由于该表并非永久存储在数据集内,因此无法与他人共享。如果要对外部数据进行一次性临时查询或执行提取、转换和加载 (ETL) 过程,则使用临时表查询外部数据源非常有用。

使用永久外部表查询 Cloud Bigtable 数据

如需使用永久表查询 Cloud Bigtable 数据源,您需要在 BigQuery 数据集中创建一个链接到 Cloud Bigtable 数据源的表。数据不会存储在 BigQuery 表中。由于该表是永久表,因此您可以使用数据集级层的访问权限控制与其他同样有权访问底层 Cloud Bigtable 数据源的人员共享该表。

在 BigQuery 中创建链接到 Cloud Bigtable 数据源的永久外部表时,您可以通过两种方法指定表架构:

  • 如果使用 API 或 CLI,您需要创建一个表定义文件来定义外部数据源的架构和元数据。
  • 如果您使用的是 Cloud Console 或经典版 BigQuery 网页界面,请手动输入 Cloud Bigtable 列族和限定符。

要使用永久外部表查询 Cloud Bigtable 数据,请执行以下操作:

  • 创建一个表定义文件(用于 CLI 或 API)
  • 在 BigQuery 中创建一个链接到外部数据源的表
  • 使用永久表查询数据

创建和查询永久外部表

如需创建和查询永久表,请按如下所述操作:

控制台

目前,Cloud Console 不支持从 Cloud Bigtable 查询数据。

经典版界面

  1. 转到 BigQuery 网页界面。
    转到 BigQuery 网页界面

  2. 在导航面板中,将鼠标悬停在数据集上,点击向下箭头图标 向下箭头图标图片,然后点击 Create new table

  3. Create Table 页面的 Source Data 部分,执行以下操作:

    • Location 部分,选择 Google Cloud Bigtable,然后在来源字段中按照以下格式输入 Cloud Bigtable URI:https://googleapis.com/bigtable/projects/project_id/instances/instance_id/tables/table_name。其中,project_id 是您的 Cloud Bigtable 实例所属的项目,instance_id 是 Cloud Bigtable 实例 ID,table_name 是您要查询的表的名称。
    • File format 部分,确认已选中 Cloud Bigtable。
  4. Create Table 页面的 Destination Table 部分,执行以下操作:

    • 对于 Table name,请选择适当的数据集,然后在表名称字段中输入要在 BigQuery 中创建的永久表的名称。
    • 确认 Table type 已设置为 External table
  5. Column Family and Qualifiers 框中,使用 Add Family 指定列族和限定符,或者点击 Edit as text 并输入列族和限定符构成的 JSON 数组。此列表限制可以在查询中引用的列族,并指定其值类型。例如:

      [
        {
          "familyId": "family_int",
          "type": "INTEGER",
          "encoding": "BINARY",
          "onlyReadLatest": "true",
          "columns": [
            {
              "qualifierString": "foo",
              "onlyReadLatest": "true"
            }
          ]
        }
      ]
    
    您可以使用列限定符列表来执行类型转换。如果将此列表留空,则所有列族都会加入表架构中,并且列族的值会被读取为 BYTES。如需了解详情,请参阅 externalDataConfiguration API 文档中的 Cloud Bigtable 选项。

  6. Options 部分中,选择适用项,然后点击 Create Table

创建永久表后,您可以对该表运行查询,就像对原生 BigQuery 表运行查询一样。查询完成后,可以将结果导出为 CSV 或 JSON 文件,将结果保存为表,或将结果保存到 Google 表格。

CLI

您可以使用 bq mk 命令在 BigQuery 命令行工具中创建表。使用 CLI 创建链接到外部数据源的表时,可以使用表定义文件标识表的架构。

  1. 使用 bq mk 命令创建永久表。

    bq mk \
    --external_table_definition=definition_file \
    dataset.table
    

    其中:

    • definition_file 是本地机器上表定义文件的路径。
    • dataset 是该表所属数据集的名称。
    • table 是您要创建的表的名称。

    接着,您可以对该表运行查询,就像对原生 BigQuery 表运行查询一样,但需遵守外部数据源的限制

API

  • 对于表资源中的 sourceUris 属性,您只能指定一个 Cloud Bigtable URI,并且此 URI 必须是完整、有效的 HTTPS 网址。

  • 通过设置 sourceFormat 属性来指定数据格式属性。对于 Cloud Bigtable,请指定 "BIGTABLE"

使用临时外部表查询 Cloud Bigtable 数据

如果您想查询外部数据源,但不想创建永久表,请运行命令来组合以下项:

  • 表定义文件与查询组合
  • 将内嵌架构定义与查询组合
  • 将 JSON 架构定义文件与查询组合

系统会使用表定义文件或提供的架构来创建临时外部表,然后对临时外部表运行查询。BigQuery CLI 和 API 支持使用临时表查询外部数据源。

使用临时外部表时,并不会在您的某个 BigQuery 数据集中创建表。由于该表不会永久存储在数据集内,因此无法与他人共享。使用临时表查询外部数据源适用于对外部数据进行一次性临时查询,或执行提取、转换和加载 (ETL) 过程。

创建和查询临时外部表

如需使用临时外部表查询 Cloud Bigtable 数据,您需要执行以下操作:

CLI 和 API 目前支持创建和查询临时外部表。

CLI

如需使用表定义文件查询临时表,请输入带 --external_table_definition 标志的 bq query 命令。

(可选)提供 --location 标志并将其值设置为您的位置

bq --location=location query \
--use_legacy_sql=false \
--external_table_definition=table::definition_file \
'query'

其中:

  • location 是您的位置的名称。--location 是可选标志。
  • table 是您要创建的临时表的名称。
  • definition_file 是本地机器上表定义文件的路径。
  • query 是您要提交到临时表的查询。

例如,以下命令使用名为 follows_def 的表定义文件创建并查询名为 follows 的临时表。

bq query \
--use_legacy_sql=false \
--external_table_definition=follows::/tmp/follows_def \
'SELECT
  COUNT(rowkey)
 FROM
   follows'

API

  • 创建查询。如需了解如何创建查询作业,请参阅查询数据

  • (可选)在作业资源jobReference 部分的 location 属性中指定您的位置。

  • 表资源设置 ExternalDataConfiguration 以指定外部数据源属性。

性能考虑因素

针对 Cloud Bigtable 外部数据源的查询性能取决于三个因素:

  • 行数
  • 读取的数据量
  • 并行化程度

BigQuery 会尝试仅读取查询中引用的列族,从而尽可能减少读取数据量。并行化程度取决于您在 Cloud Bigtable 集群中拥有的节点数以及您在自己的表中的拆分次数。

请注意,Cloud Bigtable 会根据负载自动合并拆分。如果读取该表的频率较低,则随着时间的推移,拆分次数会减少,查询性能会逐渐降低。如需详细了解如何按行键拆分表,请参阅管理表

通过 BigQuery 查询 Cloud Bigtable 会消耗 Cloud Bigtable CPU 周期。BigQuery 的 CPU 消耗可能会影响其他并发请求(例如实时用户流量传送)的延迟时间和吞吐量。例如,Cloud Bigtable 上的高 CPU 使用率会影响长尾查询,并增加第 99 百分位的延迟时间。

您应该监控 Cloud Bigtable 的 CPU 使用率,以验证此数据是否处于 Cloud Console 内 Cloud Bigtable 监控信息中心所注明的推荐范围内。通过增加实例的节点数,可更好地同时处理 BigQuery 流量和来自其他并发请求的流量。

生成的架构

默认情况下,BigQuery 将列族中的值作为列数组公开,并在其中包含以不同时间戳写入的值数组。该架构保留了 Cloud Bigtable 中数据的自然布局,但 SQL 查询可能难度较大。可能的解决方案是将列提升为父级列族中的子字段,并且只读取每个单元格中的最新值。这会以标量值的形式表示默认架构中的两个数组。

示例

您要存储某个虚构社交网络的用户个人资料。一个数据模型可能是一个 profile 列族,其中包含对应于 genderageemail 的各列:

rowkey | profile:gender| profile:age| profile:email
-------| --------------| -----------| -------------
alice  | female        | 30         | alice@gmail.com

使用默认架构时,计算 30 岁以上男性用户数量的标准 SQL 查询如下:

SELECT
  COUNT(1)
FROM
  `dataset.table`
OMIT
  RECORD IF NOT SOME(profile.column.name = "gender"
    AND profile.column.cell.value = "male")
  OR NOT SOME(profile.column.name = "age"
    AND INTEGER(profile.column.cell.value) > 30)

如果将 genderage 作为子字段公开提供,则查询数据会较为容易。为了将这些字段作为子字段公开提供,可以在定义表时将 genderage 作为 profile 列族中的命名列列出。您还可以指示 BigQuery 公开提供此列族中的最新值。通常情况下,我们只关注最新值(可能也是唯一的值)。

将列作为子字段公开提供之后,用于计算 30 岁以上男性用户数量的标准 SQL 查询如下:

SELECT
  COUNT(1)
FROM
  `dataset.table`
WHERE
  profile.gender.cell.value="male"
  AND profile.age.cell.value > 30

请注意如何将 genderage 直接作为字段引用。此设置的 JSON 配置如下:

  "bigtableOptions": {
    "readRowkeyAsString": "true",
    "columnFamilies": [
      {
          "familyId": "profile",
          "onlyReadLatest": "true",
          "columns": [
              {
                  "qualifierString": "gender",
                  "type": "STRING"
              },
              {
                  "qualifierString": "age",
                  "type": "INTEGER"
              }
          ]
      }
    ]
  }

值编码

Cloud Bigtable 将数据存储为与数据编码无关的原始字节。但字节值在 SQL 查询分析中的用途有限。Cloud Bigtable 提供两种基本类型的标量解码:文本和 HBase 二进制。

文本格式假定所有值均存储为字母数字文本字符串。例如,整数 768 将存储为字符串“768”。二进制编码假定使用 HBase 的 Bytes.toBytes 方法类对数据进行编码,并应用适当的解码方法。

查询过滤器

采用行相等性过滤器的查询仅读取该特定行。例如,在以下标准 SQL 语法中:

SELECT
  COUNT(follows.column.name)
FROM
  `dataset.table`
WHERE
  rowkey = "alice";

系统也支持 rowkey > '1'rowkey < '8' 等范围过滤条件,但只有在使用 readRowkeyAsString 选项以字符串形式读取 rowkey 时才能提供此支持。