Migracja na żywo do wystąpienia zarządzanego platformy Azure dla usługi Apache Cassandra przy użyciu serwera proxy z podwójnym zapisem
Jeśli to możliwe, zalecamy użycie natywnej funkcji apache Cassandra do migrowania danych z istniejącego klastra do wystąpienia zarządzanego platformy Azure dla usługi Apache Cassandra przez skonfigurowanie klastra hybrydowego. Ta funkcja używa protokołu plotek platformy Apache Cassandra do replikacji danych ze źródłowego centrum danych do nowego centrum danych wystąpienia zarządzanego w bezproblemowy sposób. Mogą jednak wystąpić pewne scenariusze, w których źródłowa wersja bazy danych nie jest zgodna lub konfiguracja klastra hybrydowego nie jest możliwa.
W tym samouczku opisano sposób migrowania danych do usługi Azure Managed Instance for Apache Cassandra w sposób dynamiczny przy użyciu serwera proxy z podwójnym zapisem i platformy Apache Spark. Serwer proxy z podwójnym zapisem służy do przechwytywania zmian na żywo, podczas gdy dane historyczne są kopiowane zbiorczo przy użyciu platformy Apache Spark. Korzyści wynikające z tego podejścia są następujące:
- Minimalne zmiany aplikacji. Serwer proxy może akceptować połączenia z kodu aplikacji z kilkoma zmianami konfiguracji. Spowoduje to kierowanie wszystkich żądań do źródłowej bazy danych i asynchroniczne kierowanie zapisów do pomocniczego obiektu docelowego.
- Zależność protokołu przewodowego klienta. Ponieważ takie podejście nie jest zależne od zasobów zaplecza ani protokołów wewnętrznych, może być używane z dowolnym źródłowym lub docelowym systemem Cassandra, który implementuje protokół przewodowy Apache Cassandra.
Na poniższej ilustracji przedstawiono podejście.
Wymagania wstępne
Aprowizuj wystąpienie zarządzane platformy Azure dla klastra Apache Cassandra przy użyciu witryny Azure Portal lub interfejsu wiersza polecenia platformy Azure. Upewnij się, że możesz nawiązać połączenie z klastrem za pomocą protokołu CQLSH.
Aprowizuj konto usługi Azure Databricks w zarządzanej sieci wirtualnej Cassandra. Upewnij się, że konto ma dostęp sieciowy do źródłowego klastra Cassandra. Utworzymy klaster Spark na tym koncie na potrzeby ładowania danych historycznych.
Upewnij się, że przeprowadzono już migrację schematu przestrzeni kluczy/tabeli ze źródłowej bazy danych Cassandra do docelowej bazy danych wystąpienia zarządzanego Cassandra.
Aprowizuj klaster Spark
Zalecamy wybranie środowiska uruchomieniowego usługi Azure Databricks w wersji 7.5, która obsługuje platformę Spark 3.0.
Dodawanie zależności platformy Spark
Musisz dodać bibliotekę łącznika Apache Spark Cassandra Connector do klastra, aby nawiązać połączenie z dowolnymi punktami końcowymi apache Cassandra zgodnymi z protokołem przewodowym. W klastrze wybierz pozycję Biblioteki>Zainstaluj nowe>narzędzie Maven, a następnie dodaj com.datastax.spark:spark-cassandra-connector-assembly_2.12:3.0.0
współrzędne narzędzia Maven.
Ważne
Jeśli wymagana jest ochrona bazy danych Apache Cassandra writetime
dla każdego wiersza podczas migracji, zalecamy użycie tego przykładu. Plik jar zależności w tym przykładzie zawiera również łącznik Spark, dlatego należy zainstalować go zamiast zestawu łącznika powyżej. Ten przykład jest również przydatny, jeśli chcesz przeprowadzić walidację porównania wierszy między źródłem i obiektem docelowym po zakończeniu ładowania danych historycznych. Zobacz sekcje "uruchamianie ładowania danych historycznych" i "weryfikowanie źródła i celu" poniżej, aby uzyskać więcej informacji.
Wybierz pozycję Zainstaluj, a następnie uruchom ponownie klaster po zakończeniu instalacji.
Uwaga
Pamiętaj, aby ponownie uruchomić klaster usługi Azure Databricks po zainstalowaniu biblioteki łącznika Cassandra.
Instalowanie serwera proxy z podwójnym zapisem
Aby uzyskać optymalną wydajność podczas podwójnych zapisów, zalecamy zainstalowanie serwera proxy we wszystkich węzłach w źródłowym klastrze Cassandra.
#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
Uruchamianie serwera proxy z podwójnym zapisem
Zalecamy zainstalowanie serwera proxy na wszystkich węzłach w źródłowym klastrze Cassandra. Uruchom co najmniej następujące polecenie, aby uruchomić serwer proxy w każdym węźle. Zastąp <target-server>
ciąg adresem IP lub adresem serwera z jednego z węzłów w klastrze docelowym. Zastąp ciąg ścieżką do lokalnego pliku jks i zastąp <path to JKS file>
<keystore password>
ciąg odpowiednim hasłem.
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>
Uruchomienie serwera proxy w ten sposób zakłada, że spełnione są następujące warunki:
- Źródłowe i docelowe punkty końcowe mają taką samą nazwę użytkownika i hasło.
- Źródłowe i docelowe punkty końcowe implementują protokół SECURE Sockets Layer (SSL).
Jeśli źródłowe i docelowe punkty końcowe nie mogą spełnić tych kryteriów, zapoznaj się z tematem dalsze opcje konfiguracji.
Konfigurowanie protokołu SSL
W przypadku protokołu SSL można zaimplementować istniejący magazyn kluczy (na przykład używany przez klaster źródłowy) lub utworzyć certyfikat z podpisem własnym przy użyciu polecenia keytool
:
keytool -genkey -keyalg RSA -alias selfsigned -keystore keystore.jks -storepass password -validity 360 -keysize 2048
Możesz również wyłączyć protokół SSL dla źródłowych lub docelowych punktów końcowych, jeśli nie implementują protokołu SSL. --disable-source-tls
Użyj flag lub--disable-target-tls
:
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
Uwaga
Podczas tworzenia połączeń SSL z bazą danych za pośrednictwem serwera proxy upewnij się, że aplikacja kliencka używa tego samego magazynu kluczy i hasła, co dla serwera proxy.
Konfigurowanie poświadczeń i portów
Domyślnie poświadczenia źródłowe będą przekazywane z aplikacji klienckiej. Serwer proxy będzie używać poświadczeń do nawiązywania połączeń z klastrami źródłowymi i docelowymi. Jak wspomniano wcześniej, ten proces zakłada, że poświadczenia źródłowe i docelowe są takie same. W razie potrzeby możesz oddzielnie określić inną nazwę użytkownika i hasło dla docelowego punktu końcowego cassandra podczas uruchamiania serwera proxy:
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>
Domyślne porty źródłowe i docelowe, jeśli nie zostaną określone, będą mieć wartość 9042. Jeśli docelowy lub źródłowy punkt końcowy Cassandra działa na innym porcie, możesz użyć --source-port
polecenia lub --target-port
określić inny numer portu:
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>
Zdalne wdrażanie serwera proxy
Mogą wystąpić okoliczności, w których nie chcesz instalować serwera proxy na samych węzłach klastra i wolisz zainstalować go na osobnej maszynie. W tym scenariuszu należy określić adres IP :<source-server>
java -jar target/cassandra-proxy-1.0-SNAPSHOT-fat.jar <source-server> <destination-server>
Ostrzeżenie
Jeśli wolisz uruchomić serwer proxy zdalnie na oddzielnej maszynie (zamiast uruchamiać go na wszystkich węzłach w źródłowym klastrze Apache Cassandra), zalecamy wdrożenie serwera proxy na tej samej liczbie maszyn, na których znajdują się węzły w klastrze, i skonfigurowanie podstawiania ich adresów IP w systemie.peers przy użyciu konfiguracji serwera proxy wymienionego tutaj. Jeśli tego nie zrobisz, może to mieć wpływ na wydajność podczas migracji na żywo, ponieważ sterownik klienta nie będzie mógł otwierać połączeń ze wszystkimi węzłami w klastrze.
Zezwalaj na zerowe zmiany kodu aplikacji
Domyślnie serwer proxy nasłuchuje na porcie 29042. Kod aplikacji należy zmienić tak, aby wskazywał ten port. Można jednak zmienić port, na którym nasłuchuje serwer proxy. Możesz to zrobić, jeśli chcesz wyeliminować zmiany kodu na poziomie aplikacji przez:
- Po uruchomieniu źródłowego serwera Cassandra na innym porcie.
- Uruchomienie serwera proxy na standardowym porcie Cassandra 9042.
java -jar target/cassandra-proxy-1.0-SNAPSHOT-fat.jar source-server destination-server --proxy-port 9042
Uwaga
Instalowanie serwera proxy w węzłach klastra nie wymaga ponownego uruchomienia węzłów. Jeśli jednak masz wielu klientów aplikacji i wolisz mieć serwer proxy uruchomiony na standardowym porcie Cassandra 9042, aby wyeliminować wszelkie zmiany kodu na poziomie aplikacji, musisz zmienić domyślny port apache Cassandra. Następnie należy ponownie uruchomić węzły w klastrze i skonfigurować port źródłowy jako nowy port zdefiniowany dla źródłowego klastra Cassandra.
W poniższym przykładzie zmienimy źródłowy klaster Cassandra na uruchomiony na porcie 3074 i uruchomimy klaster na porcie 9042:
java -jar target/cassandra-proxy-1.0-SNAPSHOT-fat.jar source-server destination-server --proxy-port 9042 --source-port 3074
Wymuszanie protokołów
Serwer proxy ma funkcje wymuszania protokołów, które mogą być konieczne, jeśli źródłowy punkt końcowy jest bardziej zaawansowany niż docelowy lub w inny sposób nie jest obsługiwany. W takim przypadku można określić --protocol-version
i --cql-version
wymusić, aby protokół był zgodny z celem:
java -jar target/cassandra-proxy-1.0-SNAPSHOT-fat.jar source-server destination-server --protocol-version 4 --cql-version 3.11
Po uruchomieniu serwera proxy z podwójnym zapisem należy zmienić port na kliencie aplikacji i uruchomić go ponownie. (Lub zmień port Cassandra i uruchom ponownie klaster, jeśli wybrano to podejście). Następnie serwer proxy rozpocznie przekazywanie zapisów do docelowego punktu końcowego. Informacje o monitorowaniu i metrykach dostępnych w narzędziu serwera proxy.
Uruchamianie ładowania danych historycznych
Aby załadować dane, utwórz notes Języka Scala na koncie usługi Azure Databricks. Zastąp źródłowe i docelowe konfiguracje bazy danych Cassandra odpowiednimi poświadczeniami, a następnie zastąp źródłowe i docelowe przestrzenie kluczy i tabele. Dodaj więcej zmiennych dla każdej tabeli zgodnie z wymaganiami do poniższego przykładu, a następnie uruchom polecenie . Gdy aplikacja zacznie wysyłać żądania do serwera proxy z podwójnym zapisem, możesz przystąpić do migracji danych historycznych.
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
Uwaga
W poprzednim przykładzie Scala zauważysz, że timestamp
jest ustawiana na bieżący czas przed odczytaniem wszystkich danych w tabeli źródłowej. writetime
Następnie jest ustawiana na tę sygnaturę czasową wsteczną. Gwarantuje to, że rekordy zapisywane z ładowania danych historycznych do docelowego punktu końcowego nie mogą zastąpić aktualizacji, które pochodzą z późniejszego sygnatury czasowej z serwera proxy z podwójnym zapisem, podczas gdy dane historyczne są odczytywane.
Ważne
Jeśli musisz zachować dokładne sygnatury czasowe z jakiegokolwiek powodu, należy podjąć podejście do migracji danych historycznych, które zachowuje sygnatury czasowe, takie jak ten przykład. Plik jar zależności w przykładzie zawiera również łącznik Spark, więc nie trzeba instalować zestawu łącznika Spark wymienionego we wcześniejszych wymaganiach wstępnych — po zainstalowaniu obu w klastrze Spark wystąpią konflikty.
Weryfikowanie źródła i miejsca docelowego
Po zakończeniu ładowania danych historycznych bazy danych powinny być zsynchronizowane i gotowe do migracji jednorazowej. Zalecamy jednak zweryfikowanie źródła i celu, aby upewnić się, że są one zgodne przed zakończeniem cięcia.
Uwaga
Jeśli użyto przykładu cassandra migrator wymienionego powyżej w celu zachowania writetime
wartości , obejmuje to możliwość weryfikacji migracji przez porównanie wierszy w źródle i obiekcie docelowym na podstawie pewnych tolerancji.