NiceFlow是一个类似Kettle数据ETL工具,同时比Kettle更加易用和轻量,目前还没有GUI界面
1. git地址
2. 特性
- 基于python的插件机制,目前提供70+插件,同时支持自定义插件
- 基于json的flow任务,支持自定义任务配置
- 提供好用的cli命令,无需写代码,完成数据分析工作
3. 安装依赖
pip install NiceFlow
4. MySQL数据全量/增量/按天分区同步HDFS(Hive)实战
4.1. 说明
NiceFlow 数据同步,只需要配置一个json文件,配置好后,执行任务即可,无需写任何代码,网上数据同步的工具非常多,NiceFlow和这些工具有非常多相似的地方,下面列举一些常用的数据同步工具
- SeaTunnel 基于java,更新非常活跃,使用较为简单,支持的特性比较丰富,博主比较看好的一个数据同步工具
- DataX 插件基于java,调用基于python,更新不活跃,执行速度较快,数据清洗转换插件较少,目前正在使用的同步工具
- Kettle kettle是博主最开始用的数据同步工具,开发过一些kettle的插件,kettle的问题点是缺失任务调度,插件开发复杂,在linux上运行较费内存,高级特性文档不够丰富,任务多了,容易让人崩溃,因为使用kettle的时候博主还是个菜鸟,使用kettle出现的各种坑爹的问题给博主造成了不小的精神上的伤害,因此博主想开发一个更加好用的数据ETL的工具,让大家轻松完成各种ETL任务。
- Sqoop 基于java,未更新,依赖 Hadoop MR 实现分布式,仅支持 MySQL、Oracle、DB2、Hive、HBase、S3 等几种数据源,使用较少
- Flume 基于java,更新不活跃,使用较少
4.2. 全量同步
下面是MySQL数据全量同步HDFS(Hive)的配置
{
"flow": {
"name": "",
"uid": "",
"param": {
}
},
"nodes": [
{
"id": "MySQLInput",
"name": "read1",
"type": "input",
"properties": {
"host": "127.0.0.1",
"port": 3306,
"username": "root",
"password": "123456",
"query": "select *,LEFT(create_time,10) as dt from wulian.wvp_log ",
"mode": "cursor" -- 可不传,cursor为游标模式抽取数据
}
},
{
"id": "HDFSOutput",
"name": "out",
"type": "translate",
"properties": {
"url": "http://192.168.1.90:14000", -- WebHDFS端口
"user": "hdfs",
"source": "wvp_log", --本地的一个临时目录,抽取mysql数据后会将数据先写道本地
"dest": "/user/hive/warehouse/test.db/wvp_log", --hdfs目录
"partitions": "dt", --hive表分区键,支持多分区 比如 dt,type
"format": "parquet" -- 生成parquet格式数据
}
}
],
"edges": [
{
"startId": "read1",
"endId": "out"
}
]
}
4.3. 执行同步任务
import unittest
from NiceFlow.core.flow import Flow
from NiceFlow.core.manager import FlowManager
class TestDuckDBInput(unittest.TestCase):
def test_hdfs_import_data_to_mysql(self):
path = "mysql_input_to_hdfs_all_sync.json"
myFlow: Flow = FlowManager.read(path)
flow_param ={}
myFlow.set_param(flow_param)
myFlow.run()
if __name__ == '__main__':
unittest.main()
4.4. 也可以使用cli方式执行任务
NiceFlow exec --path mysql_input_to_hdfs_all_sync.json
4.5. hdfs查看同步结果
hdfs dfs -ls /user/hive/warehouse/test.db/wvp_log/
4.6. hive建表并查看同步结果
-- dt为分区键,此时可实现按天分区
CREATE TABLE IF NOT EXISTS wvp_log (
id BIGINT COMMENT '主键',
name STRING COMMENT '名称',
type STRING COMMENT '请求类型',
uri STRING COMMENT '请求uri',
address STRING COMMENT '请求地址',
result STRING COMMENT '响应结果',
timing BIGINT COMMENT '耗时',
username STRING COMMENT '请求用户',
create_time STRING COMMENT '创建时间'
)
PARTITIONED BY (dt STRING)
STORED AS PARQUET;
-- 分区修复
MSCK REPAIR TABLE wvp_log;
-- 查询结果
SELECT * from wvp_log ;
-- 统计两边数据是否一致
SELECT count(1) from wvp_log ;
4.7. 按天同步
按天同步非常简单,只需要将sql语句添加一个查询条件即可,数据会自动覆盖分区的结果,如下:
{
"id": "MySQLInput",
"name": "read1",
"type": "input",
"properties": {
"host": "127.0.0.1",
"port": 3306,
"username": "root",
"password": "123456",
"query": "select *,LEFT(create_time,10) as dt from wulian.wvp_log where create_time >=TIMESTAMP(DATE_ADD(CURDATE(), INTERVAL -1 DAY)) ",
"mode": "cursor" -- 可不传,cursor为游标模式抽取数据
}
}
4.8. json中使用动态参数
上面的查询语句全量和增量不一样,这样需要修改json,我们可以传入一个参数动态生成查询参数
{
"id": "MySQLInput",
"name": "read1",
"type": "input",
"properties": {
"host": "127.0.0.1",
"port": 3306,
"username": "root",
"password": "123456",
"query": "select *,LEFT(create_time,10) as dt from wulian.wvp_log ${where_query} ",
"mode": "cursor" -- 可不传,cursor为游标模式抽取数据
}
}
cli中这样使用
NiceFlow exec --path mysql_input_to_hdfs_all_sync.json --param '{"where_query":"where create_time >=TIMESTAMP(DATE_ADD(CURDATE(), INTERVAL -1 DAY))"}'
代码中这样使用
def test_hdfs_import_data_to_mysql(self):
path = "mysql_input_to_hdfs_all_sync.json"
myFlow: Flow = FlowManager.read(path)
flow_param ={"where_query":"where create_time >=TIMESTAMP(DATE_ADD(CURDATE(), INTERVAL -1 DAY))"}
myFlow.set_param(flow_param)
myFlow.run()
4.9. TODO
下一节介绍一个json实现多表同步