Bagikan melalui


Perpindahan langsung Azure Managed Instance for Apache Cassandra dengan menggunakan proksi dual-write

Jika memungkinkan, sebaiknya gunakan kemampuan asli Apache Cassandra untuk memindahkan data dari kluster yang ada ke Azure Managed Instance for Apache Cassandra dengan mengonfigurasi kluster hibrida. Kemampuan ini menggunakan protokol gosip Apache Cassandra untuk mereplikasi data dari pusat data sumber Anda ke pusat data instans terkelola yang baru tanpa hambatan. Tetapi, mungkin ada beberapa skenario dimana versi database sumber Anda tidak cocok, atau pengaturan kluster hibrida tidak layak.

Tutorial ini menjelaskan cara memigrasikan data ke Azure Managed Instance for Apache Cassandra secara langsung menggunakan proksi tulis ganda dan Apache Spark. Proksi tulis ganda digunakan untuk menangkap perubahan langsung, sementara data historis disalin secara massal menggunakan Apache Spark. Keuntungan-keuntungan dari pendekatan ini adalah:

  • Perubahan aplikasi minimal. Proksi dapat menerima koneksi dari kode aplikasi Anda dengan sedikit atau tanpa perubahan konfigurasi. Hal ini akan merutekan semua permintaan ke database sumber Anda dan secara asinkron merutekan menulis ke target sekunder.
  • Dependensi protokol kabel klien. Karena pendekatan ini tidak bergantung pada sumber daya back-end atau protokol internal, hal ini dapat digunakan dengan sumber apa pun atau target sistem Cassandra yang mengimplementasikan protokol kabel Apache Cassandra.

Gambar berikut mengilustrasikan pendekatan.

Animasi yang menampilkan perpindahan data langsung ke Azure Managed Instance for Apache Cassandra.

Prasyarat

Provisi kluster Spark

Kami merekomendasikan memilih Azure Databricks versi runtime 7.5, yang mendukung Spark 3.0.

Cuplikan layar yang menampilkan penemuan versi runtime Azure Databricks.

Tambahkan ketergantungan Spark

Anda perlu menambahkan pustaka Konektor Apache Spark Cassandra ke kluster Anda untuk terhubung ke protokol kawat apa pun yang kompatibel dengan titik akhir Apache Cassandra. Di klaster Anda, pilih Pustaka>Pasang Baru>Maven, lalu tambahkan com.datastax.spark:spark-cassandra-connector-assembly_2.12:3.0.0 di koordinat Maven.

Penting

Jika Anda memiliki persyaratan untuk mempertahankan Apache Cassandra writetime untuk setiap baris selama migrasi, sebaiknya gunakan sampel ini. Jar dependensi dalam sampel ini juga berisi konektor Spark, jadi Anda harus menginstal ini, bukan rangkaian konektor di atas. Sampel ini juga berguna jika Anda ingin melakukan validasi perbandingan baris antara sumber dan target setelah pemuatan data historis selesai. Lihat bagian "menjalankan pemuatan data historis" dan "memvalidasi sumber dan target" di bawah untuk detail selengkapnya.

Cuplikan layar yang menampilkan pencarian paket Maven di Azure Databricks.

Pilih Pasang, lalu mulai ulang klaster ketika pemasangan selesai.

Catatan

Pastikan untuk memulai ulang kluster Azure Databricks setelah pustaka Konektor Cassandra terpasang.

Pasang proksi dual-write

Untuk tampilan optimal selama dual writes, kami merekomendasikan untuk menginstal proksi pada seluruh node dalam sumber kluster Cassandra Anda.

#assuming you do not have git already installed
sudo apt-get install git 

#assuming you do not have maven already installed
sudo apt install maven

#clone repo for dual-write proxy
git clone https://github.com/Azure-Samples/cassandra-proxy.git

#change directory
cd cassandra-proxy

#compile the proxy
mvn package

Mulai proksi dual-write

Kami merekomendasikan untuk memasang proksi pada seluruh simpul dalam sumber kluster Cassandra. Pada kondisi minimum, jalankan perintah berikut untuk memulai proksi di setiap simpul. Ganti <target-server> dengan sebuah IP atau alamat server dari satu node dalam kluster target. Ganti <path to JKS file> dengan jalur ke file .jks lokal, dan ganti <keystore password> dengan kata sandi terkait.

java -jar target/cassandra-proxy-1.0-SNAPSHOT-fat.jar localhost <target-server> --proxy-jks-file <path to JKS file> --proxy-jks-password <keystore password>

Mulai proksi dengan cara ini dengan asumsi bahwa poin-poin berikut adalah benar:

  • Titik akhir sumber dan target memiliki nama pengguna dan kata sandi yang sama.
  • Titik akhir sumber dan target mengimplementasikan Secure Sockets Layer (SSL).

Jika titik akhir sumber dan target Anda tidak dapat memenuhi kriteria tersebut, baca terus untuk opsi konfigurasi lebih lanjut.

Konfigurasikan SSL

Untuk SSL, Anda dapat mengimplementasi sebuah keystore yang sudah ada (contohnya, yang digunakan oleh sumber kluster Anda), atau membuat sertifikat dengan tanda tangan sendiri menggunakan keytool:

keytool -genkey -keyalg RSA -alias selfsigned -keystore keystore.jks -storepass password -validity 360 -keysize 2048

Anda juga dapat menonaktifkan SSL untuk titik akhir sumber atau target jika tidak mengimplementasi SSL. Gunakan --disable-source-tls atau --disable-target-tls flags:

java -jar target/cassandra-proxy-1.0-SNAPSHOT-fat.jar localhost <target-server> --source-port 9042 --target-port 10350 --proxy-jks-file <path to JKS file> --proxy-jks-password <keystore password> --target-username <username> --target-password <password> --disable-source-tls true  --disable-target-tls true 

Catatan

Pastikan aplikasi klien Anda menggunakan keystore dan kata sandi yang sama dengan yang digunakan untuk proksi dual-write ketika menyambungkan koneksi SSL ke database melalui proksi tersebut.

Konfigurasikan informasi masuk dan port

Secara default, sumber informasi masuk akan diteruskan melalui aplikasi klien Anda. Proksi akan menggunakan informasi masuk untuk membuat koneksi ke kluster sumber dan target. Seperti disebutkan sebelumnya, proses ini mengasumsikan bahwa informasi masuk sumber dan target adalah sama. Jika dibutuhkan, Anda dapat menentukan nama pengguna dan kata sandi yang berbeda untuk target titik akhir Cassandra secara terpisah saat memulai proksi:

java -jar target/cassandra-proxy-1.0-SNAPSHOT-fat.jar localhost <target-server> --proxy-jks-file <path to JKS file> --proxy-jks-password <keystore password> --target-username <username> --target-password <password>

Port sumber dan target default, saat tidak ditentukan, akan menjadi 9042. Jika titik akhir Cassandra target atau sumber dijalankan pada port yang berbeda, Anda dapat menggunakan --source-port atau --target-port untuk menentukan nomor port yang berbeda:

java -jar target/cassandra-proxy-1.0-SNAPSHOT-fat.jar localhost <target-server> --source-port 9042 --target-port 10350 --proxy-jks-file <path to JKS file> --proxy-jks-password <keystore password> --target-username <username> --target-password <password>

Sebarkan proksi dari jarak jauh

Mungkin ada keadaan dimana Anda tidak ingin memasang proksi pada node kluster, dan memilih untuk memasangnya pada komputer terpisah. Dalam skenario itu, Anda perlu menentukan alamat IP <source-server>:

java -jar target/cassandra-proxy-1.0-SNAPSHOT-fat.jar <source-server> <destination-server>

Peringatan

Jika Anda lebih suka menjalankan proksi dari jarak jauh pada komputer terpisah (daripada menjalankannya pada semua simpul di kluster Apache Cassandra sumber Anda), sebaiknya sebarkan proksi ke jumlah komputer yang sama seperti Anda memiliki simpul di kluster Anda, dan menyiapkan pengganti alamat IP mereka di system.peer menggunakan konfigurasi dalam proksi yang disebutkan di sini. Jika Anda tidak melakukan ini, hal ini dapat memengaruhi performa saat migrasi langsung terjadi, karena driver klien tidak akan dapat membuka koneksi ke semua node dalam kluster.

Izinkan perubahan kode aplikasi nol

Secara default, proksi tersebut mengikuti port 29042. Kode aplikasi harus diubah pada titik port ini. Tetapi, Anda juga bisa mengubah port yang diikuti oleh proksi. Anda dapat melakukan ini jika Anda ingin menghilangkan perubahan kode tingkat aplikasi dengan:

  • Menjalankan sumber server Cassandra pada port yang berbeda.
  • Menjalankan proksi pada port Cassandra standar 9042.
java -jar target/cassandra-proxy-1.0-SNAPSHOT-fat.jar source-server destination-server --proxy-port 9042

Catatan

Menginstal proksi pada kluster node tidak membutuhkan restart node. Namun, jika Anda memiliki banyak klien aplikasi dan memilih untuk menjalankan proksi pada port 9042 standar Cassandra untuk menghilangkan perubahan kode level aplikasi, Anda perlu mengubah port default Apache Cassandra. Anda kemudian perlu memulai ulang simpul di kluster Anda, dan mengonfigurasi port sumber untuk menjadi port baru yang Anda tentukan untuk sumber kluster Cassandra Anda.

Dalam contoh berikut, kami mengubah sumber kluster Cassandra untuk dijalankan pada port 3074, dan kami memulai kluster pada port 9042:

java -jar target/cassandra-proxy-1.0-SNAPSHOT-fat.jar source-server destination-server --proxy-port 9042 --source-port 3074

Protokol paksa

Proksi tersebut memiliki beberapa fungsi untuk memaksa protokol-protokol yang mungkin diperlukan jika titik akhir sumber lebih modern daripada target atau jika target tidak mendukung. Dalam hal ini, Anda dapat menentukan --protocol-version dan --cql-version untuk memaksa protokol mematuhi target:

java -jar target/cassandra-proxy-1.0-SNAPSHOT-fat.jar source-server destination-server --protocol-version 4 --cql-version 3.11

Setelah proksi dual-write berjalan, Anda perlu mengubah port pada aplikasi klien Anda dan memulai ulang. (Atau ubah port Cassandra dan mulai ulang kluster jika Anda telah memilih pendekatan tersebut.) Proksi kemudian akan mulai meneruskan menulis ke titik akhir target. Anda bisa mempelajari tentang pantauan dan metrik tersedia di alat proksi.

Jalankan muatan data riwayat

Untuk memuat data, buatlah catatan Scala di dalam akun Azure Databricks Anda. Ganti konfigurasi Cassandra sumber dan target Anda dengan informasi masuk terkait, dan ganti keyspace dan tabel sumber dan target. Tambahkan variabel lebih untuk tiap tabel sesuai kebutuhan ke contoh berikut, kemudian jalankan. Setelah aplikasi Anda mulai mengirimkan permintaan ke proksi dual-write, Anda siap untuk memindahkan data riwayat.

import com.datastax.spark.connector._
import com.datastax.spark.connector.cql._
import org.apache.spark.SparkContext

// source cassandra configs
val sourceCassandra = Map( 
    "spark.cassandra.connection.host" -> "<Source Cassandra Host>",
    "spark.cassandra.connection.port" -> "9042",
    "spark.cassandra.auth.username" -> "<USERNAME>",
    "spark.cassandra.auth.password" -> "<PASSWORD>",
    "spark.cassandra.connection.ssl.enabled" -> "true",
    "keyspace" -> "<KEYSPACE>",
    "table" -> "<TABLE>"
)

//target cassandra configs
val targetCassandra = Map( 
    "spark.cassandra.connection.host" -> "<Source Cassandra Host>",
    "spark.cassandra.connection.port" -> "9042",
    "spark.cassandra.auth.username" -> "<USERNAME>",
    "spark.cassandra.auth.password" -> "<PASSWORD>",
    "spark.cassandra.connection.ssl.enabled" -> "true",
    "keyspace" -> "<KEYSPACE>",
    "table" -> "<TABLE>",
    //throughput related settings below - tweak these depending on data volumes. 
    "spark.cassandra.output.batch.size.rows"-> "1",
    "spark.cassandra.output.concurrent.writes" -> "1000",
    "spark.cassandra.connection.remoteConnectionsPerExecutor" -> "1",
    "spark.cassandra.concurrent.reads" -> "512",
    "spark.cassandra.output.batch.grouping.buffer.size" -> "1000",
    "spark.cassandra.connection.keep_alive_ms" -> "600000000"
)

//set timestamp to ensure it is before read job starts
val timestamp: Long = System.currentTimeMillis / 1000

//Read from source Cassandra
val DFfromSourceCassandra = sqlContext
  .read
  .format("org.apache.spark.sql.cassandra")
  .options(sourceCassandra)
  .load
  
//Write to target Cassandra
DFfromSourceCassandra
  .write
  .format("org.apache.spark.sql.cassandra")
  .options(targetCassandra)
  .option("writetime", timestamp)
  .mode(SaveMode.Append)
  .save

Catatan

Dalam sampel Scala sebelumnya, Anda akan melihat bahwa timestamp sedang diatur ke waktu saat ini sebelum membaca semua data dalam tabel sumber. Kemudian, writetime sedang diatur ke penandaan waktu dengan kondisi.backdated ini. Hal ini untuk meyakinkan bahwa rekaman-rekaman yang dituliskan dari muatan data riwayat ke titik akhir target tidak bisa menimpa pembaruan yang datang dengan penandaan waktu selanjutnya dari proksi dual-write saat riwayat data sedang dibaca.

Penting

Jika Anda butuh mempertahankan penandaan waktu tertentu karena suatu alasan, Anda disarankan untuk melakukan pendekatan pemindahan data riwayat yang mempertahankan penandaan waktu, seperti contoh berikut ini. Jar dependensi dalam sampel juga berisi konektor Spark, jadi Anda tidak perlu menginstal rangkaian konektor Spark yang disebutkan di prasyarat sebelumnya - menginstal keduanya di kluster Spark Anda akan menyebabkan konflik.

Validasi sumber dan target

Saat muatan data riwayat sudah lengkap, database Anda seharusnya sudah sinkron dan siap untuk dipindahkan langsung. Namun, sebaiknya Anda memvalidasi sumber dan target untuk memastikan mereka cocok sebelum akhirnya memotongnya.

Catatan

Jika Anda menggunakan sampel cassandra migrator yang disebutkan di atas untuk mempertahankan writetime, hal ini mencakup kemampuan untuk memvalidasi migrasi dengan membandingkan baris di sumber dan target berdasarkan toleransi tertentu.

Langkah berikutnya