Изначально я хотел протестировать синхронизацию данных из 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
Так как в данном тестовом примере используется 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.```
Нажмите кнопку Create, Project Name заполните значением `test1`, а Start URL — адресом Mooc (потому что он надежен).

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

Нажмите кнопку 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 сек)
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
, чтобы не забыть.
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
Хотя StreamSets имеет модуль streamsets-datacollector-jdbc-lib
, он не содержит конкретных драйверов для определенных баз данных, поэтому нам нужно загрузить jar-файлы. Откройте браузер и перейдите на порт 18630 хост-машины. Необходимо добавить этот порт в правила доступа ECS.
Я также загрузил jar-файл для Oracle. Для таких баз данных, как Oracle и Hive, которые требуют нескольких jar-файлов, загружайте все необходимые jar-файлы.

Теперь мы можем перезапустить сервис и проверить, куда были загружены 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-контейнер по умолчанию выставляет этот каталог через переменную окружения, поэтому мы также используем этот каталог при создании контейнера и монтируем его на хост-машине.
],
...
/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
В этом разделе я опираюсь на методы настройки, описанные другими пользователями, и предоставляю ссылку на соответствующий пост.
Вот как я настроил конфигурацию, без лишних пояснений:
Настройки источников:
Настройки учетных записей для доступа к MySQL (пользователь и пароль):
Настройки целевых объектов:
На последнем изображении отмечены настройки типа данных для полей типа BLOB по умолчанию в pyspider.
Настройки учетных записей для доступа к MySQL (пользователь и пароль):
Проверка синхронизации данных:
Проверил несколько раз, и в разделе истории можно подробно просмотреть, как SDC получает данные и записывает их в целевую таблицу, отслеживая смещение (offset).
Эти данные, как правило, сохраняются в директории /data
контейнера SDC, которую мы уже примонтировали к хост-системе:
Показывает, что PySpider довольно ресурсоемок
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Опубликовать ( 0 )