关于此 Codelab
1. 简介
Bigtable 是一种全代管式高性能 NoSQL 数据库服务,专用于处理大规模分析和运营工作负载。从 Apache Cassandra 等现有数据库迁移到 Bigtable 通常需要仔细规划,以尽量减少停机时间和对应用的影响。
此 Codelab 演示了一种将 Cassandra 迁移到 Bigtable 的迁移策略,该策略结合使用了以下代理工具:
- Cassandra-Bigtable 代理:允许 Cassandra 客户端和工具(例如
cqlsh
或驱动程序)通过转换查询,使用 Cassandra 查询语言 (CQL) 协议与 Bigtable 交互。 - Datastax 零停机迁移 (ZDM) 代理:一个位于应用和数据库服务(通过 Cassandra-Bigtable 代理的源 Cassandra 和目标 Bigtable)之间的开源代理。它可协调双写入并管理流量路由,从而实现最少的应用更改和停机时间。
- Cassandra 数据迁移器 (CDM):这是一个开源工具,用于将历史数据从源 Cassandra 集群批量迁移到目标 Bigtable 实例。
学习内容
- 如何在 Compute Engine 上设置基本 Cassandra 集群。
- 如何创建 Bigtable 实例。
- 如何部署和配置 Cassandra-Bigtable 代理,以将 Cassandra 架构映射到 Bigtable。
- 如何部署和配置 Datastax ZDM 代理以实现双写。
- 如何使用 Cassandra Data Migrator 工具批量迁移现有数据。
- 基于代理的 Cassandra 到 Bigtable 迁移的整体工作流。
所需条件
- 启用了结算功能的 Google Cloud 项目。新用户可免费试用。
- 基本熟悉 Google Cloud 概念,例如项目、Compute Engine、VPC 网络和防火墙规则。基本熟悉 Linux 命令行工具。
- 访问安装并配置了
gcloud
CLI 的机器,或使用 Google Cloud Shell。
在本 Codelab 中,我们将主要使用位于同一 VPC 网络和区域内的 Compute Engine 虚拟机 (VM),以简化网络设置。建议使用内部 IP 地址。
2. 设置环境
1. 选择或创建 Google Cloud 项目
前往 Google Cloud 控制台,然后选择一个现有项目或创建一个新项目。记下您的项目 ID。
2. 启用必需的 API
确保已为您的项目启用 Compute Engine API 和 Bigtable API。
gcloud services enable compute.googleapis.com bigtable.googleapis.com bigtableadmin.googleapis.com --project=<your-project-id>
将 替换为您的实际项目 ID。
3. 选择区域和可用区
为您的资源选择区域和可用区。我们将使用 us-central1 和 us-central1-c 作为示例。为方便起见,请将它们定义为环境变量:
export PROJECT_ID="<your-project-id>" export REGION="us-central1" export ZONE="us-central1-c" gcloud config set project $PROJECT_ID gcloud config set compute/region $REGION gcloud config set compute/zone $ZONE
4. 配置防火墙规则
我们需要允许默认 VPC 网络中的虚拟机通过多个端口进行通信:
- Cassandra/代理 CQL 端口:9042
- ZDM 代理健康检查端口:14001
- SSH:22
创建防火墙规则,以允许这些端口上的内部流量。我们将使用标记 cassandra-migration
轻松将此规则应用于相关虚拟机。
gcloud compute firewall-rules create allow-migration-internal \ --network=default \ --action=ALLOW \ --rules=tcp:22,tcp:9042,tcp:14001 \ --source-ranges=10.128.0.0/9 # Adjust if using a custom VPC/IP range \ --target-tags=cassandra-migration
3. 部署 Cassandra 集群 (Origin)
在此 Codelab 中,我们将在 Compute Engine 上设置一个简单的单节点 Cassandra 集群。在实际场景中,您需要连接到现有集群。
1. 为 Cassandra 创建 GCE 虚拟机
gcloud compute instances create cassandra-origin \ --machine-type=e2-medium \ --image-family=ubuntu-2004-lts \ --image-project=ubuntu-os-cloud \ --tags=cassandra-migration \ --boot-disk-size=20GB
2. 安装 Cassandra
# Install Java (Cassandra dependency) sudo apt-get update sudo apt-get install -y openjdk-11-jre-headless # Add Cassandra repository echo "deb [https://debian.cassandra.apache.org](https://debian.cassandra.apache.org) 41x main" | sudo tee -a /etc/apt/sources.list.d/cassandra.sources.list curl [https://downloads.apache.org/cassandra/KEYS](https://downloads.apache.org/cassandra/KEYS) | sudo apt-key add - # Install Cassandra sudo apt-get update sudo apt-get install -y cassandra
3. 创建键空间和表
我们将使用员工表示例,并创建一个名为“zdmbigtable”的键空间。
cd ~/apache-cassandra bin/cqlsh <your-localhost-ip? 9042 #starts the cql shell
在 cqlsh 中:
-- Create keyspace (adjust replication for production) CREATE KEYSPACE zdmbigtable WITH replication = {'class':'SimpleStrategy', 'replication_factor':1}; -- Use the keyspace USE zdmbigtable; -- Create the employee table CREATE TABLE employee ( name text PRIMARY KEY, age bigint, code int, credited double, balance float, is_active boolean, birth_date timestamp ); -- Exit cqlsh EXIT;
让 SSH 会话保持打开状态,或记下此虚拟机的 IP 地址(hostname -I)。
4. 设置 Bigtable(目标)
时长 0:01
创建 Bigtable 实例。我们将使用 zdmbigtable 作为实例 ID。
gcloud bigtable instances create zdmbigtable \ --display-name="ZDM Bigtable Target" \ --cluster=bigtable-c1 \ --cluster-zone=$ZONE \ --cluster-num-nodes=1 # Use 1 node for dev/testing; scale as needed
Bigtable 表本身将由 Cassandra-Bigtable 代理设置脚本稍后创建。
5. 设置 Cassandra-Bigtable 代理
1. 为 Cassandra-Bigtable 代理创建 Compute Engine 虚拟机
gcloud compute instances create bigtable-proxy-vm \ --machine-type=e2-medium \ --image-family=ubuntu-2004-lts \ --image-project=ubuntu-os-cloud \ --tags=cassandra-migration \ --boot-disk-size=20GB
通过 SSH 连接到 bigtable-proxy-vm:
gcloud compute ssh bigtable-proxy-vm
在虚拟机内:
# Install Git and Go sudo apt-get update sudo apt-get install -y git golang-go # Clone the proxy repository # Replace with the actual repository URL if different git clone https://github.com/GoogleCloudPlatform/cloud-bigtable-ecosystem.git cd cassandra-to-bigtable-proxy/ # Set Go environment variables export GOPATH=$HOME/go export PATH=$PATH:/usr/local/go/bin:$GOPATH/bin
2. 配置代理
nano config.yaml
更新以下变量。如需进行更高级的配置,请使用 GitHub 上提供的此示例。
#!/bin/bash
cassandraToBigtableConfigs:
# Global default GCP Project ID
projectId: <your-project-id>
listeners:
- name: cluster1
port: 9042
bigtable:
#If you want to use multiple instances then pass the instance names by comma seperated
#Instance name should not contain any special characters except underscore(_)
instanceIds: zdmbigtable
# Number of grpc channels to be used for Bigtable session.
Session:
grpcChannels: 4
otel:
# Set enabled to true or false for OTEL metrics/traces/logs.
enabled: False
# Name of the collector service to be setup as a sidecar
serviceName: cassandra-to-bigtable-otel-service
healthcheck:
# Enable the health check in this proxy application config only if the
# "health_check" extension is added to the OTEL collector service configuration.
#
# Recommendation:
# Enable the OTEL health check if you need to verify the collector's availability
# at the start of the application. For development or testing environments, it can
# be safely disabled to reduce complexity.
# Enable/Disable Health Check for OTEL, Default 'False'.
enabled: False
# Health check endpoint for the OTEL collector service
endpoint: localhost:13133
metrics:
# Collector service endpoint
endpoint: localhost:4317
traces:
# Collector service endpoint
endpoint: localhost:4317
#Sampling ratio should be between 0 and 1. Here 0.05 means 5/100 Sampling ratio.
samplingRatio: 1
loggerConfig:
# Specifies the type of output, here it is set to 'file' indicating logs will be written to a file.
# Value of `outputType` should be `file` for file type or `stdout` for standard output.
# Default value is `stdout`.
outputType: stdout
# Set this only if the outputType is set to `file`.
# The path and name of the log file where logs will be stored. For example, output.log, Required Key.
# Default `/var/log/cassandra-to-spanner-proxy/output.log`.
fileName: output/output.log
# Set this only if the outputType is set to `file`.
# The maximum size of the log file in megabytes before it is rotated. For example, 500 for 500 MB.
maxSize: 10
# Set this only if the outputType is set to `file`.
# The maximum number of backup log files to keep. Once this limit is reached, the oldest log file will be deleted.
maxBackups: 2
# Set this only if the outputType is set to `file`.
# The maximum age in days for a log file to be retained. Logs older than this will be deleted. Required Key.
# Default 3 days
maxAge: 1
# Set this only if the outputType is set to `file`.
# Default value is set to 'False'. Change the value to 'True', if log files are required to be compressed.
compress: True
保存并关闭文件(在 nano 中,依次按 Ctrl+X、Y 和 Enter)。
3. 启动 Cassandra-Bigtable 代理
启动代理服务器。
# At the root of the cassandra-to-bigtable-proxy directory go run proxy.go
代理将启动并监听端口 9042 以接收传入的 CQL 连接。让此终端会话保持运行状态。记下此虚拟机的 IP 地址(主机名 -I)
4. 通过 CQL 创建表
将 cqlsh
连接到 Cassandra-Bigtable 代理虚拟机的 IP 地址。
在 cqlsh
中,运行以下命令
-- Create the employee table CREATE TABLE zdmbigtable.employee ( name text PRIMARY KEY, age bigint, code int, credited double, balance float, is_active boolean, birth_date timestamp );
在 Google Cloud 控制台中,验证您的 Bigtable 实例中是否存在员工表和元数据表。
6. 设置 ZDM 代理
ZDM 代理至少需要两台机器:一台或多台用于处理流量的代理节点,以及用于通过 Ansible 进行部署和编排的“跳板机”。
1. 为 ZDM 代理创建 Compute Engine 虚拟机
我们需要两个虚拟机:zdm-proxy-jumphost 和 zdm-proxy-node-1
# Jumphost VM gcloud compute instances create zdm-jumphost \ --machine-type=e2-medium \ --image-family=ubuntu-2004-lts \ --image-project=ubuntu-os-cloud \ --tags=cassandra-migration \ --boot-disk-size=20GB # Proxy Node VM gcloud compute instances create zdm-proxy-node-1 \ --machine-type=e2-standard-8 \ --image-family=ubuntu-2004-lts \ --image-project=ubuntu-os-cloud \ --tags=cassandra-migration \ --boot-disk-size=20GB
记下这两个虚拟机的 IP 地址。
2. 准备跳转主机
通过 SSH 连接到 zdm-jumphost
gcloud compute ssh zdm-jumphost
# Install Git and Ansible
sudo apt-get update
sudo apt-get install -y git ansible
在跳转主机内
git clone https:\/\/github.com/datastax/zdm-proxy-automation.git
cd zdm-proxy-automation/ansible/
修改主配置文件 vars/zdm_proxy_cluster_config.yml:
将 origin_contact_points 和 target_contact_points 分别更新为 Cassandra 虚拟机和 Cassandra-Bigtable 代理虚拟机的内部 IP 地址。请将身份验证注释掉,因为我们未进行设置。
##############################
#### ORIGIN CONFIGURATION ####
##############################
## Origin credentials (leave commented if no auth)
# origin_username: ...
# origin_password: ...
## Set the following two parameters only if Origin is a self-managed, non-Astra cluster
origin_contact_points: <Your-Cassandra-VM-Internal-IP> # Replace!
origin_port: 9042
##############################
#### TARGET CONFIGURATION ####
##############################
## Target credentials (leave commented if no auth)
# target_username: ...
# target_password: ...
## Set the following two parameters only if Target is a self-managed, non-Astra cluster
target_contact_points: <Your-Bigtable-Proxy-VM-Internal-IP> # Replace!
target_port: 9042
# --- Other ZDM Proxy settings can be configured below ---
# ... (keep defaults for this codelab)
保存并关闭此文件。
3. 使用 Ansible 部署 ZDM 代理
在跳转主机上的 ansible 目录中运行 Ansible 操作手册:
ansible-playbook deploy_zdm_proxy.yml -i zdm_ansible_inventory
此命令将在代理节点 (zdm-proxy-node-1) 上安装必要的软件(例如 Docker),拉取 ZDM 代理 Docker 映像,并使用您提供的配置启动代理容器。
4. 验证 ZDM 代理运行状况
从跳转主机检查在 zdm-proxy-node-1(端口 14001)上运行的 ZDM 代理的就绪情况端点:
# Replace <zdm-proxy-node-1-internal-ip> with the actual internal IP.
curl -G http://<zdm-proxy-node-1-internal-ip>:14001/health/readiness
您应该会看到类似于以下内容的输出,表明源 (Cassandra) 和目标 (Cassandra-Bigtable 代理) 均处于 UP 状态:
{
"OriginStatus": {
"Addr": "<Your-Cassandra-VM-Internal-IP>:9042",
"CurrentFailureCount": 0,
"FailureCountThreshold": 1,
"Status": "UP"
},
"TargetStatus": {
"Addr": "<Your-Bigtable-Proxy-VM-Internal-IP>:9042",
"CurrentFailureCount": 0,
"FailureCountThreshold": 1,
"Status": "UP"
},
"Status": "UP"
}
7. 配置应用并启动双写入
时长 0:05
在实际迁移的此阶段,您需要重新配置应用,使其指向 ZDM 代理节点的 IP 地址(例如:9042),而不是直接连接到 Cassandra。
应用连接到 ZDM 代理后:默认情况下,读取操作由源 (Cassandra) 提供。写入操作会同时发送到源 (Cassandra) 和目标 (Bigtable,通过 Cassandra-Bigtable 代理)。这样,您的应用就可以继续正常运行,同时确保新数据同时写入两个数据库。您可以使用指向跳转主机或网络中的其他虚拟机上的 ZDM 代理的 cqlsh 来测试连接:
Cqlsh <zdm-proxy-node-1-ip-address> 9042
尝试插入一些数据:
INSERT INTO zdmbigtable.employee (name, age, is_active) VALUES ('Alice', 30, true); SELECT * FROM employee WHERE name = 'Alice';
这些数据应同时写入 Cassandra 和 Bigtable。您可以在 Bigtable 中确认这一点,方法是前往 Google Cloud 控制台,然后打开实例的 Bigtable 查询编辑器。运行“SELECT * FROM employee”查询,您应该会看到最近插入的数据。
8. 使用 Cassandra Data Migrator 迁移历史数据
现在,双写功能已针对新数据启用,请使用 Cassandra 数据迁移器 (CDM) 工具将现有历史数据从 Cassandra 复制到 Bigtable。
1. 为 CDM 创建 Compute Engine 虚拟机
此虚拟机需要有足够的内存来运行 Spark。
gcloud compute instances create cdm-migrator-vm \ --machine-type=e2-medium \ --image-family=ubuntu-2004-lts \ --image-project=ubuntu-os-cloud \ --tags=cassandra-migration \ --boot-disk-size=40GB
2. 安装必备软件(Java 11、Spark)
通过 SSH 连接到 cdm-migrator-vm:
gcloud compute ssh cdm-migrator-vm
在虚拟机内:
# Install Java 11
sudo apt-get update
sudo apt-get install -y openjdk-11-jdk
# Verify Java installation
java -version
# Download and Extract Spark (Using version 3.5.3 as requested)
# Check the Apache Spark archives for the correct URL if needed
wget [https://archive.apache.org/dist/spark/spark-3.5.3/spark-3.5.3-bin-hadoop3-scala2.13.tgz](https://archive.apache.org/dist/spark/spark-3.5.3/spark-3.5.3-bin-hadoop3-scala2.13.tgz) tar -xvzf spark-3.5.3-bin-hadoop3-scala2.13.tgz
export SPARK_HOME=$PWD/spark-3.5.3-bin-hadoop3-scala2.13
export PATH=$PATH:$SPARK_HOME/bin
3. 下载 Cassandra 数据迁移器
下载 CDM 工具 jar 文件。请访问 Cassandra Data Migrator GitHub 版本页面,查找所需版本的正确网址。
# Example using version 5.2.2 - replace URL if needed
wget https://github.com/datastax/cassandra-data-migrator/releases/download/v5.2.2/cassandra-data-migrator-5.2.2.jar)
4. 配置 CDM
创建一个名为 cdm.properties 的属性文件
Nano cdm.properties
粘贴以下配置,替换 IP 地址并停用 TTL/Writetime 功能,因为 Bigtable 不以相同的方式直接支持这些功能。将 auth 注释掉。
# Origin Cassandra Connection
spark.cdm.connect.origin.host <Your-Cassandra-VM-IP-Address> # Replace!
spark.cdm.connect.origin.port 9042
spark.cdm.connect.origin.username cassandra # Leave default, or set if auth is enabled #
spark.cdm.connect.origin.password cassandra # Leave default, or set if auth is enabled #
# Target Bigtable (via Cassandra-Bigtable Proxy)
Connection spark.cdm.connect.target.host <Your-Bigtable-Proxy-VM-IP-Address> # Replace!
spark.cdm.connect.target.port 9042
spark.cdm.connect.target.username cassandra # Leave default, or set if auth is enabled #
spark.cdm.connect.target.password cassandra # Leave default, or set if auth is enabled #
# Disable TTL/Writetime features (Important for Bigtable compatibility via Proxy)
spark.cdm.feature.origin.ttl.automatic false
spark.cdm.feature.origin.writetime.automatic false
spark.cdm.feature.target.ttl.automatic false
spark.cdm.feature.target.writetime.automatic false
保存并关闭文件。
5. 运行迁移作业
使用 spark-submit 执行迁移。此命令会告知 Spark 使用您的属性文件运行 CDM jar,并指定要迁移的键空间和表。根据虚拟机大小和数据量调整内存设置(-driver-memory、-executor-memory)。
确保您位于包含 CDM jar 文件和属性文件的目录中。如果您下载的版本不同,请替换“cassandra-data-migrator-5.2.2.jar”。
./spark-3.5.3-bin-hadoop3-scala2.13/bin/spark-submit \ --properties-file cdm.properties \ --master "local[*]" \ --driver-memory 4G \ --executor-memory 4G \ --class com.datastax.cdm.job.Migrate \ cassandra-data-migrator-5.2.2.jar &> cdm_migration_$(date +%Y%m%d_%H%M).log
迁移将在后台运行,日志将写入 cdm_migration_... .log。监控日志文件,了解进度和是否存在任何错误:
tail -f cdm_migration_*.log
6. 验证数据迁移
CDM 作业成功完成后,请验证 Bigtable 中是否存在历史数据。由于 Cassandra-Bigtable 代理允许执行 CQL 读取,因此您可以再次使用连接到 ZDM 代理(该代理会在迁移后将读取路由到目标,或可以配置为执行此操作)或直接连接到 Cassandra-Bigtable 代理的 cqlsh 来查询数据。通过 ZDM 代理连接:
cqlsh <zdm-proxy-node-1-ip-address> 9042
在 cqlsh 中:
SELECT COUNT(*) FROM zdmbigtable.employee; -- Check row count matches origin SELECT * FROM employee LIMIT 10; -- Check some sample data
或者,您也可以使用 cbt 工具(如果已安装在 CDM VM 或 Cloud Shell 上)直接在 Bigtable 中查询数据:
# First, install cbt if needed
# gcloud components update
# gcloud components install cbt
# Then lookup a specific row (replace 'some_employee_name' with an actual primary key)
cbt -project $PROJECT_ID -instance zdmbigtable lookup employee some_employee_name
9. 切换(概念)
彻底验证 Cassandra 和 Bigtable 之间数据的一致性后,您可以继续进行最终切换。
对于 ZDM 代理,切换涉及将其重新配置为主要从目标(Bigtable)而不是来源(Cassandra)读取。这通常是通过 ZDM 代理的配置完成的,可有效地将应用的读取流量转移到 Bigtable。
在确信 Bigtable 能够正确处理所有流量后,您最终可以:
- 通过重新配置 ZDM 代理来停止双写入。
- 停用原始 Cassandra 集群。
- 移除 ZDM 代理,让应用直接连接到 Cassandra-Bigtable 代理,或使用适用于 Java 的原生 Bigtable CQL 客户端。
有关为切换重新配置 ZDM 代理的具体信息超出了本基本 Codelab 的范围,但 Datastax ZDM 文档中对此进行了详细介绍。
10. 清理
为避免产生费用,请删除您在本 Codelab 中创建的资源。
1. 删除 Compute Engine 虚拟机
gcloud compute instances delete cassandra-origin-vm zdm-proxy-jumphost zdm-proxy-node-1 bigtable-proxy-vm cdm-migrator-vm --zone=$ZONE --quiet
2. 删除 Bigtable 实例
gcloud bigtable instances delete zdmbigtable
3. 删除防火墙规则
gcloud compute firewall-rules delete allow-migration-internal
4. 删除 Cassandra 数据库(如果本地安装或持久化)
如果您在本教程中创建的 Compute Engine 虚拟机之外安装了 Cassandra,请按照相应步骤移除数据或卸载 Cassandra。
11. 恭喜!
您已成功完成从 Apache Cassandra 到 Bigtable 设置基于代理的迁移路径的流程!
您已学习了:
部署 Cassandra 和 Bigtable。
- 配置 Cassandra-Bigtable 代理以实现 CQL 兼容性。
- 部署 Datastax ZDM 代理以管理双写入和流量。
- 使用 Cassandra 数据迁移工具移动历史数据。
这种方法利用代理层,可在不停机的情况下进行迁移,并且无需更改代码。
后续步骤
- 探索 Bigtable 文档
- 如需了解高级配置和切换流程,请参阅 DataStax ZDM 代理文档。
- 如需了解详情,请查看 Cassandra-Bigtable Proxy 代码库。
- 如需了解高级用法,请参阅 Cassandra Data Migrator 代码库。
- 试用其他 Google Cloud Codelab