我尝试使用Embulk将MongoDB中的数据迁移到MySQL
本文是ZOZO Technologies Advent Calendar第2天的第24篇文章。
概述
ZOZOTOWN的替换工具采用Embulk进行数据库数据迁移。
Embulk是一种用于数据传输的工具,可以通过组合插件(输入、输出、过滤器)来自由传输各种数据。
这次我们进行了从MongoDB到MySQL的数据迁移,
由于相关信息比较少,希望能提供参考,我想介绍一下步骤。
太长了,不想读。
embulk-input-mongodb、embulk-output-mysql
を使う
filter を使いデータ加工を行う必要がある
カラム展開は expand_json を使う
NULLデータの default 値は column で設定
过渡的必要条件
我们根据以下要求进行了数据迁移。
-
- MongoDB 2.6 → mysql 5.7 へデータ移行
-
- MongoDB のデータはフィールド数がまちまち
- MySQLで NOT NULL としたいカラムに対し、MongoDB で Key が存在しないデータの場合デフォルト値を指定して移行
建立测试环境
为了能够轻松进行操作确认,我们可以使用docker-compose快速创建验证环境。
如果您只想确认流程,请忽略这里的内容。
version: "3.7"
networks:
backend:
services:
mongodb:
image: mongo:2.6
container_name: mongodb
networks:
- backend
ports:
- 27018:27017
mysql:
image: mysql:5.7
container_name: mysql
environment:
- MYSQL_DATABASE=test
- MYSQL_ROOT_PASSWORD=hogehoge
networks:
- backend
ports:
- 3307:3306
请在创建上述docker-compose.yml文件后执行以下命令。
$ docker-compose up -d
$ docker-compose exec mongodb mongo test
(mongo)> db.Users.insert([
{"id": 1, "name": "hoge", "email": "hoge@example.com", "age": 20},
{"id": 2, "name": "fuga", "email": "fuga@example.com", "age": 25},
{"id": 3, "name": "foo", "age": 30}
])
如果存储了下面这样的数据,准备工作就可以了。
> db.Users.find()
{ "_id" : ObjectId("5fe2679a62a2dec6c0f0751b"), "id" : 1, "name" : "hoge", "email" : "hoge@example.com", "age" : 20 }
{ "_id" : ObjectId("5fe2679a62a2dec6c0f0751c"), "id" : 2, "name" : "fuga", "email" : "fuga@example.com", "age" : 25 }
{ "_id" : ObjectId("5fe2679a62a2dec6c0f0751d"), "id" : 3, "name" : "foo", "age" : 30 }
将MongoDB中的数据迁移到MySQL
输入-MongoDB、输出-MySQL插件。
通过使用 `embulk-input-mongodb`,可以将数据从 MongoDB 迁移到 MySQL。
Embulk的YAML如下所示。
in:
type: mongodb
hosts:
- {host: 127.0.0.1, port: 27018}
database: test
collection: "Users"
out:
type: mysql
host: 127.0.0.1
port: 3307
user: root
password: hogehoge
database: test
table: users
mode: replace
当执行embulk run config.yml时,可以将以下数据迁移到MySQL users表中。
$ mysql -u root -phogehoge -P 3307 -h 127.0.0.1 test -e "select * from users;"
+-------------------------------------------------------------------------------------------------+
| record |
+-------------------------------------------------------------------------------------------------+
| {"_id":"5fe2679a62a2dec6c0f0751b","id":1.0,"name":"hoge","email":"hoge@example.com","age":20.0} |
| {"_id":"5fe2679a62a2dec6c0f0751c","id":2.0,"name":"fuga","email":"fuga@example.com","age":25.0} |
| {"_id":"5fe2679a62a2dec6c0f0751d","id":3.0,"name":"foo","age":30.0} |
+-------------------------------------------------------------------------------------------------+
我已成功将 MongoDB 的数据迁移到 MySQL。
然而,记录列中的数据仍保持为 JSON 结构。
因此,我将使用过滤器对数据进行处理。
使用expand_json过滤器,将JSON展开到列中
使用过滤器:expand_json。
在 embulk-input-mongodb 中,默认输出的列名为 record,所以将 json_column_name 设置为 record。
in:
type: mongodb
hosts:
- {host: 127.0.0.1, port: 27018}
database: test
collection: "Users"
filters:
- type: expand_json
json_column_name: record
expanded_columns:
- {name: id, type: long}
- {name: name, type: string}
- {name: email, type: string}
- {name: age, type: long}
out:
type: mysql
host: 127.0.0.1
port: 3307
user: root
password: hogehoge
database: test
table: users
mode: replace
运行`embulk run config.yml`可以将以下数据迁移到MySQL的`users`表中。
$ mysql -u root -phogehoge -P 3307 -h 127.0.0.1 test -e "select * from users;"
+------+------+------------------+------+
| id | name | email | age |
+------+------+------------------+------+
| 1 | hoge | hoge@example.com | 20 |
| 2 | fuga | fuga@example.com | 25 |
| 3 | foo | NULL | 30 |
+------+------+------------------+------+
json をカラムに展開しつつデータ移行できました。
MongoDB で email の Key を持たないデータは、email が NULL となっています。
email カラムを NOT NULL としたい場合この状態は望ましくありません。
こちらもフィルターを使うことで、NULLではなく ”(空) など default 値を設定することが出来ます。
使用列过滤器,指定默认值。
使用过滤器:列。
in:
type: mongodb
hosts:
- {host: 127.0.0.1, port: 27018}
database: test
collection: "Users"
filters:
- type: expand_json
json_column_name: record
expanded_columns:
- {name: id, type: long}
- {name: name, type: string}
- {name: email, type: string}
- {name: age, type: long}
- type: column
columns:
- {name: id}
- {name: name}
- {name: email, default: ''}
- {name: age}
out:
type: mysql
host: 127.0.0.1
port: 3307
user: root
password: hogehoge
database: test
table: users
mode: replace
执行”embulk run config.yml”命令可以将以下数据迁移到MySQL users表中。
+------+------+------------------+------+
| id | name | email | age |
+------+------+------------------+------+
| 1 | hoge | hoge@example.com | 20 |
| 2 | fuga | fuga@example.com | 25 |
| 3 | foo | | 30 |
+------+------+------------------+------+
以上是根据要求成功地进行了数据迁移,通过将电子邮件列设置为空”。
概述
使用 embulk-input-mongodb 获取数据,并结合过滤器,成功将 MongoDB 的数据迁移到 MySQL,按照要求完成了数据迁移。
由于 Embulk 内建了许多插件,可以灵活地满足各种需求,因此我们可以根据不同的要求进行适应。
(在我们公司中,Sonots、Civitaspo 等人发布了各种插件,本次使用的过滤器也是由他们开发的。)
如果您对涉及数据迁移的替换时机感兴趣的话,强烈建议您使用Embulk,轻松进行数据迁移的尝试。
感谢您阅读。