连接到 Cloud SQL

作为 BigQuery 管理员,您可以创建一个连接来访问 Cloud SQL 数据。借助此连接,数据分析师可以查询 Cloud SQL 中的数据。 如需连接到 Cloud SQL,您必须按照以下步骤操作:

  1. 创建 Cloud SQL 连接
  2. BigQuery Connection Service Agent 授予访问权限

准备工作

  1. 选择包含 Cloud SQL 实例的项目。

    转到“项目选择器”

  2. 启用 BigQuery Connection API。

    启用 API

  3. 确保 Cloud SQL 实例具有公共 IP 连接专用连接
    • 为了保护 Cloud SQL 实例,您可以在没有授权地址的情况下添加公共 IP 地址连接。这使实例无法通过公共互联网访问,但可以通过 BigQuery 查询访问。

    • 为了让 BigQuery 通过专用连接访问 Cloud SQL 数据,请为新的现有 Cloud SQL 实例配置专用 IP 连接,然后选择 Google Cloud 服务的专用路径复选框。此服务使用内部直接路径,而不是 Virtual Private Cloud 内的专用 IP 地址。

  4. 如需获得创建 Cloud SQL 连接所需的权限,请让您的管理员为您授予项目的 BigQuery Connection Admin (roles/bigquery.connectionAdmin) IAM 角色。如需详细了解如何授予角色,请参阅管理对项目、文件夹和组织的访问权限

    您也可以通过自定义角色或其他预定义角色来获取所需的权限。

创建 Cloud SQL 连接

最佳实践是连接到 Cloud SQL 时使用连接处理数据库凭据。在 BigQuery 连接服务中,连接将会被加密并安全地存储。如果用户凭据对来源中的其他数据有效,则可以重复使用该连接。例如,您可以使用一个连接来查询驻留在同一个 Cloud SQL 实例中的多个数据库。

选择下列其中一个选项来创建 Cloud SQL 连接:

控制台

  1. 转到 BigQuery 页面。

    转到 BigQuery

  2. 探索器窗格中,点击 添加

  3. 添加对话框中,点击与外部数据源的连接

  4. 外部数据源对话框中,输入以下信息:

    • 对于连接类型,请选择来源类型,例如 MySQL 或 Postgres。
    • 对于连接 ID,输入连接资源的标识符。允许使用字母、数字和下划线。 例如 bq_sql_connection
    • 对于数据位置,选择与您的外部数据源区域兼容的 BigQuery 位置(或区域)。
    • 可选:对于易记名称,输入方便用户使用的连接名称,例如 My connection resource。易记名称可以是任何容易辨识的值,让您以后在需要修改连接资源时能够轻松识别。
    • 可选:对于说明,输入此连接资源的说明。
    • 可选:加密。如果要使用客户管理的加密密钥 (CMEK) 来加密凭据,请选择客户管理的加密密钥 (CMEK),然后选择客户管理的密钥。否则,您的凭据受 Google 拥有且 Google 管理的默认密钥保护。
    • 如果您选择了 Cloud SQL MySQL 或 Postgres 作为连接类型,对于 Cloud SQL 连接名称,请输入完整的 Cloud SQL 实例的名称,格式通常为 project-id:location-id:instance-id。您可以在想要查询的 Cloud SQL 实例的详情页面找到实例 ID。
    • 对于数据库名称,输入数据库的名称。
    • 对于数据库用户名,输入数据库的用户名。
    • 对于数据库密码,输入数据库的密码。

      • 可选:如需看到密码,请点击 显示密码
  5. 点击创建连接

  6. 点击转到连接

  7. 连接信息窗格中,复制服务账号 ID 以在下一步中使用。

bq

输入 bq mk 命令并提供连接标志:--connection。此外,还必须提供以下标志:

  • --connection_type
  • --properties
  • --connection_credential
  • --project_id
  • --location

以下标志是可选的:

  • --display_name 连接的易记名称。
  • --description 连接的说明。

connection_id 是可选参数,可以添加为在内部用于存储的命令的最后一个参数。如果未提供连接 ID,则系统会自动生成一个唯一 ID。connection_id 可以包含字母、数字和下划线。

    bq mk --connection --display_name='friendly name' --connection_type=TYPE \
      --properties=PROPERTIES --connection_credential=CREDENTIALS \
      --project_id=PROJECT_ID --location=LOCATION \
      CONNECTION_ID

替换以下内容:

  • TYPE:外部数据源的类型。
  • PROPERTIES:所创建的连接的参数(采用 JSON 格式)。例如 --properties='{"param":"param_value"}'。为了创建连接资源,您必须提供 instanceIDdatabasetype 参数。
  • CREDENTIALS:参数 usernamepassword
  • PROJECT_ID:您的项目 ID。
  • LOCATION:您的 Cloud SQL 实例所在的区域。
  • CONNECTION_ID:连接标识符。

例如,以下命令在 ID 为 federation-test 的项目中创建一个名为 my_new_connection(易记名称:“我的新连接”)的新连接资源。

bq mk --connection --display_name='friendly name' --connection_type='CLOUD_SQL' \
  --properties='{"instanceId":"federation-test:us-central1:mytestsql","database":"mydatabase","type":"MYSQL"}' \
  --connection_credential='{"username":"myusername", "password":"mypassword"}' \
  --project_id=federation-test --location=us my_connection_id

API

通过 BigQuery Connection API,您可以在 ConnectionService 中调用 CreateConnection 来实例化连接。如需了解详情,请参阅客户端库页面

Java

试用此示例之前,请按照 BigQuery 快速入门:使用客户端库中的 Java 设置说明进行操作。 如需了解详情,请参阅 BigQuery Java API 参考文档

如需向 BigQuery 进行身份验证,请设置应用默认凭据。 如需了解详情,请参阅为客户端库设置身份验证

import com.google.cloud.bigquery.connection.v1.CloudSqlCredential;
import com.google.cloud.bigquery.connection.v1.CloudSqlProperties;
import com.google.cloud.bigquery.connection.v1.Connection;
import com.google.cloud.bigquery.connection.v1.CreateConnectionRequest;
import com.google.cloud.bigquery.connection.v1.LocationName;
import com.google.cloud.bigqueryconnection.v1.ConnectionServiceClient;
import java.io.IOException;

// Sample to create a connection with cloud MySql database
public class CreateConnection {

  public static void main(String[] args) throws IOException {
    // TODO(developer): Replace these variables before running the sample.
    String projectId = "MY_PROJECT_ID";
    String location = "MY_LOCATION";
    String connectionId = "MY_CONNECTION_ID";
    String database = "MY_DATABASE";
    String instance = "MY_INSTANCE";
    String instanceLocation = "MY_INSTANCE_LOCATION";
    String username = "MY_USERNAME";
    String password = "MY_PASSWORD";
    String instanceId = String.format("%s:%s:%s", projectId, instanceLocation, instance);
    CloudSqlCredential cloudSqlCredential =
        CloudSqlCredential.newBuilder().setUsername(username).setPassword(password).build();
    CloudSqlProperties cloudSqlProperties =
        CloudSqlProperties.newBuilder()
            .setType(CloudSqlProperties.DatabaseType.MYSQL)
            .setDatabase(database)
            .setInstanceId(instanceId)
            .setCredential(cloudSqlCredential)
            .build();
    Connection connection = Connection.newBuilder().setCloudSql(cloudSqlProperties).build();
    createConnection(projectId, location, connectionId, connection);
  }

  static void createConnection(
      String projectId, String location, String connectionId, Connection connection)
      throws IOException {
    try (ConnectionServiceClient client = ConnectionServiceClient.create()) {
      LocationName parent = LocationName.of(projectId, location);
      CreateConnectionRequest request =
          CreateConnectionRequest.newBuilder()
              .setParent(parent.toString())
              .setConnection(connection)
              .setConnectionId(connectionId)
              .build();
      Connection response = client.createConnection(request);
      System.out.println("Connection created successfully :" + response.getName());
    }
  }
}

向服务代理授予访问权限

当您在项目中创建第一个与 Cloud SQL 的连接时,系统会自动创建服务代理。该服务代理名为 BigQuery Connection Service Agent。如需获取服务代理 ID,请查看连接详细信息。服务代理 ID 的格式如下:

service-PROJECT_NUMBER@gcp-sa-bigqueryconnection.iam.gserviceaccount.com

如需连接到 Cloud SQL,您必须向新的连接授予对 Cloud SQL 的只读权限,以便 BigQuery 能够代表用户访问文件。 服务代理必须具有以下权限:

  • cloudsql.instances.connect
  • cloudsql.instances.get

您可以向与连接关联的服务代理授予 Cloud SQL Client IAM 角色 (roles/cloudsql.client),该角色分配有上述权限。如果服务代理已具有所需的权限,则可以跳过以下步骤。

控制台

  1. 前往 IAM 和管理页面。

    转到“IAM 和管理”

  2. 点击 授予访问权限

    系统随即会打开添加主账号对话框。

  3. 新的主账号字段中,输入服务代理名称 BigQuery Connection Service Agent 或从连接信息中提取的服务代理 ID。

  4. 选择角色字段中,选择 Cloud SQL,然后选择 Cloud SQL Client

  5. 点击保存

gcloud

使用 gcloud projects add-iam-policy-binding 命令:

gcloud projects add-iam-policy-binding PROJECT_ID --member=serviceAccount:SERVICE_AGENT_ID --role=roles/cloudsql.client

请提供以下值:

  • PROJECT_ID:您的 Google Cloud 项目 ID。
  • SERVICE_AGENT_ID:从连接信息中获取的服务代理 ID。

与用户共享连接

您可以授予以下角色,以使用户可以查询数据并管理连接:

  • roles/bigquery.connectionUser:允许用户使用连接与外部数据源建立连接,并对其运行查询。

  • roles/bigquery.connectionAdmin:允许用户管理连接。

如需详细了解 BigQuery 中的 IAM 角色和权限,请参阅预定义的角色和权限

从下列选项中选择一项:

控制台

  1. 转到 BigQuery 页面。

    转到 BigQuery

    连接列在项目的外部连接组中。

  2. 探索器窗格中,点击您的项目名称 > 外部连接 > 连接

  3. 详细信息窗格中,点击共享以共享连接。之后,执行以下操作:

    1. 连接权限对话框中,通过添加或修改主账号与其他主账号共享连接。

    2. 点击保存

bq

您不能使用 bq 命令行工具共享连接。如需共享连接,请使用 Google Cloud 控制台或 BigQuery Connections API 方法共享连接。

API

使用 BigQuery Connections REST API 参考文档部分中的 projects.locations.connections.setIAM 方法,并提供一个 policy 资源实例。

Java

试用此示例之前,请按照 BigQuery 快速入门:使用客户端库中的 Java 设置说明进行操作。 如需了解详情,请参阅 BigQuery Java API 参考文档

如需向 BigQuery 进行身份验证,请设置应用默认凭据。 如需了解详情,请参阅为客户端库设置身份验证

import com.google.api.resourcenames.ResourceName;
import com.google.cloud.bigquery.connection.v1.ConnectionName;
import com.google.cloud.bigqueryconnection.v1.ConnectionServiceClient;
import com.google.iam.v1.Binding;
import com.google.iam.v1.Policy;
import com.google.iam.v1.SetIamPolicyRequest;
import java.io.IOException;

// Sample to share connections
public class ShareConnection {

  public static void main(String[] args) throws IOException {
    // TODO(developer): Replace these variables before running the sample.
    String projectId = "MY_PROJECT_ID";
    String location = "MY_LOCATION";
    String connectionId = "MY_CONNECTION_ID";
    shareConnection(projectId, location, connectionId);
  }

  static void shareConnection(String projectId, String location, String connectionId)
      throws IOException {
    try (ConnectionServiceClient client = ConnectionServiceClient.create()) {
      ResourceName resource = ConnectionName.of(projectId, location, connectionId);
      Binding binding =
          Binding.newBuilder()
              .addMembers("group:example-analyst-group@google.com")
              .setRole("roles/bigquery.connectionUser")
              .build();
      Policy policy = Policy.newBuilder().addBindings(binding).build();
      SetIamPolicyRequest request =
          SetIamPolicyRequest.newBuilder()
              .setResource(resource.toString())
              .setPolicy(policy)
              .build();
      client.setIamPolicy(request);
      System.out.println("Connection shared successfully");
    }
  }
}

后续步骤