Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
По возможности рекомендуется использовать собственную возможность Apache Cassandra для переноса данных из существующего кластера в Управляемый экземпляр Azure для Apache Cassandra, настроив гибридный кластер. Эта возможность использует протокол Apache Cassandra для непрерывной репликации данных из исходного центра обработки данных в новый управляемый экземпляр.
Могут быть сценарии, в которых версия вашей исходной базы данных несовместима, или настройка гибридного кластера по другим причинам нецелесообразна. В этом учебнике описывается, как перенести данные в Управляемый экземпляр Azure для Apache Cassandra в реальном времени с помощью прокси-сервера двойной записи и Apache Spark. Прокси-сервер с двойной записью используется для записи изменений, происходящих в реальном времени, а исторические данные массово копируются помощью Apache Spark. Преимущества этого подхода
- Минимальные изменения приложения. Прокси-сервер может принимать подключения из кода приложения с минимальными изменениями конфигурации или без них. Он направляет все запросы в исходную базу данных и асинхронно направляет запись в дополнительный целевой объект.
- Зависимость от протокола проводного соединения клиента. Так как этот подход не зависит от внутренних ресурсов или внутренних протоколов, его можно использовать с любой исходной или целевой системой Cassandra, реализующей протокол провода Apache Cassandra.
На приведенном ниже рисунке представлен этот подход.
Необходимые компоненты
Подготовьте кластер Управляемого экземпляра Azure для Apache Cassandra с помощью портала Azure или интерфейса командной строки Azure. Убедитесь, что вы можете подключиться к кластеру с помощью CQLSH.
Подготовьте учетную запись Azure Databricks в управляемой виртуальной сети Cassandra. Убедитесь, что у учетной записи есть сетевой доступ к исходному кластеру Cassandra. В этом примере создается кластер Spark в этой учетной записи для загрузки исторических данных.
Убедитесь, что вы уже перенесли схему пространства ключей или таблицы из исходной базы данных Cassandra в целевую базу данных управляемого экземпляра Cassandra.
Подготовка кластера Spark
Рекомендуется выбрать среду выполнения Azure Databricks версии 7.5, которая поддерживает Spark 3.0.
Добавление зависимостей Spark
Необходимо добавить библиотеку соединителя Apache Spark Cassandra в кластер, чтобы подключиться к любым конечным точкам, совместимым с протоколом Apache Cassandra. В кластере выберите Библиотеки>Установить>Maven, а затем добавьте com.datastax.spark:spark-cassandra-connector-assembly_2.12:3.0.0
в координаты Maven.
Внимание
Если во время миграции вам необходимо сохранить writetime
Apache Cassandra для каждой строки, рекомендуем использовать этот пример. Jar-файл зависимостей в этом примере также содержит соединитель Spark, поэтому установите эту версию вместо сборки соединителя.
Этот пример также пригодится, если вы хотите выполнить проверку со сравнением строк между исходным и целевым объектами после завершения загрузки исторических данных. См. статью "Запуск исторической загрузки данных " и "Проверка источника и целевого объекта".
Нажмите кнопку Установить, а затем перезапустите кластер после завершения установки.
Примечание.
Не забудьте перезапустить кластер Azure Databricks после установки библиотеки соединителя Cassandra.
Установка прокси-сервера двойной записи
Для оптимальной производительности во время двойной записи рекомендуется установить прокси-сервер на всех узлах в исходном кластере 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
Запуск прокси-сервера двойной записи
Рекомендуем установить прокси-сервер на всех узлах в исходном кластере Cassandra. Для запуска прокси-сервера на каждом узле необходимо как минимум выполнить приведенную ниже команду. Замените <target-server>
на IP-адрес или адрес сервера одного из узлов в целевом кластере. Замените <path to JKS file>
путь к локальному файлу jks и замените <keystore password>
соответствующим паролем.
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>
Запуск прокси-сервера таким способом предполагает соблюдение следующих условий:
- исходная и целевая конечные точки используют одни и те же имя пользователя и пароль;
- в исходной и целевой конечных точках реализована поддержка протокола SSL.
Если ваши исходная и целевая конечные точки не отвечают этим условиям, ознакомьтесь с описанными ниже параметрами конфигурации.
Настройка SSL
Для SSL можно реализовать существующее хранилище ключей, например используемое в исходном кластере, или создать самозаверяющий сертификат с помощью keytool
:
keytool -genkey -keyalg RSA -alias selfsigned -keystore keystore.jks -storepass password -validity 360 -keysize 2048
Вы также можете отключить SSL для исходной или целевой конечной точки, если для них не используется SSL. Используйте флаг --disable-source-tls
или --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
Примечание.
Убедитесь, что клиентское приложение использует то же хранилище ключей и пароль, что и те, которые используются для прокси-сервера двойной записи при сборке SSL-подключений к базе данных, использующую прокси-сервер.
Настройка учетных данных и порта
По умолчанию исходные учетные данные передаются из клиентского приложения. Прокси-сервер использует учетные данные для подключения к исходным и целевым кластерам. Как упоминалось ранее, в этом процессе предполагается, что исходные и целевые учетные данные совпадают. При необходимости можно отдельно указать другие имя пользователя и пароль целевой конечной точки Cassandra при запуске прокси-сервера.
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>
Исходные и целевые порты по умолчанию, если они не указаны, — 9042. Если целевая или исходная конечные точки Cassandra запущены на другом порту, можно использовать --source-port
или --target-port
, чтобы указать другой номер порта.
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>
Удаленное развертывание прокси-сервера
Могут возникнуть обстоятельства, в которых вы не хотите устанавливать прокси-сервер на самих узлах кластера. Вы хотите установить его на отдельном компьютере. В этом сценарии укажите IP-адрес <source-server>
:
java -jar target/cassandra-proxy-1.0-SNAPSHOT-fat.jar <source-server> <destination-server>
Предупреждение
Возможно, вы хотите удаленно запустить прокси-сервер на отдельном компьютере, а не запускать его на всех узлах в исходном кластере Apache Cassandra. В этом случае рекомендуется развернуть прокси-сервер на том же количестве компьютеров, что и узлы в кластере. Настройте подстановку их IP-адресов в system.peers. Используйте эту конфигурацию в прокси-сервере. Если этот подход не используется, это может повлиять на производительность во время динамической миграции, так как драйвер клиента не может открывать подключения ко всем узлам в кластере.
Предотвращение изменения кода приложения
По умолчанию прокси-сервер прослушивает порт 29042. Чтобы указать этот порт, необходимо изменить код приложения. Кроме того, можно изменить порт, который используется для прослушивания прокси-сервером. Этот подход можно использовать, если вы хотите исключить изменения кода на уровне приложения, выполнив следующие действия.
- запустить исходный сервер Cassandra на другом порту;
- запустить прокси-сервер на стандартом для Cassandra порту 9042.
java -jar target/cassandra-proxy-1.0-SNAPSHOT-fat.jar source-server destination-server --proxy-port 9042
Примечание.
Установка прокси-сервера на узлах кластера не требует перезапуска узлов. Если у вас много клиентов приложений и вы предпочитаете запускать прокси-сервер на стандартном порту Cassandra 9042, чтобы устранить любые изменения кода на уровне приложения, измените порт по умолчанию Apache Cassandra. Затем необходимо перезапустить узлы в кластере и настроить исходный порт в качестве нового порта, определенного в исходном кластере Cassandra.
В следующем примере мы переведем исходный кластер Cassandra на порт 3074 и запустим кластер на порту 9042:
java -jar target/cassandra-proxy-1.0-SNAPSHOT-fat.jar source-server destination-server --proxy-port 9042 --source-port 3074
Принудительное применение протоколов
Прокси-сервер поддерживает принудительное применение протоколов, которое может потребоваться, если исходная конечная точка сложнее целевой или не поддерживается по другой причине. В таком случае вы можете указать параметры --protocol-version
и --cql-version
, чтобы принудительно сопоставить протокол с целевым объектом:
java -jar target/cassandra-proxy-1.0-SNAPSHOT-fat.jar source-server destination-server --protocol-version 4 --cql-version 3.11
После запуска прокси-сервера двойной записи измените порт на клиенте приложения и перезапустите его. Или измените порт Cassandra и перезапустите кластер, если вы выбрали этот подход. Прокси-сервер начинает переадресацию записи в целевую конечную точку. Вы можете узнать о мониторинге и метриках, доступных в средстве прокси-сервера.
Запуск нагрузки исторических данных
Чтобы загрузить данные, создайте записную книжку Scala в учетной записи Azure Databricks. Замените исходные и целевые конфигурации Cassandra соответствующими учетными данными, а также замените исходные и целевые пространства ключей и таблицы. Добавьте дополнительные переменные для каждой таблицы, как указано в приведенном ниже примере, а затем выполните команду. После того как приложение начнет отправлять запросы на прокси-сервер двойной записи, можно приступать к переносу исторических данных.
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
Примечание.
В предыдущем примере на Scala, текущее время устанавливается как timestamp
перед чтением всех данных в исходной таблице. Затем в качестве writetime
устанавливается эта метка прошедшего времени. Этот подход гарантирует, что записи, загружаемые из исторических данных в целевую конечную точку, не могут перезаписать обновления с более поздней временной меткой, поступающие через прокси-сервер двойной записи во время чтения исторических данных.
Внимание
Если по какой-либо причине требуется сохранить точные метки времени, следует применить подход с переносом исторических данных, при котором сохраняются метки времени, например этот пример. Jar-файл зависимостей в примере также содержит соединитель Spark, поэтому не нужно устанавливать сборку соединителя Spark, упомянутую в предыдущих предварительных требованиях. При установке обоих компонентов в кластере Spark возникают конфликты.
Проверка исходного и целевого объектов
По завершении загрузки исторических данных ваши базы данных должны быть синхронизированы и готовы к прямому переносу. Рекомендуется проверить источник и целевой объект, чтобы убедиться, что они совпадают, прежде чем окончательно сократить.
Примечание.
Если вы использовали пример миграции Cassandra , упомянутый в предыдущих разделах для сохранения writetime
, вы можете проверить миграцию путем сравнения строк в источнике и целевом объекте на основе определенных допустимых значений.