1. 简介
Bigtable 是一种全托管式高性能 NoSQL 数据库服务,专用于处理大规模分析和运营工作负载。从 Apache Cassandra 等现有数据库迁移到 Bigtable 通常需要仔细规划,以最大限度地减少停机时间和应用影响。
此 Codelab 演示了如何结合使用代理工具,将数据从 Cassandra 迁移到 Bigtable:
- Cassandra-Bigtable 代理:通过翻译查询,允许 Cassandra 客户端和工具(例如 cqlsh或驱动程序)使用 Cassandra 查询语言 (CQL) 协议与 Bigtable 进行互动。
- Datastax 零停机时间迁移 (ZDM) 代理:一个开源代理,位于您的应用和数据库服务(源 Cassandra 和目标 Bigtable,通过 Cassandra-Bigtable 代理)之间。它可编排双重写入并管理流量路由,从而以最少的应用更改和停机时间实现迁移。
- Cassandra Data Migrator (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 命令行工具。
- 访问安装并配置了 gcloudCLI 的机器,或使用 Google Cloud Shell。
在本实验中,我们将主要使用同一 VPC 网络和区域内的 Compute Engine 虚拟机 (VM),以简化网络配置。建议使用内部 IP 地址。
2. 设置您的环境
1. 选择或创建 Google Cloud 项目
前往 Google Cloud 控制台,然后选择现有项目或创建新项目。记下您的项目 ID。
2. 选择区域和可用区
为您的资源选择区域和可用区。我们将以 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
3. 启用必需的 API
确保已为您的项目启用 Compute Engine API 和 Bigtable API。
gcloud services enable compute.googleapis.com bigtable.googleapis.com bigtableadmin.googleapis.com
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:7000,tcp:14001 \
--source-ranges=10.0.0.0/8 \
--target-tags=cassandra-migration
3. 部署 Cassandra 集群(原始)
在此 Codelab 中,我们将在 Compute Engine 上设置一个简单的单节点 Cassandra 集群。在实际应用场景中,您需要连接到现有集群。
1. 为 Cassandra 创建 GCE 虚拟机
gcloud compute instances create cassandra-origin \
--machine-type=e2-medium \
--image-family=ubuntu-2204-lts \
--image-project=ubuntu-os-cloud \
--tags=cassandra-migration \
--boot-disk-size=20GB \
--scopes=cloud-platform \
--zone="$ZONE"
通过 SSH 连接到 Cassandra 实例
gcloud compute ssh --zone="$ZONE" "cassandra-origin"
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 41x main" | sudo tee -a /etc/apt/sources.list.d/cassandra.sources.list
curl https://downloads.apache.org/cassandra/KEYS | sudo apt-key add -
# Install Cassandra
sudo apt update
sudo apt install -y cassandra
# (Optional) Verify Cassandra is running
sudo systemctl status cassandra
3. 配置 Cassandra
我们需要配置 Cassandra,使其可在专用网络中访问。
运行以下命令,获取 cassandra-origin 的专用 IP:
hostname -I
修改 Cassandra 配置,您无需添加任何新的配置行,只需更新已有的配置行:
sudo vim /etc/cassandra/cassandra.yaml
- 将 seed_provider.parameters.seeds设置为"CASSANDRA_ORIGIN_PRIVATE_IP:7000"
- 将 rpc_address设置为CASSANDRA_ORIGIN_PRIVATE_IP
- 将 listen_address设置为CASSANDRA_ORIGIN_PRIVATE_IP
保存文件。
最后,重启 Cassandra 以加载配置更改:
sudo systemctl restart cassandra
# (Optional) Verify Cassandra is running
sudo systemctl status cassandra
4. 创建键空间和表
我们将使用一个员工表示例,并创建一个名为“zdmbigtable”的键空间。
注意:Cassandra 可能需要一分钟时间才能开始接受连接。
# Start cqlsh
cqlsh $(hostname -I)
在 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 iam service-accounts create bigtable-proxy-sa \
    --description="Service account for Bigtable Proxy access" \
    --display-name="Bigtable Proxy Access SA"
export BIGTABLE_PROXY_SA_EMAIL=$(gcloud iam service-accounts list --filter="displayName='Bigtable Proxy Access SA'" --format="value(email)")
gcloud bigtable instances add-iam-policy-binding zdmbigtable \
  --member="serviceAccount:$BIGTABLE_PROXY_SA_EMAIL" \
  --role="roles/bigtable.admin"
gcloud compute instances create bigtable-proxy-vm \
--machine-type=e2-medium \
--image-family=ubuntu-2204-lts \
--image-project=ubuntu-os-cloud \
--tags=cassandra-migration \
--boot-disk-size=20GB \
--zone=$ZONE \
--scopes=cloud-platform \
--service-account="$BIGTABLE_PROXY_SA_EMAIL"
通过 SSH 连接到 bigtable-proxy-vm:
gcloud compute ssh --zone="$ZONE" "bigtable-proxy-vm"
在 bigtable-proxy-vm 上运行:
# Install Git and Go
sudo apt-get update
sudo apt-get install -y git
wget https://go.dev/dl/go1.23.6.linux-amd64.tar.gz
sudo rm -rf /usr/local/go
sudo tar -C /usr/local -xzf go1.23.6.linux-amd64.tar.gz
echo 'export GOPATH=$HOME/go' >> ~/.profile
echo 'export PATH=$PATH:/usr/local/go/bin:$GOPATH/bin' >> ~/.profile
source ~/.profile
# Clone the proxy repository
git clone https://github.com/GoogleCloudPlatform/cloud-bigtable-ecosystem.git
cd cloud-bigtable-ecosystem/cassandra-bigtable-migration-tools/cassandra-bigtable-proxy/
2. 启动 Cassandra-Bigtable 代理
启动代理服务器。
# At the root of the cassandra-to-bigtable-proxy directory
go run proxy.go --project-id="$(gcloud config get-value project)" --instance-id=zdmbigtable --keyspace-id=zdmbigtable --rpc-address=$(hostname -I)
代理将启动并侦听端口 9042 以接收传入的 CQL 连接。保持此终端会话处于运行状态。记下此虚拟机的 IP 地址(主机名 -I)
3. 通过 CQL 创建表
将 CQLSH 连接到 Cassandra-Bigtable 代理虚拟机的 IP 地址。您可以在本地运行以下命令来查找 IP 地址:
gcloud compute instances describe bigtable-proxy-vm --format='get(networkInterfaces[0].networkIP)'
在单独的窗口中,通过 SSH 连接到 cassandra-origin 虚拟机,并使用 cqlsh 连接到 bigtable-proxy。请注意,我们设置了比默认值更长的请求超时时间,以确保 Bigtable 有足够的时间来创建底层表。您应该会看到“Connected to cassandra-bigtable-proxy-v0.2.3”或类似消息,表明您已连接到 Bigtable 代理,而不是本地 Cassandra 服务器。
# Replace <your-bigtable-proxy-vm-ip> with the ip from the above command
export BIGTABLE_PROXY_IP=<your-bigtable-proxy-vm-ip>
cqlsh --request-timeout=60 $BIGTABLE_PROXY_IP
-- 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
);
在 CQLSH 中,运行以下命令,验证表是否已创建:
DESC TABLE zdmbigtable.employee;
6. 设置 ZDM 代理
在此实验中,我们将创建一个 ZDM 代理实例,但在生产环境迁移中,您需要设置多节点。
1. 创建 ZDM 代理虚拟机
gcloud compute instances create zdm-proxy-vm \
--machine-type=e2-medium \
--image-family=ubuntu-2204-lts \
--image-project=ubuntu-os-cloud \
--tags=cassandra-migration \
--boot-disk-size=20GB \
--scopes=cloud-platform \
--zone=$ZONE
记下这两个虚拟机的 IP 地址。
2. 准备 ZDM 代理
gcloud compute ssh --zone="$ZONE" zdm-proxy-vm
export ZDM_VERSION="2.3.4"
wget "https://github.com/datastax/zdm-proxy/releases/download/v$ZDM_VERSION/zdm-proxy-linux-amd64-v$ZDM_VERSION.tgz"
tar -xvzf "zdm-proxy-linux-amd64-v$ZDM_VERSION.tgz"
# replace YOUR_ZONE
gcloud config set compute/zone "YOUR_ZONE"
export ZDM_ORIGIN_CONTACT_POINTS=$(gcloud compute instances describe cassandra-origin --format='get(networkInterfaces[0].networkIP)') 
export ZDM_TARGET_CONTACT_POINTS=$(gcloud compute instances describe bigtable-proxy-vm --format='get(networkInterfaces[0].networkIP)')
export ZDM_ORIGIN_USERNAME=""
export ZDM_ORIGIN_PASSWORD=""
export ZDM_TARGET_USERNAME=""
export ZDM_TARGET_PASSWORD=""
export ZDM_PROXY_LISTEN_ADDRESS=0.0.0.0
export ZDM_PROXY_LISTEN_PORT=9042
./zdm-proxy-v${ZDM_VERSION}
7. 配置应用并开始双重写入
时长 0:05
在实际迁移的此阶段,您需要重新配置应用,使其指向 ZDM 代理虚拟机的 IP 地址(例如 :9042),而不是直接连接到 Cassandra。
应用连接到 ZDM 代理后:默认情况下,读取由源 (Cassandra) 提供。写入操作会同时发送到源(Cassandra)和目标(通过 Cassandra-Bigtable 代理发送到 Bigtable)。这样一来,您的应用就可以继续正常运行,同时确保新数据同时写入两个数据库。您可以使用指向 ZDM 代理的 cqlsh 测试连接:
cqlsh $(gcloud compute instances describe zdm-proxy-vm --format='get(networkInterfaces[0].networkIP)')
尝试插入一些数据:
INSERT INTO zdmbigtable.employee (name, age, is_active) VALUES ('Alice', 30, true); 
INSERT INTO zdmbigtable.employee (name, age, is_active) VALUES ('Anna', 45, true); 
INSERT INTO zdmbigtable.employee (name, age, is_active) VALUES ('Albert', 50, false); 
SELECT * FROM zdmbigtable.employee;
这些数据应同时写入 Cassandra 和 Bigtable。您可以在 Bigtable 中确认这一点,方法是前往 Google Cloud 控制台,然后打开实例的 Bigtable 查询编辑器。运行“SELECT * FROM employee”查询,您应该会看到最近插入的数据。
8. 使用 Cassandra Data Migrator 迁移历史数据
现在,双重写入已针对新数据处于有效状态,请使用 Cassandra Data Migrator (CDM) 工具将现有的历史数据从 Cassandra 复制到 Bigtable。
1. 为 CDM 创建 Compute Engine 虚拟机
此虚拟机需要足够的内存来运行 Spark。
gcloud compute instances create cdm-migrator-vm \
--machine-type=e2-medium \
--image-family=ubuntu-2204-lts \
--image-project=ubuntu-os-cloud \
--tags=cassandra-migration \
--boot-disk-size=40GB \
--scopes=cloud-platform \
--zone=$ZONE
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
tar -xvzf spark-3.5.3-bin-hadoop3-scala2.13.tgz
echo 'export SPARK_HOME=$PWD/spark-3.5.3-bin-hadoop3-scala2.13' >> ~/.profile
echo 'export PATH=$PATH:$SPARK_HOME/bin' >> ~/.profile
source ~/.profile
3. 下载 Cassandra Data Migrator
在浏览器中,打开 CDM Packages 页面,然后从“Assets”面板中复制 .jar 链接。如果 5.4.0 不可用,请选择最接近的版本。将该链接粘贴到以下命令中,并在 cdm-migrator-vm 实例上运行该命令,同时保留网址周围的英文单引号。
wget 'JAR_URL_GOES_HERE' -O cassandra-data-migrator.jar
使用 jar 工具扫描 jar 文件,验证该文件是否已正确下载:您应该会看到一个很长的“.class”文件列表。
jar tf cassandra-data-migrator.jar 
4. 添加一些数据
我们需要通过直接写入 cassandra-origin(而非 zdm-proxy-vm)来添加一些要迁移的数据
INSERT INTO zdmbigtable.employee (name, age, is_active) VALUES ('Alfred', 67, true); 
INSERT INTO zdmbigtable.employee (name, age, is_active) VALUES ('Bobby', 12, false); 
INSERT INTO zdmbigtable.employee (name, age, is_active) VALUES ('Carol', 29, true); 
5. 运行迁移作业
使用 spark-submit 执行迁移。此命令会指示 Spark 运行 CDM JAR,使用您的属性文件并指定要迁移的键空间和表。根据虚拟机大小和数据量调整内存设置(–driver-memory、–executor-memory)。
确保您位于包含 CDM JAR 和属性文件的目录中。
提示:您可以在本地机器上运行以下命令,获取 Cassandra 和代理虚拟机的内部 IP:
gcloud compute instances describe cassandra-origin --format='get(networkInterfaces[0].networkIP)'
gcloud compute instances describe bigtable-proxy-vm --format='get(networkInterfaces[0].networkIP)'
export ORIGIN_HOST="<your-cassandra-origin-ip>"
export TARGET_HOST="<your-bigtable-proxy-vm-ip>"
export KEYSPACE_TABLE="zdmbigtable.employee"
spark-submit --verbose --master "local[*]" \
--driver-memory 3G --executor-memory 3G \
--conf spark.cdm.schema.origin.keyspaceTable="$KEYSPACE_TABLE" \
--conf spark.cdm.connect.origin.host="$ORIGIN_HOST" \
--conf spark.cdm.connect.origin.port=9042 \
--conf spark.cdm.connect.target.host="$TARGET_HOST" \
--conf spark.cdm.connect.target.port=9042 \
--conf spark.cdm.feature.origin.ttl.automatic=false \
--conf spark.cdm.feature.origin.writetime.automatic=false \
--conf spark.cdm.feature.target.ttl.automatic=false \
--conf spark.cdm.feature.target.writetime.automatic=false \
--conf spark.cdm.schema.origin.column.ttl.automatic=false \
--conf spark.cdm.schema.ttlwritetime.calc.useCollections=false \
--class com.datastax.cdm.job.Migrate cassandra-data-migrator.jar
6. 验证数据迁移
CDM 作业成功完成后,验证 Bigtable 中是否存在历史数据。
cqlsh <bigtable-proxy-vm-ip>
在 cqlsh 中:
SELECT COUNT(*) FROM zdmbigtable.employee; -- Check row count matches origin 
SELECT * FROM zdmbigtable.employee LIMIT 10; -- Check some sample data
9. 割接(概念性)
在彻底验证 Cassandra 和 Bigtable 之间的数据一致性后,您可以继续进行最终切换。
借助 ZDM 代理,切换涉及重新配置该代理,使其主要从目标 (Bigtable) 而不是源 (Cassandra) 读取数据。这通常通过 ZDM 代理的配置来实现,从而有效地将应用的读取流量转移到 Bigtable。
在确信 Bigtable 能够正确处理所有流量后,您最终可以:
- 通过重新配置 ZDM 代理来停止双重写入。
- 停用原始 Cassandra 集群。
- 移除 ZDM 代理,让应用直接连接到 Cassandra-Bigtable 代理,或使用原生 Bigtable CQL 客户端(适用于 Java)。
有关 ZDM 代理在切换期间重新配置的具体细节超出了本基本 Codelab 的范围,但 Datastax ZDM 文档中对此进行了详细说明。
10. 清理
为避免产生费用,请删除在本 Codelab 中创建的资源。
1. 删除 Compute Engine 虚拟机
gcloud compute instances delete cassandra-origin zdm-proxy-vm 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 Data Migrator 迁移历史数据。
此方法利用代理层,可实现停机时间最短且无需更改代码的迁移。
后续步骤
- 探索 Bigtable 文档
- 如需了解高级配置和切换程序,请参阅 Datastax ZDM 代理文档。
- 如需了解详情,请查看 Cassandra-Bigtable 代理代码库。
- 如需了解高级用法,请查看 Cassandra Data Migrator 代码库。
- 尝试其他 Google Cloud Codelab