使用雙寫 Proxy 從 Cassandra 遷移至 Bigtable

1. 簡介

Bigtable 是全代管的高效能 NoSQL 資料庫服務,適合用來處理大型分析和作業工作負載。從 Apache Cassandra 等現有資料庫遷移至 Bigtable 時,通常需要仔細規劃,才能盡量縮短停機時間,並減少對應用程式的影響。

本程式碼研究室將示範如何結合使用下列 Proxy 工具,從 Cassandra 遷移至 Bigtable:

  1. Cassandra-Bigtable Proxy:可翻譯查詢,讓 Cassandra 用戶端和工具 (例如 cqlsh 或驅動程式) 使用 Cassandra 查詢語言 (CQL) 通訊協定與 Bigtable 互動。
  2. Datastax 零停機時間遷移 (ZDM) Proxy:這項開放原始碼 Proxy 位於應用程式和資料庫服務之間 (原始 Cassandra 和目標 Bigtable,透過 Cassandra-Bigtable Proxy)。這項服務會自動化調度雙重寫入作業,並管理流量路徑,因此您只需進行最少的應用程式變更,就能完成遷移作業,且停機時間極短。
  3. Cassandra 資料移轉工具 (CDM):這項開放原始碼工具可用於將來源 Cassandra 叢集中的大量歷史資料,移轉至目標 Bigtable 執行個體。

課程內容

  • 如何在 Compute Engine 上設定基本 Cassandra 叢集。
  • 如何建立 Bigtable 執行個體。
  • 如何部署及設定 Cassandra-Bigtable Proxy,將 Cassandra 結構定義對應至 Bigtable。
  • 說明如何部署及設定 Datastax ZDM Proxy,以進行雙重寫入。
  • 如何使用 Cassandra 資料遷移工具大量遷移現有資料。
  • 以 Proxy 為基礎,從 Cassandra 遷移至 Bigtable 的整體工作流程。

軟硬體需求

  • 啟用計費功能的 Google Cloud 專案。新使用者可免費試用
  • 熟悉 Google Cloud 的基本概念,例如專案、Compute Engine、虛擬私有雲端網路和防火牆規則。熟悉 Linux 指令列工具的基本操作。
  • 存取已安裝及設定 gcloud CLI 的機器,或使用 Google Cloud Shell

在本程式碼研究室中,我們主要會使用同一個虛擬私有雲網路和區域中的 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. 設定防火牆規則

我們需要允許預設虛擬私有雲網路中的 VM 在多個通訊埠上進行通訊:

  • Cassandra/Proxies CQL 連接埠:9042
  • ZDM Proxy 健康狀態檢查通訊埠:14001
  • SSH:22

建立防火牆規則,允許這些通訊埠上的內部流量。我們將使用標記 cassandra-migration,輕鬆將這項規則套用至相關 VM。

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 叢集 (來源)

在本程式碼研究室中,我們將在 Compute Engine 上設定簡單的單一節點 Cassandra 叢集。在實際情況中,您會連線至現有叢集。

1. 為 Cassandra 建立 GCE VM

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
  1. seed_provider.parameters.seeds 設為 "CASSANDRA_ORIGIN_PRIVATE_IP:7000"
  2. rpc_address 設為 CASSANDRA_ORIGIN_PRIVATE_IP
  3. 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 工作階段開啟,或記下這個 VM 的 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

Cassandra-Bigtable Proxy 設定指令碼稍後會建立 Bigtable 資料表。

5. 設定 Cassandra-Bigtable Proxy

1. 為 Cassandra-Bigtable Proxy 建立 Compute Engine VM

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 Proxy

啟動 Proxy 伺服器。

# 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)

Proxy 會啟動並監聽通訊埠 9042,以接收傳入的 CQL 連線。請讓這個終端機工作階段保持執行狀態。記下這個 VM 的 IP 位址 (主機名稱 -I)

3. 透過 CQL 建立資料表

將 CQLSH 連線至 Cassandra-Bigtable Proxy VM 的 IP 位址。您可以在本機執行下列指令,找出 IP 位址:

gcloud compute instances describe bigtable-proxy-vm --format='get(networkInterfaces[0].networkIP)'

在另一個視窗中,透過 SSH 連線至 cassandra-origin VM,並使用 cqlsh 連線至 bigtable-proxy。請注意,我們將要求逾時時間設得比預設值更長,確保 Bigtable 有足夠時間建立基礎資料表。您應該會看到「Connected to cassandra-bigtable-proxy-v0.2.3」或類似訊息,表示您已連線至 Bigtable Proxy,而非本機 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 Proxy

在本實驗室中,我們將建立 ZDM Proxy 的單一執行個體,但您會需要多節點設定,才能進行正式版遷移。

1. 建立 ZDM Proxy VM

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

記下這兩個 VM 的 IP 位址。

2. 準備 ZDM Proxy

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 Proxy VM 的 IP 位址 (例如 :9042),而不是直接連線至 Cassandra。

應用程式連線至 ZDM Proxy 後,系統預設會從來源 (Cassandra) 提供讀取作業。系統會將寫入作業傳送至來源 (Cassandra) 和目標 (透過 Cassandra-Bigtable Proxy 傳送至 Bigtable)。這樣一來,應用程式就能繼續正常運作,同時確保新資料會同時寫入兩個資料庫。您可以透過指向 ZDM Proxy 的 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。如要確認這點,請前往 Google Cloud 控制台,開啟執行個體的 Bigtable 查詢編輯器。執行「SELECT * FROM employee」查詢,最近插入的資料應該會顯示出來。

8. 使用 Cassandra 資料遷移工具遷移歷來資料

新資料的雙重寫入功能已啟用,現在請使用 Cassandra 資料移轉工具 (CDM),將現有的歷來資料從 Cassandra 複製到 Bigtable。

1. 為 CDM 建立 Compute Engine VM

這個 VM 需要足夠的記憶體才能執行 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

在 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,使用您的屬性檔案,並指定要遷移的鍵空間和資料表。根據 VM 大小和資料量調整記憶體設定 (–driver-memory、–executor-memory)。

確認您位於包含 CDM JAR 和屬性檔案的目錄中。

提示:您可以在本機電腦執行下列指令,取得 Cassandra 和 Proxy VM 的內部 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 Proxy 時,轉換作業需要重新設定 Proxy,主要從目標 (Bigtable) 讀取資料,而不是來源 (Cassandra)。這通常是透過 ZDM Proxy 的設定完成,可有效將應用程式的讀取流量轉移至 Bigtable。

確認 Bigtable 能正確處理所有流量後,您最終可以:

  • 重新設定 ZDM Proxy,停止雙重寫入。
  • 停用原始 Cassandra 叢集。
  • 移除 ZDM Proxy,讓應用程式直接連線至 Cassandra-Bigtable Proxy,或使用 Java 的原生 Bigtable CQL 用戶端。

本基本程式碼研究室不會詳細說明如何重新設定 ZDM Proxy 以進行轉換,但 Datastax ZDM 說明文件會提供相關資訊。

10. 清除所用資源

為避免產生費用,請刪除在本程式碼研究室中建立的資源。

1. 刪除 Compute Engine VM

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 VM 以外的位置安裝 Cassandra,請按照適當步驟移除資料或解除安裝 Cassandra。

11. 恭喜!

您已成功完成設定程序,透過 Proxy 將資料從 Apache Cassandra 遷移至 Bigtable!

您已學會如何:

部署 Cassandra 和 Bigtable。

  • 設定 Cassandra-Bigtable Proxy,確保 CQL 相容性。
  • 部署 Datastax ZDM Proxy,管理雙重寫入和流量。
  • 使用 Cassandra Data Migrator 遷移歷來資料。

這個方法會運用 Proxy 層,因此遷移作業的停機時間極短,且不需要變更程式碼。

後續步驟

  • 探索 Bigtable 說明文件
  • 如需進階設定和轉換程序,請參閱 Datastax ZDM Proxy 說明文件。
  • 詳情請參閱 Cassandra-Bigtable Proxy 存放區。
  • 如需進階用法,請查看 Cassandra Data Migrator 存放區。
  • 試試其他 Google Cloud 程式碼研究室