1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/Hu-Lyndon-streamsets-start-asset

В этом репозитории не указан файл с открытой лицензией (LICENSE). При использовании обратитесь к конкретному описанию проекта и его зависимостям в коде.
Клонировать/Скачать
12.Mysql_to_PostgresSQL.md 23 КБ
Копировать Редактировать Web IDE Исходные данные Просмотреть построчно История
Отправлено 09.06.2025 14:20 9a477ac

12. MySQL к PostgreSQL

Изначально я хотел протестировать синхронизацию данных из MySQL в PostgreSQL, но экспериментальная фаза потребовала некоторых усилий. Сначала я опишу мою тестовую среду, не судите строго, если вы дочитаете до конца.

Подготовка сервера

В 2017 году я приобрел сервер на платформе Alibaba Cloud ecs.t5-c1m2.large, для более подробной информации о конфигурации перейдите по ссылке. Основное использование — легкие нагрузки, благодаря 4 ГБ оперативной памяти и небольшому потреблению ресурсов при версии ядра 3.10, я решил немного поэкспериментировать.

Тестовая среда:

Проект Версия
Linux 3.10.0-862.11.6.el7.x86_64
Docker 19.03.2-rc1

Изображения:

REPOSITORY TAG SIZE
streamsets/datacollector 3.14.0 687MB
saibaster/pyspider 1.28 1.66GB
mysql 5.7.29 455MB
rabbitmq alpine 103MB
postgres 9.6.17-alpine 36.1MB

Так как у меня только один сервер, я выбрал изображения Alpine версии, чтобы сэкономить место.

Создание контейнеров

Так как у меня только один сервер, контейнеры будут управляться с помощью docker-compose, для этого достаточно использовать встроенный python2.7. Если вы не знаете, как установить, воспользуйтесь поиском в интернете, здесь подробно останавливаться не буду.Войдя в систему под учетной записью root, создайте путь /root/docker-space/, чтобы избежать проблем с потерей файлов ресурсов docker или k8s (это просто для хайпа, здесь не используется k8s).

mkdir /root/docker-space
mkdir /root/docker-space/pyspider
mkdir /root/docker-space/postgresql
mkdir /root/docker-space/sdc

Создание сети

Сначала создадим подсеть для контейнеров, чтобы избежать сложностей с сетью, все тестовые контейнеры будут созданы в этой подсети.

docker network create --driver=bridge --subnet=172.19.0.0/16 --gateway=172.19.0.1 pyspider

Создание контейнера pyspider

Так как в данном тестовом примере используется StreamSets для перемещения данных из MySQL в PostgreSQL, я решил использовать инструмент для парсинга данных, чтобы избежать проблем с созданием данных. Сначала создайте два конфигурационных файла в директории pyspider.

$ cd /root/docker-space/pyspider
$ ls
config.json  docker-compose.yaml
# docker-compose.yaml
version: "3.3"

services:
  rabbitmq:
    image: rabbitmq:alpine
    container_name: rabbitmq
    environment:
      RABBITMQ_DEFAULT_USER: "pyspider"
      RABBITMQ_DEFAULT_PASS: "pyspider"
    networks:
      - pyspider
    command: rabbitmq-server

  mysql:
    image: mysql:5.7.29
    container_name: mysql
    ports:
      - "3306:3306"
    environment:
      - MYSQL_ALLOW_EMPTY_PASSWORD=yes
      - MYSQL_ROOT_PASSWORD=password
      - MYSQL_ROOT_HOST=%
    networks:
      - pyspider

  phantomjs:
    image: saibaster/pyspider:1.28
    container_name: phantomjs
    networks:
      - pyspider
    volumes:
      - ./config.json:/opt/pyspider/config.json
    command: -c config.json phantomjs
    depends_on:
      - mysql
      - rabbitmq
    restart: unless-stopped
```  result:
    image: saibaster/pyspider:1.28
    container_name: result
    networks:
      - pyspider
    volumes:
      - ./config.json:/opt/pyspider/config.json
      - ./result/data:/opt/pyspider/data
    command: -c config.json result_worker
    depends_on:
      - mysql
      - rabbitmq
    restart: unless-stopped # Иногда мы получаем ошибку "connection refused", так как rabbitmq еще не завершил полную загрузку  processor:
    container_name: processor
    image: saibaster/pyspider:1.28
    networks:
      - pyspider
    volumes:
      - ./config.json:/opt/pyspider/config.json
    command: -c config.json processor
    depends_on:
      - mysql
      - rabbitmq
    restart: unless-stopped

  fetcher:
    image: saibaster/pyspider:1.28
    container_name: fetcher
    networks:
      - pyspider
    volumes:
      - ./config.json:/opt/pyspider/config.json
    command: -c config.json fetcher
    depends_on:
      - mysql
      - rabbitmq
    restart: unless-stopped

  scheduler:
    image: saibaster/pyspider:1.28
    container_name: scheduler
    networks:
      - pyspider
    volumes:
      - ./config.json:/opt/pyspider/config.json
    command: -c config.json scheduler
    depends_on:
      - mysql
      - rabbitmq
    restart: unless-stopped

  webui:
    image: saibaster/pyspider:1.28
    container_name: webui
    ports:
      - "5050:5000"
    networks:
      - pyspider
    volumes:
      - ./config.json:/opt/pyspider/config.json
    command: -c config.json webui
    depends_on:
      - mysql
      - rabbitmq
    restart: unless-stopped
```сети:
  pyspider:
    внешняя:
      имя: pyspider
  по умолчанию:
    драйвер: bridge
# config.json
{
  "taskdb": "mysql+taskdb://root:password@mysql:3306",
  "projectdb": "mysql+projectdb://root:password@mysql:3306",
  "resultdb": "mysql+resultdb://root:password@mysql:3306",
  "message_queue": "amqp://pyspider:pyspider@rabbitmq:5672/%2F",
  "phantomjs-proxy": "http://phantomjs:25555",

  "phantomjs": {
    "phantomjs-path": "phantomjs",
    "порт": 25555,
    "авто-перезапуск": true
  },
  
  "fetcher": {
    "xmlrpc": true,
    "xmlrpc-host": "fetcher",
    "xmlrpc-port": 24444
  },


  "webui": {
    "username": "username",
    "password": "password",
    "need-auth": false,
    "scheduler-rpc": "http://scheduler:23333",
    "fetcher-rpc": "http://fetcher:24444"
  }
}
```Затем можно использовать команду `docker-compose up` для запуска pyspider. После запуска, в другом окне используйте команду `docker ps` для мониторинга состояния всех контейнеров pyspider. В процессе запуска могут появляться сообщения об ошибках, и `docker-compose` будет пытаться перезапустить контейнеры, пока все они не будут в состоянии `up`.

```shell
$ docker ps
CONTAINER ID        IMAGE                      COMMAND                  CREATED             STATUS              PORTS                                                                NAMES
ded46411b3ac        saibaster/pyspider:1.28    "pyspider -c config..."   3 часа назад        Up 3 часа           5000/tcp, 22222/tcp, 23333/tcp, 24444/tcp, 25555/tcp                 scheduler
20e092a40ffd        saibaster/pyspider:1.28    "pyspider -c config..."   3 часа назад        Up 3 часа           5000/tcp, 22222/tcp, 23333/tcp, 24444/tcp, 25555/tcp                 processor
e9a0bf6a47a4        saibaster/pyspider:1.28    "pyspider -c config..."   3 часа назад        Up 3 часа           5000/tcp, 22222/tcp, 23333/tcp, 24444/tcp, 25555/tcp                 result
5b4e42616714        saibaster/pyspider:1.28    "pyspider -c config..."   3 часа назад        Up 3 часа           22222/tcp, 23333/tcp, 24444/tcp, 25555/tcp, 0.0.0.0:5050->5000/tcp   webui
c061994f3441        saibaster/pyspider:1.28    "pyspider -c config..."   3 часа назад        Up 3 часа           5000/tcp, 22222/tcp, 23333/tcp, 24444/tcp, 25555/tcp                 phantomjs
d01f1d287ec6        saibaster/pyspider:1.28    "pyspider -c config..."   3 часа назад        Up 3 часа           5000/tcp, 22222/tcp, 23333/tcp, 24444/tcp, 25555/tcp                 fetcher
b896b71abc5a        mysql:5.7.29               "docker-entrypoint..."   3 часа назад        Up 3 часа           0.0.0.0:3306->3306/tcp, 33060/tcp                                    mysql
c35877e37522        rabbitmq:alpine            "docker-entrypoint..."   3 часа назад        Up 3 часа           4369/tcp, 5671-5672/tcp, 25672/tcp                                   rabbitmq
``````Перейдите в консоль управления Alibaba Cloud и откройте порт 5050 для правил безопасности сервера ECS. После этого вы сможете использовать браузер для входа на страницу PySpider.```![image-20200422001952239](./image/image-20200422001952239.png)

Нажмите кнопку Create, Project Name заполните значением `test1`, а Start URL  адресом Mooc (потому что он надежен).

![image-20200422002218520](./image-20200422002218520.png)

Используйте код, сгенерированный по умолчанию в pyspider, пока не будете готовы его изменять. Если вас интересует это, вы можете изучить руководство по pyspider. Нажмите `Save`, затем перейдите на страницу `pyspider` в левой панели, вернитесь на главную страницу и нажмите на TODO под Status, чтобы изменить состояние на DEBUG. Затем нажмите кнопку RUN справа, и вы увидите, что по умолчанию скрипт уже выполнил парсинг Mooc.

![image-20200422002556392](./image/image--20200422002556392.png)

Нажмите кнопку RESULT или перейдите в базу данных MySQL, чтобы просмотреть данные.

Мы используем команду docker для входа в MySQL, чтобы извлечь структуру таблицы результатов.

```shell
$ docker exec -it mysql /bin/sh
$# mysql -u root -p
Введите пароль: 

Добро пожаловать в MySQL monitor. Команды заканчиваются символами ; или \g.
Ваш идентификатор подключения к MySQL  45
Версия сервера: 5.7.29 MySQL Community Server (GPL)

Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.

Oracle  зарегистрированный товарный знак Oracle Corporation и/или ее
связанных компаний. Другие названия могут быть товарными знаками их
соответствующих владельцев.

Введите 'help;' или '\h' для получения помощи. Введите '\c', чтобы очистить текущий ввод.
```mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| projectdb          |
| resultdb           |
| sys                |
| taskdb             |
+--------------------+
7 строк (0.00 сек)

mysql> use resultdb;
Чтение информации о таблицах для завершения названий таблиц и столбцов.
Вы можете отключить эту функцию для более быстрого запуска с помощью -AБаза данных изменена
```sql
mysql> show tables;
+--------------------+
| Tables_in_resultdb |
+--------------------+
| imooc              |
+--------------------+
1 строка (0.00 сек)
mysql> desc imooc;
+------------+---------------+------+-----+---------+-------+
| Field      | Type          | Null | Key | Default | Extra |
+------------+---------------+------+-----+---------+-------+
| taskid     | varchar(64)   | NO   | PRI | NULL    |       |
| url        | varchar(1024) | YES  |     | NULL    |       |
| result     | mediumblob    | YES  |     | NULL    |       |
| updatetime | double(16,4)  | YES  |     | NULL    |       |
+------------+---------------+------+-----+---------+-------+
4 строки (0.00 сек)
mysql> show create table imooc;
+-------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table                                                                                                                                                                                                               |
+-------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| imooc | CREATE TABLE `imooc` (
  `taskid` varchar(64) NOT NULL,
  `url` varchar(1024) DEFAULT NULL,
  `result` mediumblob,
  `updatetime` double(16,4) DEFAULT NULL,
  PRIMARY KEY (`taskid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
+-------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 строка (0.00 сек)

Создание контейнера PostgreSQL

docker run --name postgres -e POSTGRES_PASSWORD=etl123456 -p 5432:5432 --network pyspider -d postgres:9.6.17-alpine

С помощью данной команды мы создаем контейнер PostgreSQL. По умолчанию имя пользователя postgres, мы указали пароль etl123456 и указали сеть pyspider. Также мы открыли порт 5432 для доступа к контейнеру.

Аналогично, данную команду мы сохранили в файл README.md, который находится в директории /root/docker-space/postgresql, чтобы не забыть.

Создание структуры целевой таблицы с помощью Dbvis

image-20200422003422770

Создание контейнера SDC

SDC (StreamSets Data Collector), команда для создания контейнера находится в файле README.md, который находится в директории /root/docker-space/sdc, чтобы не забыть.

docker run --name sdc -d \
-v sdc-conf:/etc/sdc \
-v sdc-data:/data \
-v sdc-stagelibs:/opt/streamsets-datacollector-3.14.0/streamsets-libs \
-v sdc-resources:/resources \
-v sdc-user-libs:/opt/streamsets-datacollector-user-libs \
-v sdc-streamsets-libs-extras:/opt/streamsets-datacollector-3.14.0/streamsets-libs-extras \
-p 18630:18630 --network pyspider streamsets/datacollector dc -verbose

Далее приятное тестирование

Загрузка jdbcDriver

Хотя StreamSets имеет модуль streamsets-datacollector-jdbc-lib, он не содержит конкретных драйверов для определенных баз данных, поэтому нам нужно загрузить jar-файлы. Откройте браузер и перейдите на порт 18630 хост-машины. Необходимо добавить этот порт в правила доступа ECS.

image-20200422004314955


Я также загрузил jar-файл для Oracle. Для таких баз данных, как Oracle и Hive, которые требуют нескольких jar-файлов, загружайте все необходимые jar-файлы.

![image-20200422004656912](./image/image-20200422004656912.png)

Теперь мы можем перезапустить сервис и проверить, куда были загружены jar-файлы.

```shell
$ docker inspect sdc
...
            "Env": [
                "PATH=/opt/java/openjdk/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
                "JAVA_VERSION=jdk8u192-b12",
                "JAVA_HOME=/opt/java/openjdk",
                "JAVA_TOOL_OPTIONS=-XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap",
                "SDC_CONF=/etc/sdc",
                "SDC_DATA=/data",
                "SDC_DIST=/opt/streamsets-datacollector-3.14.0",
                "SDC_HOME=/opt/streamsets-datacollector-3.14.0",
                "SDC_LOG=/logs",
                "SDC_RESOURCES=/resources",
                "USER_LIBRARIES_DIR=/opt/streamsets-datacollector-user-libs",
                "STREAMSETS_LIBRARIES_EXTRA_DIR=/opt/streamsets-datacollector-3.14.0/streamsets-libs-extras"  ----- SDC-контейнер по умолчанию выставляет этот каталог через переменную окружения, поэтому мы также используем этот каталог при создании контейнера и монтируем его на хост-машине.
            ],
...

В серии из 11 статей мы создали том sdc-streamsets-libs-extras

Войдя в этот том с хост-машины, можно увидеть jar-файлы, которые мы только что загрузили. Это означает, что мы можем самостоятельно поместить jar-файлы в этот каталог.

/var/lib/docker/volumes/sdc-streamsets-libs-extras/_data/streamsets-datacollector-jdbc-lib/lib [root@iz2ze2bvmg4pzeb80fhp5nz lib]# ls mysql.jar ojdbc6.jar orai18n.jar postgresql.jar xdb.jar xmlparserv2.jar #### Создание конвейера в интерфейсе SDCВ этом разделе я опираюсь на методы настройки, описанные другими пользователями, и предоставляю ссылку на соответствующий пост.

Вот как я настроил конфигурацию, без лишних пояснений:

Настройки источников:

image-20200422005442435

image-20200422005638389

image-20200422005701090

image-20200422005723942

Настройки учетных записей для доступа к MySQL (пользователь и пароль):

image-20200422005844102

Настройки целевых объектов:

image-20200422010001337

image-20200422010108923

На последнем изображении отмечены настройки типа данных для полей типа BLOB по умолчанию в pyspider.

Настройки учетных записей для доступа к MySQL (пользователь и пароль):

image-20200422010250590

Наконец, нажмите кнопку "Start" для запуска синхронизации данных

image-20200422010416801

Проверка синхронизации данных:

image-20200422010536913

Проверил несколько раз, и в разделе истории можно подробно просмотреть, как SDC получает данные и записывает их в целевую таблицу, отслеживая смещение (offset).

image-20200422010802424

Эти данные, как правило, сохраняются в директории /data контейнера SDC, которую мы уже примонтировали к хост-системе:image-20200422010956388

Оставшиеся вопросы

  1. Когда все данные из источников полностью синхронизированы, задача не завершается. Какие дальнейшие действия предпринимаются? Занимает ли соединение с базой данных? Как завершить задачу? Или это зависит от типа задачи или параметров?
  2. Как SDC работает вместе с StreamSets Control Hub для обеспечения отказоустойчивости (HA)?
  3. По предварительным оценкам, SDC, будь то в режиме standalone, кластера или многопоточном режиме, является решением для работы с большими данными. Как организовать зависимости между задачами, их триггеры, управление параллельным выполнением задач и общей пулл соединений. Это требует дальнейшего изучения или исследования после изучения Control Hub.

Приложение: использование ресурсов

image-20200422011420897Показывает, что PySpider довольно ресурсоемок

image-20200422011357110

Опубликовать ( 0 )

Вы можете оставить комментарий после Вход в систему

1
https://api.gitlife.ru/oschina-mirror/Hu-Lyndon-streamsets-start-asset.git
git@api.gitlife.ru:oschina-mirror/Hu-Lyndon-streamsets-start-asset.git
oschina-mirror
Hu-Lyndon-streamsets-start-asset
Hu-Lyndon-streamsets-start-asset
master