使用 Cassandra Java 客户端连接到 Spanner Omni

适用于 Spanner 的 Cassandra Java 客户端可将为 Apache Cassandra 数据库编写的应用与 Spanner 连接起来。客户端与 Spanner Omni 的交互方式与与 Spanner 的交互方式相同。

由于 Spanner 原生支持 Cassandra v4 传输协议,因此 Spanner Cassandra Java 客户端会将 Cassandra 传输协议转换为 Spanner gRPC API。这样一来,您就可以通过极少的代码更改将 Cassandra 应用迁移到 Spanner。

本文档介绍了如何使用以下方法之一将客户端与 Spanner Omni 集成:

  • 进程内依赖项:如果 Java 应用已使用 cassandra-java-driver,请使用此方法。此方法将客户端嵌入到应用进程中,只需进行最少的代码修改。

  • 边车代理:对于非 Java 应用或使用外部 Cassandra 工具(例如 cqlsh)时,请使用此方法。此方法将客户端作为独立进程运行。

如需了解详情,请参阅 Spanner 文档中的 Cassandra 接口

何时使用 Spanner Cassandra Java 客户端

此客户端在以下情况下非常有用:

  • 以最少的重构工作量使用 Spanner。您希望使用 Spanner 作为 Java 应用的后端,但又希望继续使用熟悉的 cassandra-java-driver API 来访问数据。

  • 使用非 Java Cassandra 工具。您希望使用标准 Cassandra 工具(例如 cqlsh)或使用 Cassandra 驱动程序的其他语言编写的应用连接到 Spanner。

将客户端用作进程内依赖项

将 Spanner Cassandra Java 客户端作为进程内依赖项进行集成是 Java 应用连接到 Spanner Omni 的推荐方法。与边车代理方法相比,进程内配置可避免额外的网络跃点以及相关的数据序列化和反序列化,从而提供更好的性能。此外,它还简化了部署架构,无需管理单独的独立进程。

如需将客户端用作进程内依赖项,请执行以下操作:

  1. 修改 CqlSession 创建代码,并添加 Spanner Omni 通信专用选项。

  2. 将 Spanner Cassandra Java 客户端作为依赖项添加到您的项目中。

    纯文本通信

    以下示例展示了如何建立与 Spanner Omni 的纯文本连接:

    CqlSession session =
        SpannerCqlSession.builder() // `SpannerCqlSession` instead of `CqlSession`
            .setDatabaseUri("DATABASE_ID") // Required: Specify the Spanner database name
            .withConfigLoader(
                DriverConfigLoader.programmaticBuilder()
                    .withString(DefaultDriverOption.PROTOCOL_VERSION, "V4")
                    .withDuration(
                        DefaultDriverOption.CONNECTION_INIT_QUERY_TIMEOUT,
                        Duration.ofSeconds(5))
                    .build())
        .setExperimentalHostEndpoint("ENDPOINT")
      .setUsePlainText(true)
            .build();
    
    // Rest of your business logic such as session.Query(SELECT * FROM ...)
    
    session.close();
    

    TLS 连接

    如需使用 TLS 连接,请确保按照 Java SDK TLS 说明中所述,将 CA 证书添加到应用使用的信任库中:

    CqlSession session =
        SpannerCqlSession.builder() // `SpannerCqlSession` instead of `CqlSession`
            .setDatabaseUri("DATABASE_ID") // Required: Specify the Spanner database name
            .withConfigLoader(
                DriverConfigLoader.programmaticBuilder()
                    .withString(DefaultDriverOption.PROTOCOL_VERSION, "V4")
                    .withDuration(
                        DefaultDriverOption.CONNECTION_INIT_QUERY_TIMEOUT,
                        Duration.ofSeconds(5))
                    .build())
        .setExperimentalHostEndpoint("ENDPOINT")
      .setUsePlainText(false)
            .build();
    
    // Rest of your business logic such as session.Query(SELECT * FROM ...)
    
    session.close();
    

    mTLS 连接

    如需使用 mTLS 连接,请确保 CA 证书已添加到应用使用的信任库,并且客户端密钥采用 PKCS#8 格式,如 Java SDK mTLS 说明中所述:

    CqlSession session =
        SpannerCqlSession.builder() // `SpannerCqlSession` instead of `CqlSession`
            .setDatabaseUri("DATABASE_ID") // Required: Specify the Spanner database name
            .withConfigLoader(
                DriverConfigLoader.programmaticBuilder()
                    .withString(DefaultDriverOption.PROTOCOL_VERSION, "V4")
                    .withDuration(
                        DefaultDriverOption.CONNECTION_INIT_QUERY_TIMEOUT,
                        Duration.ofSeconds(5))
                    .build())
        .setExperimentalHostEndpoint("ENDPOINT")
      .setUsePlainText(false)
      .useClientCert("PATH_TO_CLIENT_CERT",
              "PATH_TO_CLIENT_KEY_PKCS8")
    
            .build();
    
    // Rest of your business logic such as session.Query(SELECT * FROM ...)
    
    session.close();
    

边车代理或独立进程

对于 cqlsh 等非 Java 应用和工具,将 Spanner Cassandra Java 客户端部署为边车代理是一种有效的选择,可让这些应用和工具使用标准 Cassandra 驱动程序连接到 Spanner Omni。此方法将客户端作为独立的 TCP 代理运行,该代理会拦截 Cassandra 传输协议流量并将其转换为 gRPC,以便与 Spanner Omni 通信。

您可以使用 YAML 配置文件或通过指定系统属性来运行边车代理。

使用 YAML 配置文件

对于生产设置,我们建议您使用 YAML 文件来配置适配器。此方法支持多个监听器和全局设置:

java -DconfigFilePath=PATH_TO_CONFIG_YAML -jar PATH_TO_ADAPTER_JAR

示例 config.yaml

globalClientConfigs:
  enableBuiltInMetrics: false
  healthCheckEndpoint: "127.0.0.1:8080"
  experimentalHostEndpoint: "ENDPOINT"
  clientCertPath: "PATH_TO_CLIENT_CERT"
  clientKeyPath: "PATH_TO_CLIENT_KEY_PKCS8"
  usePlainText: "false"

listeners:
  - name: "listener_1"
    host: "127.0.0.1"
    port: 9042
    spanner:
      databaseUri: "DATABASE_ID"
      numGrpcChannels: 4
      maxCommitDelayMillis: 5
  - name: "listener_2"
    host: "127.0.0.2"
    port: 9043
    spanner:
      databaseUri: "DATABASE_ID_2"
      numGrpcChannels: 8

使用系统属性

对于单个监听器或更简单的部署,您可以将边车代理作为独立进程运行,并使用 Java 系统属性配置其设置。

对于单个监听器,您可以使用系统属性。以下示例展示了如何针对每种受支持的安全模式将边车代理作为独立进程运行:

纯文本通信

对于纯文本通信,请运行以下命令:

java -DdatabaseUri=DATABASE_ID \
-Dhost=127.0.0.1 \
-Dport=9042 \
-DnumGrpcChannels=4 \
-DhealthCheckPort=8080 \
-DexperimentalHostEndpoint=ENDPOINT \
-DusePlainText=true \
-jar PATH_TO_ADAPTER_JAR

TLS 连接

对于 TLS 连接,请运行以下命令:

java -DdatabaseUri=DATABASE_ID \
-Dhost=127.0.0.1 \
-Dport=9042 \
-DnumGrpcChannels=4 \
-DhealthCheckPort=8080 \
-DexperimentalHostEndpoint=ENDPOINT \
-jar PATH_TO_ADAPTER_JAR

mTLS 连接

对于 mTLS 连接,请运行以下命令:

java -DdatabaseUri=DATABASE_ID \
-Dhost=127.0.0.1 \
-Dport=9042 \
-DnumGrpcChannels=4 \
-DhealthCheckPort=8080 \
-DexperimentalHostEndpoint=ENDPOINT \
-DclientCertPath=PATH_TO_CLIENT_CERT \
-DclientKeyPath=PATH_TO_CLIENT_KEY_PKCS8 \
-jar PATH_TO_ADAPTER_JAR