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.
Prasyarat
Provisikan kluster Azure Managed Instance for Apache Cassandra dengan menggunakan portal Microsoft Azure atau CLI Azure. Pastikan Anda dapat tersambung ke kluster Anda dengan CQLSH.
Provisikan akun Azure Databricks di dalam jaringan virtual Managed Cassandra. Pastikan akun memiliki akses jaringan ke sumber kluster Cassandra Anda. Kami akan membuat kluster Spark di akun ini untuk muatan data riwayat.
Pastikan Anda telah memindahkan skema keyspacei/tabel dari sumber database Cassandra Anda ke target database instans-Cassandra managed Anda.
Provisi kluster Spark
Kami merekomendasikan memilih Azure Databricks versi runtime 7.5, yang mendukung Spark 3.0.
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.
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.