Миграция данных между кластерами Managed Kafka
Вы можете перенести данные из исходного кластера Managed Kafka в целевой с помощью инструмента Apache Kafka MirrorMaker 2 (MM2). Исходный кластер остается доступен для записи во время миграции.
Чтобы мигрировать данные:
Если вам больше не нужны созданные ресурсы, удалите их.
Перед началом работы
Заголовок раздела «Перед началом работы»Создайте пользователя в исходном кластере для чтения данных, а в целевом — для записи.
Создайте сервисный аккаунт
sa-kafka-mm2с рольюmkafka.editor. Аккаунт понадобится для создания топиков в целевом кластере.Создайте виртуальную машину в той же сети, где расположены оба кластера. При создании ВМ привяжите к ней сервисный аккаунт
sa-kafka-mm2. В зависимости от количества переносимых разделов и интенсивности потока данных выберите конфигурацию ВМ:Параметр Минимальная конфигурация Рекомендуемая конфигурация vCPU 2 от 4 RAM 4 ГБ от 8 ГБ Диск 10 ГБ от 20 ГБ, с запасом под логи Подготовьте данные для подключений:
- адреса брокеров исходного и целевого кластеров;
- имена и пароли пользователей исходного и целевого кластеров;
- имя проекта;
- IP-адрес ВМ.
1. Подготовьте ВМ
Заголовок раздела «1. Подготовьте ВМ»Установите необходимые пакеты:
bash sudo apt update && \sudo apt install -y \curl \wget \tar \gzip \ca-certificates \netcat-openbsd \dnsutils \jqУстановите Java 17:
bash sudo apt install -y openjdk-17-jre-headlessПроверьте успешность установки:
bash java -versionСоздайте системного пользователя
kafka-mm2и каталоги для него:bash sudo useradd \--system \--home /opt/kafka \--shell /usr/sbin/nologin \kafka-mm2 && \sudo mkdir -p /opt/kafka && \sudo mkdir -p /etc/kafka-mm2 && \sudo mkdir -p /opt/kafka-mm2/scriptsУстановите Apache Kafka версии не ниже, чем в кластере:
bash cd /tmp && \wget https://downloads.apache.org/kafka/4.1.2/kafka_2.13-4.1.2.tgz && \tar -xzf kafka_2.13-4.1.2.tgz && \sudo mv kafka_2.13-4.1.2 /opt/kafka/ && \sudo ln -s /opt/kafka/kafka_2.13-4.1.2 /opt/kafka/current && \sudo chown -R kafka-mm2:kafka-mm2 /opt/kafkaПроверьте успешность установки:
bash ls -l /opt/kafka/current/bin/connect-mirror-maker.sh && \ls -l /opt/kafka/current/bin/kafka-topics.shУстановите корневой сертификат MWS — он понадобится для TLS-подключения к кластерам:
bash cd /tmp && \wget https://pki.mws.ru/certs/mws-root-ca.crt && \sudo mv /tmp/mws-root-ca.crt /etc/kafka-mm2/mws-root-ca.crt && \sudo chown kafka-mm2:kafka-mm2 /etc/kafka-mm2/mws-root-ca.crt && \sudo chmod 644 /etc/kafka-mm2/mws-root-ca.crtПроверьте доступность кластеров с ВМ. Порт подключения из внутренней сети —
9095:bash nc -vz <адрес брокера исходного кластера> 9095 && \nc -vz <адрес брокера целевого кластера> 9095Ожидаемый результат: обе команды завершаются сообщением
succeeded.
2. Настройте подключение к кластерам
Заголовок раздела «2. Настройте подключение к кластерам»Файлы конфигурации содержат параметры подключения к кластеру: аутентификацию SASL_SSL с механизмом SCRAM-SHA-256 и корневой сертификат MWS.
Создайте файл
/etc/kafka-mm2/source-client.propertiesсо следующим содержимым:properties security.protocol=SASL_SSLsasl.mechanism=SCRAM-SHA-256ssl.truststore.type=PEMssl.truststore.location=/etc/kafka-mm2/mws-root-ca.crtsasl.jaas.config=org.apache.kafka.common.security.scram.ScramLoginModule required username="<имя пользователя исходного кластера>" password="<пароль>";ssl.endpoint.identification.algorithm=Создайте файл
/etc/kafka-mm2/target-client.propertiesсо следующим содержимым:properties security.protocol=SASL_SSLsasl.mechanism=SCRAM-SHA-256ssl.truststore.type=PEMssl.truststore.location=/etc/kafka-mm2/mws-root-ca.crtsasl.jaas.config=org.apache.kafka.common.security.scram.ScramLoginModule required username="<имя пользователя целевого кластера>" password="<пароль>";ssl.endpoint.identification.algorithm=Задайте права на файлы конфигурации:
bash sudo chown kafka-mm2:kafka-mm2 \/etc/kafka-mm2/source-client.properties \/etc/kafka-mm2/target-client.properties && \sudo chmod 600 \/etc/kafka-mm2/source-client.properties \/etc/kafka-mm2/target-client.propertiesПроверьте подключение к исходному кластеру:
bash sudo -u kafka-mm2 \/opt/kafka/current/bin/kafka-topics.sh \--bootstrap-server <адрес брокера исходного кластера> \--command-config /etc/kafka-mm2/source-client.properties \--listОжидаемый результат: список топиков исходного кластера.
Проверьте подключение к целевому кластеру:
bash sudo -u kafka-mm2 \/opt/kafka/current/bin/kafka-topics.sh \--bootstrap-server <адрес брокера целевого кластера> \--command-config /etc/kafka-mm2/target-client.properties \--listОжидаемый результат: список топиков целевого кластера.
3. Проверьте доступ до Managed Kafka API
Заголовок раздела «3. Проверьте доступ до Managed Kafka API»Топики целевого кластера создаются через API Managed Kafka. Чтобы выполнить запросы, получите IAM-токен сервисного аккаунта sa-kafka-mm2 и проверьте доступ к API с помощью этого токена:
Убедитесь, что привязка сервисного аккаунта к ВМ завершена. Привязка может занять несколько минут:
bash curl -s \-H "Metadata-Flavor: Google" \http://169.254.169.254/computeMetadata/v1/instance/service-accounts/?recursive=true \| jqОжидаемый вывод:
json {"<имя проекта>/serviceAccounts/sa-kafka-mm2": {"aliases": ["default"]}}Получите IAM-токен сервисного аккаунта:
bash TOKEN="$(curl -s \-H "Metadata-Flavor: Google" \http://169.254.169.254/computeMetadata/v1/instance/service-accounts/default/token \| jq -r '.access_token')"MWS автоматически обновляет токен в метаданных ВМ.
Задайте имя проекта и получите список кластеров:
bash export MWS_PROJECT='<имя проекта>' && \curl -sS \-H "Authorization: Bearer ${TOKEN}" \"https://mkafka.mwsapis.ru/mkafka/v1/projects/${MWS_PROJECT}/clusters" \| jq -r '.items[] |[(.metadata.id | split("/") | last),.metadata.displayName] | @tsv'Пример вывода:
text cluster-source-b Source Kafkacluster-target-b Target KafkaЗадайте переменную с техническим именем целевого кластера:
bash export MWS_TARGET_CLUSTER='<техническое имя целевого кластера>'В примере техническое имя кластера —
cluster-target-b, а неTarget Kafka(отображаемое имя).API Managed Kafka использует техническое имя кластера — последний сегмент из
metadata.id. Если в запросе передать отображаемое имя, API вернет ошибкуINVALID_ARGUMENT.Проверьте доступ к API Managed Kafka:
bash curl -sS \-H "Authorization: Bearer ${TOKEN}" \"https://mkafka.mwsapis.ru/mkafka/v1/projects/${MWS_PROJECT}/clusters/${MWS_TARGET_CLUSTER}/topics" \| jqОжидаемый результат: JSON-описание топиков целевого кластера.
4. Создайте топики в целевом кластере
Заголовок раздела «4. Создайте топики в целевом кластере»MirrorMaker 2 в процессе работы попытается создать недостающие топики через Kafka Admin API. Пользователь кластера не имеет прав на создание топиков, поэтому такая операция завершится ошибкой TopicAuthorizationException.
Чтобы избежать этой ошибки, подготовьте топики целевого кластера одним из способов:
- Скриптом
- Через API
Скрипт sync-topics.sh создает в целевом кластере пользовательские топики исходного кластера, а также внутренние топики MM2, необходимые для миграции.
Используйте этот способ, чтобы перенести большое количество топиков.
Создайте на ВМ файл
/opt/kafka-mm2/scripts/sync-topics.shи вставьте в него содержимое скрипта:Назначьте права на скрипт:
bash sudo chown kafka-mm2:kafka-mm2 \/opt/kafka-mm2/scripts/sync-topics.sh && \sudo chmod 750 \/opt/kafka-mm2/scripts/sync-topics.shВыполните предварительную синхронизацию топиков:
bash sudo -u kafka-mm2 env \MWS_PROJECT='<имя проекта>' \MWS_TARGET_CLUSTER='<техническое имя целевого кластера>' \SOURCE_BOOTSTRAP_SERVERS='<адрес брокера исходного кластера>' \/opt/kafka-mm2/scripts/sync-topics.shОжидаемый результат: скрипт создает топики и завершается сообщением
Topic synchronization completed.Проверьте топики целевого кластера:
bash sudo -u kafka-mm2 \/opt/kafka/current/bin/kafka-topics.sh \--bootstrap-server <адрес брокера целевого кластера> \--command-config /etc/kafka-mm2/target-client.properties \--listОжидаемый результат: список содержит все пользовательские топики исходного кластера.
(опционально) Если во время миграции в исходном кластере появляются новые топики, запустите скрипт в режиме наблюдения. Скрипт будет периодически проверять исходный кластер и создавать новые топики в целевом:
bash sudo -u kafka-mm2 env \MWS_PROJECT='<имя проекта>' \MWS_TARGET_CLUSTER='<техническое имя целевого кластера>' \SOURCE_BOOTSTRAP_SERVERS='<адрес брокера исходного кластера>' \WATCH_INTERVAL_SECONDS=30 \/opt/kafka-mm2/scripts/sync-topics.sh
5. Создайте конфигурацию MirrorMaker 2
Заголовок раздела «5. Создайте конфигурацию MirrorMaker 2»Создайте файл
/etc/kafka-mm2/connect-mirror-maker.propertiesсо следующим содержимым:Значение
.*для параметраsource->target.topicsвключает все топики исходного кластера, аsource->target.topics.excludeзадает исключения и имеет приоритет над include-фильтром.Задайте права на файл конфигурации:
bash sudo chown kafka-mm2:kafka-mm2 \/etc/kafka-mm2/connect-mirror-maker.properties && \sudo chmod 600 \/etc/kafka-mm2/connect-mirror-maker.properties
В этой конфигурации заданы следующие ключевые решения:
| Параметр | Значение | Причина |
|---|---|---|
replication.policy.class | IdentityReplicationPolicy | Имена топиков переносятся без префикса исходного кластера |
source->target.emit.heartbeats.enabled | false | Для миграции heartbeat-топики не нужны |
source->target.sync.topic.configs.enabled | false | Топики целевого кластера создаются через API Managed Kafka |
replication.factor | 1 | В примере кластер состоит из одного брокера |
source->target.tasks.max | 4 | Количество параллельных задач репликации |
6. Проверьте направление репликации
Заголовок раздела «6. Проверьте направление репликации»Перед первым запуском репликации убедитесь, что адреса брокеров не перепутаны: данные должны идти из исходного кластера в целевой, а обратная репликация отключена.
Выполните команду:
bash grep -nE \'^(clusters|source\.bootstrap\.servers|target\.bootstrap\.servers|source->target\.enabled|target->source\.enabled)' \/etc/kafka-mm2/connect-mirror-maker.propertiesОжидаемый результат:
text clusters = source, targetsource.bootstrap.servers = <адрес брокера исходного кластера>target.bootstrap.servers = <адрес брокера целевого кластера>source->target.enabled = truetarget->source.enabled = false
7. Запустите MirrorMaker 2
Заголовок раздела «7. Запустите MirrorMaker 2»Запустите MirrorMaker 2:
bash sudo -u kafka-mm2 \env KAFKA_HEAP_OPTS="-Xms512m -Xmx1g" \/opt/kafka/current/bin/connect-mirror-maker.sh \/etc/kafka-mm2/connect-mirror-maker.properties \2>&1 | tee /tmp/mm2.logВ отдельном терминале проверьте работу процесса:
bash grep -E \'MirrorSourceTask|replicating|ERROR|WARN' \/tmp/mm2.logОжидаемый результат:
text MirrorSourceTaskreplicating 6 topic-partitions source->target:[orders-0, orders-1, orders-2, orders-3, orders-4, orders-5]
8. Проверьте репликацию
Заголовок раздела «8. Проверьте репликацию»Проверьте права записи в целевой кластер. Для этого отправьте тестовое сообщение:
bash echo '{"probe":"direct-target-write"}' | \sudo -u kafka-mm2 \/opt/kafka/current/bin/kafka-console-producer.sh \--bootstrap-server <адрес брокера целевого кластера> \--producer.config /etc/kafka-mm2/target-client.properties \--topic <имя топика>Прочитайте его:
bash sudo -u kafka-mm2 \/opt/kafka/current/bin/kafka-console-consumer.sh \--bootstrap-server <адрес брокера целевого кластера> \--consumer.config /etc/kafka-mm2/target-client.properties \--topic <имя топика> \--from-beginning \--max-messages 1Ожидаемый результат:
{"probe":"direct-target-write"}.Проверьте перенос сообщений из исходного кластера:
bash sudo -u kafka-mm2 \/opt/kafka/current/bin/kafka-console-consumer.sh \--bootstrap-server <адрес брокера целевого кластера> \--consumer.config /etc/kafka-mm2/target-client.properties \--topic <имя топика> \--from-beginning \--max-messages 5Ожидаемый результат: потребитель выводит сообщения, отправленные в исходный кластер.
Проверьте прогресс миграции. Количество сообщений определяется разницей между последним и первым смещением: сообщения старше срока хранения удаляются из топика, поэтому одного последнего смещения недостаточно.
Пример вывода скрипта подсчета:
text Topic: mm2.test.ordersSource: 1000000Target: 734521Lag: 265479Progress: 73.45%Остановите производителей в исходном кластере и дождитесь значения
Progress: 100.00%— это будет означать, что миграция успешно завершена.Пока производители отправляют сообщения, значение прогресса будет постоянно изменяться.
Типовые ошибки
Заголовок раздела «Типовые ошибки»SSL handshake: PKIX path building failed
Заголовок раздела «SSL handshake: PKIX path building failed»SSL handshake failed
PKIX path building failed
unable to find valid certification pathПроверьте, что существует файл сертификата MWS /etc/kafka-mm2/mws-root-ca.crt, а в файлах конфигурации MM2 указаны параметры ssl.truststore.type=PEM и ssl.truststore.location=/etc/kafka-mm2/mws-root-ca.crt.
SASL authentication failed
Заголовок раздела «SASL authentication failed»Проверьте параметры аутентификации в файле конфигурации MM2: security.protocol=SASL_SSL, sasl.mechanism=SCRAM-SHA-256 и учетные данные в sasl.jaas.config.
Could not look up partition metadata
Заголовок раздела «Could not look up partition metadata»ConnectException:
Could not look up partition metadata for topic'mm2-offsets.source.internal'MM2 попытался создать внутренний топик через Kafka Admin API. Чтобы устранить ошибку, создайте топики в целевом кластере.
TopicAuthorizationException при создании топика
Заголовок раздела «TopicAuthorizationException при создании топика»Could not create topic ...
TopicAuthorizationException:
Authorization failedСоздание топиков в Managed Kafka выполняется через API сервиса, а не через Kafka Admin API. Роль CLUSTER_ADMIN этого не меняет. Предварительно создайте топики в целевом кластере.
Could not create topic source.heartbeats
Заголовок раздела «Could not create topic source.heartbeats»Could not create topic source.heartbeatsОтключите репликацию heartbeat-топиков. Для этого используйте корректную конфигурацию.
INVALID_ARGUMENT listKafkaTopics.cluster
Заголовок раздела «INVALID_ARGUMENT listKafkaTopics.cluster»{ "code": "INVALID_ARGUMENT", "description": "listKafkaTopics.cluster has invalid value"}В запрос передано отображаемое имя кластера вместо технического. Используйте техническое имя кластера.
Нет данных в целевом кластере
Заголовок раздела «Нет данных в целевом кластере»Сначала проверьте имя топика. При IdentityReplicationPolicy имя топика не меняется: если в исходном кластере топик называется mm2.test.orders, то и в целевом он должен называться mm2.test.orders (но не orders).
Затем проверьте лог MirrorMaker 2:
grep -E \'MirrorSourceTask|replicating|ERROR|WARN' \/tmp/mm2.logУдалите платные ресурсы
Заголовок раздела «Удалите платные ресурсы»Ресурсы, созданные в руководстве, тарифицируются. Если вы больше не планируете использовать их:
- Удалите целевой кластер Managed Kafka, если вы проходили руководство на тестовых данных.