连接到 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 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

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

试用此示例之前,请按照 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 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 命令行工具共享连接。如需共享连接,请使用 Google Cloud 控制台或 BigQuery Connections API 方法共享连接。

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

试用此示例之前,请按照 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");
    }
  }
}

后续步骤