Mysql同步到Hive实例
以下实例均为本地模式下运行完成,主要是针对Mysql数据同步到Hive的实例说明。将介绍mysqlreader和hivewrite的所有参数配置的使用。
mysqlwrite参数说明:https://github.com/DTStack/flinkx/blob/1.10_release/docs/offline/reader/mysqlreader.md
hiveread参数说明:https://github.com/DTStack/flinkx/blob/1.10_release/docs/offline/writer/hivewriter.md
1. 搭环境
首先需要安装Mysql,Hadoop,Hive。我将Mysql安装在本地,Hadoop搭建三台集群在虚拟机上,他们之间能够远程连接
在虚拟机上编译安装Flinkx。可参考官方快速启动Flinkx,我使用的是Flinkx1.8.5
2. 启动
启动mysql,hadoop,hive
# 启动hadoop
[root@slave13 conf]# start-all.sh
# 启动Hive
[root@slave13 conf]# hive
# 启动Hiveserver2,可使用jdbc连接操作hive
[root@slave13 conf]# hiveserver2
#启动后的进程
[root@slave13 conf]# xcall jps
=========slave13==================
37588 NameNode
37797 SecondaryNameNode
71958 RunJar
37965 ResourceManager
76156 Jps
=========slave11=====================
9633 Jps
118029 NodeManager
117903 DataNode
=========slave12=====================
5813 Jps
115654 NodeManager
115530 DataNode
3. 开始
为了让大家先看看效果,先做个简单的实例;
3.1 准备mysql上的源表和数据
create table emp(
id int null,
name varchar(100) null );
insert into emp values(1,"aaa"),(2,"bbb");
3.2 同步到hive的表先不创建,因为在Flinkx同步时,发现没有表时会自动创建。当然也可以提前建表,如何建表,选择什么分隔符,要根据实际情况而定,不知道的不如先让Flinkx自动创建后,在回头看看它建表的DDL。
3.3 编写Flinkx的配置文件,在Flinkx当前目录下,新建job文件夹,在创建mysql2hive.json文件
{
"job": {
"content": [
{
"reader": {
"name": "mysqlreader",
// 连接mysql的相关配置
"parameter": {
"username": "root",
"password": "123456",
"connection": [{
"jdbcUrl": ["jdbc:mysql://192.168.8.135:3306/flinkx?useUnicode=true&characterEncoding=utf8"],
"table": ["emp"]
}],
// 抽取的字段值
"column": ["id","name"],
"queryTimeOut": 1000,
"requestAccumulatorInterval": 2
}
},
"writer": {
"name": "hivewriter",
// 连接hive的相关配置
"parameter": {
"hadoopConfig": {
// datanode的节点名
"dfs.ha.namenodes.ns1" : "slave11,slave12",
"fs.defaultFS" : "hdfs://slave13:9000",
"dfs.namenode.rpc-address.ns1.nn1" : "slave13:9000",
"dfs.client.failover.proxy.provider.ns1" : "org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider",
// namenode的节点名
"dfs.nameservices" : "slave13",
"fs.hdfs.impl.disable.cache" : "true",
"fs.hdfs.impl" : "org.apache.hadoop.hdfs.DistributedFileSystem"
},
// append追加,overwrite覆盖
"writeMode":"append",
"encoding": "utf-8",
"fileType": "text",
// 同步到hive表的相关配置
"tablesColumn" : "{\"emp_hive\":[{\"key\":\"id\",\"type\":\"INT\"},{\"key\":\"name\",\"type\":\"STRING\"}]}",
"jdbcUrl" : "jdbc:hive2://192.168.80.13:10000/flinkx",
"charsetName" : "utf-8",
"username" : "root",
"password" : "123456"
}
}
}
],
"setting": {
"speed": {
"channel": 1,
"bytes": 0
},
"errorLimit": {
"record": 100
},
"restore": {
"maxRowNumForCheckpoint": 0,
"isRestore": false,
"restoreColumnName": "",
"restoreColumnIndex": 0
},
"log" : {
"isLogger": false,
"level" : "debug",
"path" : "",
"pattern":""
}
}
}
}
3.4 在Flinkx目录下新建start.sh脚本
Flinkx的路径修改为你自己的安装路径
/usr/local/src/flinkx-1.8.5/bin/flinkx \
-mode local \
-job /usr/local/src/flinkx-1.8.5/job/mysql2hive.json \
-pluginRoot /usr/local/src/flinkx-1.8.5/plugins \
-flinkconf /usr/local/src/flinkx-1.8.5/flinkconf \
-confProp "{\"flink.checkpoint.interval\":60000}"
3.5 启动即可
启动后,会在start.sh当前目录下新建nohup.out日志文件
[root@slave13 startDir]# sh start.sh
# 实时监听日志文件
[root@slave13 startDir]# tail -f nohup.out
运行成功后,从日志中可知同步结果,比如读取条数和时间,写入条数和时间等信息,
14:16:12.165 [flink-metrics-12] INFO org.apache.flink.runtime.rpc.akka.AkkaRpcService - Stopping Akka RPC service.
14:16:12.177 [flink-akka.actor.default-dispatcher-16] INFO org.apache.flink.runtime.blob.PermanentBlobCache - Shutting down BLOB cache
14:16:12.179 [flink-akka.actor.default-dispatcher-16] INFO org.apache.flink.runtime.blob.TransientBlobCache - Shutting down BLOB cache
14:16:12.180 [flink-akka.actor.default-dispatcher-16] INFO org.apache.flink.runtime.blob.BlobServer - Stopped BLOB server at 0.0.0.0:33533
14:16:12.181 [flink-akka.actor.default-dispatcher-16] INFO org.apache.flink.runtime.rpc.akka.AkkaRpcService - Stopped Akka RPC service.
---------------------------------
numWrite | 3
last_write_num_0 | 0
conversionErrors | 0
writeDuration | 21567
duplicateErrors | 0
numRead | 3
snapshotWrite | 3
otherErrors | 0
readDuration | 4423
byteRead | 21
last_write_location_0 | 0
byteWrite | 21
nullErrors | 0
nErrors | 0
---------------------------------
5. 常用操作
如何全量增量的同步数据,如何将过滤后的数据同步,我们围绕这几点做实际的实践演练
5.1 全量同步
上面的例子就已经是全量同步的操作了。当然写模式应该是覆盖writeMode=overwrite
5.2 增量同步
其他配置不用修改,只需要修改reader参数
增量同步首先需要从源表中选出增量字段,增量同步的起始位置,并开启增量抽取的最大值展示,还有目标表写入模式为追加
增量字段最起码的要求是数据不重复,不然在增量抽取过程中无法根据增量字段定位起始位置,导致重复抽取或少抽取
增量抽取的最大值就是上次增量抽取时增量字段的最大值,以便下次增量抽取时确定抽取的起始位置。这个最大值就是运行结束后运行日志中返回的maxValue。要是运用到实际工作中,应该有相应的接口能够获取这个返回值
// 选择增量字段,比如id,时间字段
"increColumn": "id",
// 当使用时间字段作为增量字段时,使用时间戳才能够识别解析,直接使用“2021-05-27 12:12:23”解析出错
"startLocation": "24",
// 开启后,运行结束后会返回当前增量抽取的的最大值maxValue
"useMaxFunc":true,
"writeMode":"append",
5.3 轮询抽取
其他配置不用修改,只需要修改reader参数
开启间隔轮询后,会在间隔时间周期内从源库中抽取数据,在写入目标库。
需要配置polling,pollingInterval间隔时间,increColumn增量字段,startLocation起始位置(默认是增量字段最大值)
这种情况可能适用于,有固定的增量同步周期,比如固定在每天的凌晨开始同步数据,开启间隔轮询后,间隔时间调整为23小时后开始执行同步的情况
// polling全量轮询抽取,针对全量表定期更新的情况,可以开启间隔时间内的轮询抽取
// 也就是实时抽取,好像实时导入到hive行不同,同步到mysql可以
// 为什么定时写入hive,需要开启splitPk和speed.channel呢
"polling": true,
"pollingInterval": 3000,
"increColumn": "id",
"startLocation": "1",
输入的数据量在不断变化
5.4 并发读取
其他配置不用修改,只需要修改reader参数
Reader插件根据并发数和此参数指定的字段拼接sql,使每个并发读取不同的数据,提升读取速率。
推荐splitPk使用表主键,因为表主键通常情况下比较均匀,因此切分出来的分片也不容易出现数据热点。
目前splitPk仅支持整形数据切分,不支持浮点、字符串、日期等其他类型
"splitPk": "id",
"channel": 1,
并发插入的数据顺序不一
5.5 自定义查询
其他配置不用修改,只需要修改reader参数
customSql:自定义的查询语句,如果只指定字段不能满足需求时,可通过此参数指定查询的sql,可以是任意复杂的查询语句
where:reader插件根据指定的column、table、where条件拼接SQL,并根据这个SQL进行数据抽取
fetchSize:限制一次性从数据库中读取多少条数据
"customSql": "select id,name,deptno from emp where deptno=2",
"where":" id < 10",
"fetchSize": 1000,