本文为您介绍离线同步的相关问题。
文档概述
问题分类 | 相关文档 |
离线同步任务运维常见问题 | |
非插件报错原因及解决方案 | |
具体插件报错原因及解决方案 | |
离线同步场景及解决方案 |
|
报错信息及解决方案 |
|
为什么数据源测试连通性成功,但是离线同步任务执行失败?
如果您之前测试连通性通过,请重新测试连通性,确认资源组与数据库当前是可联通状态(确认数据库端无变更)。
请检查测试连通性成功的资源组和任务执行所用的资源组是不是同一个。
查看任务运行资源:
任务运行在默认的资源组上,日志中会出现如下信息:
running in Pipeline[basecommon_ group_xxxxxxxxx]
。任务运行在数据集成自定义资源组上,日志中会出现如下信息:
running in Pipeline[basecommon_xxxxxxxxx]
。任务运行在独享数据集成资源上,日志中会出现如下信息:
running in Pipeline[basecommon_S_res_group_xxx]
。
如果凌晨任务调度时偶尔失败,但重跑又能成功,请检查数据库在报错时间点的负载情况。
如何切换数据集成任务执行资源组?
您可以在DataStudio修改数据集成任务调试所用的资源组,同时,也支持您在运维中心修改任务调度时所使用的数据集成任务执行资源组。配置详情请参见:新增和使用独享数据集成资源组。
脏数据如何排查和定位?
脏数据定义:单条数据写入目标数据源过程中发生了异常,则此条数据为脏数据。 因此只要是写入失败的数据均被归类于脏数据。
脏数据影响:脏数据将不会成功写入目的端。您可以控制是否允许脏数据产生,并且支持控制脏数据条数,数据集成默认允许脏数据产生,您可以在同步任务配置时指定脏数据产生条数。详情可参考:通过向导模式配置离线同步任务。
任务设置允许脏数据:当脏数据产生时,任务继续执行,但脏数据将会被舍弃,不写入目的端。
任务控制允许产生的脏数据条数:
设置脏数据允许条数为0条,则当脏数据产生时,任务将失败退出。
设置脏数据允许条数为x条,则当脏数据产生条数超过x条时,任务将失败退出,当脏数据产生条数小于x条时,任务将继续运行,但脏数据将会被舍弃,不写入目的端。
脏数据实时场景分析:
场景一:
报错现象:
{"message":"写入 ODPS 目的表时遇到了脏数据: 第[3]个字段的数据出现错误,请检查该数据并作出修改或者您可以增大阈值,忽略这条记录.","record":[{"byteSize":0,"index":0,"type":"DATE"},{"byteSize":0,"index":1,"type":"DATE"},{"byteSize":1,"index":2,"rawData":0,"type":"LONG"},{"byteSize":0,"index":3,"type":"STRING"},{"byteSize":1,"index":4,"rawData":0,"type":"LONG"},{"byteSize":0,"index":5,"type":"STRING"},{"byteSize":0,"index":6,"type":"STRING"}
。如何处理:该日志中可以看出脏数据的字段,第三个字段异常。
脏数据是writer端报的,要检查下writer端的建表语句。odps端该表字段指定的字段大小小于MySQL端该字段数据大小 。
数据同步原则:来源端数据源的数据要能写入目的端数据源(来源端和目的端类型需要匹配,字段定义的大小需要匹配),即源端数据类型需要与写端数据类型匹配,源端是VARCHAR类型的数据不可写到INT类型的目标列中;目标端的数据类型定义的大小需要可以接收源端映射字段实际数据大小,源端是long、varchar 、double等类型的数据,目的端均可用string、text等大范围类型接纳。
脏数据报错不清晰时,需要复制出打印出的脏数据的一整条,观察其中的数据,和目的端数据类型比较,看哪一条或哪一些不合规范。
比如:
{"byteSize":28,"index":25,"rawData":"ohOM71vdGKqXOqtmtriUs5QqJsf4","type":"STRING"}
byteSize:字节数;index:25,第26个字段;rawData:具体值(即value);type:数据类型。
场景二:
报错现象:DataX读取MySQL中有空值时报脏数据。
如何处理:请检查源端存在空值的字段将写入目标端什么类型的字段中,如果类型不一致将会报错。例如,string类型的null写入目标端int类型字段时会报错。
如何查看脏数据?
如果离线同步传输数据时,脏数据超出限制,是否所有数据都不会同步?
当脏数据数量超出限制时,任务立即停止,此前传输了多少条数据就是多少条。脏数据限制设置为多少就是不允许有多少条脏数据,若限制为0即在发现第一条脏数据时就会停止任务,此时有可能已经传几条数据了,或者没有传输数据(脏数据在所有数据中位于第一条时)。
如何排查离线同步任务运行时间长的问题?
可能原因1:执行时间过长
前置语句或后置语句(例如:preSql和postSql)在数据库执行耗时过长,导致任务运行慢。
未合理配置切分键,导致任务运行慢。
离线同步会根据切分键(splitPk)来对进行数据分片,数据同步根据此配置启动并发任务进行数据同步,提高数据同步的效能。(具体插件是否需要配置切分键,请参考具体插件文档)。
解决方案1:
若配置前置或后置语句,建议使用添加了索引的字段进行数据过滤。
支持设置切分键的场景下,建议合理配置切分键。以MySQL Reader插件切分键配置为例:
推荐splitPk用户使用表主键,因为表主键通常情况下比较均匀,因此切分出来的分片也不容易出现数据热点。
目前splitPk仅支持整型数据切分,不支持字符串、浮点和日期等其他类型 。如果指定其他非支持类型,将使用单通道进行同步。
如果不填写splitPk,包括不提供splitPk或者splitPk值为空,数据同步视作使用单通道同步该表数据 。
可能原因2:等待数据集成任务执行资源
解决方案2:若日志出现长时间WAIT状态,说明当前任务运行所使用的独享数据集成资源组剩余可运行的并发数不足以运行当前任务。具体原因及解决方案详情请参见:为什么数据集成任务一直显示wait?。
由于离线同步任务通过调度资源组下发到数据集成执行资源组上执行,所以一个离线同步任务将同时耗费一个调度资源,若离线同步任务长时间运行未释放资源,除了阻塞其他离线任务运行外,可能还将阻塞其他类型的调度任务运行。
如何处理编码格式设置/乱码问题导致的脏数据报错?
报错现象:
如果数据中包括表情符,在同步过程中可能会报错脏数据:
[13350975-0-0-writer] ERROR StdoutPluginCollector - 脏数据 {"exception":"Incorrect string value: '\\xF0\\x9F\\x98\\x82\\xE8\\xA2...' for column 'introduction' at row 1","record":[{"byteSize":8,"index":0,"rawData":9642,"type":"LONG"}],"type":"writer"}
。可能原因:
数据库相关编码未设置为utf8mb4,导致同步表情符报错。
源端的数据本身就是乱码。
数据库和客户端的编码不一样。
浏览器编码不一样,导致预览失败或乱码。
解决方案:
针对产生乱码的不同原因,选择相应的解决方法:
如果您的原始数据乱码,需首先处理好原始数据,再进行同步任务。
数据库和客户端编码格式不一致,需先修改编码格式。
浏览器编码和数据库或客户端编码格式不一致,需先统一编码格式,然后进行数据预览。
您可以尝试以下操作:
JDBC格式添加的数据源修改utf8mb4:
jdbc:mysql://xxx.x.x.x:3306/database?com.mysql.jdbc.faultInjection.serverCharsetIndex=45
。实例ID形式添加数据源:在数据库名后拼接,格式为
database?com.mysql.jdbc.faultInjection.serverCharsetIndex=45
。修改数据库相关的编码格式为utf8mb4。例如,在RDS控制台修改RDS的数据库编码格式。
说明设置RDS数据源编码格式命令:
set names utf8mb4
。查看RDS数据库编码格式命令:show variables like 'char%'
。
任务存在SSRF攻击Task have SSRF attacks
如何处理?
目前基于数据库内网的数据源,请更换使用独享数据集成资源组运行任务,独享数据集成资源组的使用详情可参见文档:新增和使用独享数据集成资源组。
离线同步任务执行偶尔成功偶尔失败
出现离线同步任务偶尔执行失败的情况,可能是因为白名单配置不全导致的,您需要检查数据库白名单是否配置完全。
使用独享数据集成资源组时:
如果您此前已经将独享数据集成资源组的弹性网卡IP添加到了数据源的白名单中,后续如果资源组有扩容,您需要及时更新数据源的白名单,将扩容后的资源组的弹性网卡IP添加到数据源白名单中。
为了避免出现资源组扩容后需要再次添加白名单的情况,建议您直接添加独享数据集成资源组绑定的交换机网段作为数据库白名单。详情请参见添加白名单。
如果白名单无异常,请确认数据库负载是否过高导致连接中断。
离线同步源表有加列(修改)如何处理?
进入同步任务配置页面,修改字段的映射后,即可将变化的字段更新在任务配置中,完成后,您需要重新提交执行任务后变更才能生效。
添加MongoDB数据源时,使用root用户时报错
使用root用户添加MongoDB数据源时报错,是因为添加MongoDB数据源时,必须使用用户需要同步的表所在的数据库创建的用户名,不可以使用root用户。
例如需要导入name表,name表在test库,则此处数据库名称为test,需要使用test数据库中创建的用户的用户名。
读取MongoDB时,如何在query参数中使用timestamp实现增量同步?
可以使用赋值节点先对date类型时间处理成timestamp,将该值作为MongoDB数据同步的入参,详情请参考文档:MongoDB时间戳类型字段如何实现增量同步?
MongoDB同步至数据目的端数据源后,时区加了8个小时,如何处理?
你需要在MongoDB Reader配置中设置时区,详情请参见MongoDB Reader。
读取MongoDB数据期间,源端有更新记录,但未同步至目的端,如何处理?
您可以间隔一段时间后重启任务,query条件不变,即将同步任务的执行时间延迟,配置不变。
读取OSS文件是否有文件数限制?
OSSreader插件读取OSS执行时间超过RDS侧允许的最大文件数datax本身没有限制,主要看任务配置的jvm参数,但是不建议object参数配置*,容易导致内存溢出。
写入DataHub时,一次性写入数据超限导致写入失败如何处理?
报错现象:
ERROR JobContainer - Exception when job runcom.alibaba.datax.common.exception.DataXException: Code:[DatahubWriter-04], Description:[写数据失败.]. - com.aliyun.datahub.exception.DatahubServiceException: Record count 12498 exceed max limit 10000 (Status Code: 413; Error Code: TooLargePayload; Request ID: 20201201004200a945df0bf8e11a42)
可能原因:
报错原因为datax一次性提交到DataHub的数据量超过DataHub的限制。影响提交到DataHub数据量的配置参数主要为:
maxCommitSize:表示datax累积的buffer数据,待积累的数据大小达到maxCommitSize 大小(单位MB)时,批量提交到目的端。默认是 1MB,即 1,048,576字节。
batchSize:DataX-On-Flume积累的Buffer数据条数,待积累的数据条数达到batchSize大小(单位条数)时,批量提交至目的端。
解决方案:
调小maxCommitSize和batchSize的参数值。
使用lindorm bulk方式写入数据,是否每次都会替换掉历史数据?
和API方式写入逻辑一致,同行同列会被覆盖,其他数据不变。
如何查询一个ES索引下的所有字段?
通过curl命令获取ES索引Mapping,从Mapping中提取所有字段。
查询Shell命令:
//es7 curl -u username:password --request GET 'http://esxxx.elasticsearch.aliyuncs.com:9200/indexname/_mapping' //es6 curl -u username:password --request GET 'http://esxxx.elasticsearch.aliyuncs.com:9200/indexname/typename/_mapping'
结果获取字段:
{ "indexname": { "mappings": { "typename": { "properties": { "field1": { "type": "text" }, "field2": { "type": "long" }, "field3": { "type": "double" } } } } } }
返回结果中properties下就是索引所有的字段和属性定义。如上索引包含field1、field2、field3三个字段。
数据从ES离线同步至其他数据源中时,每天同步的索引名称不一样,如何配置?
索引配置时可以加入日期调度变量,根据不同的日期计算出索引字符串,实现Elasticsearch Reades索引名的自动变化,配置过程包含如下三步:定义日期变量、配置索引变量、任务发布与执行。
定义日期变量:在同步任务的调度配置中,选择新增参数定义日期变量。如下var1配置表示任务执行时间(当天),var2表示任务的业务日期(前一天)。详情请参见调度参数配置最佳实践。
配置索引变量:将任务转为脚本模式,配置Elasticsearch Reader的索引,配置方式为:${变量名},如下图所示。
任务发布与执行:执行验证后,将任务提交发布至运维中心,以周期调度或补数据的方式运行。
单击带参运行按钮直接运行任务进行验证,带参运行会将任务配置中使用的调度系统参数进行替换,执行后查看日志同步索引是否符合预期。
说明注意在带参运行时直接输入参数值进行替换测试。
如果上一步验证符合预期,则任务配置已经完成,此时可以依次单击保存和提交按钮将同步任务提交到生产环境。
如果是标准项目,需要单击发布按钮进入发布中心才能将同步任务发布到生产环境。
结果:如下是配置与实际运行的索引结果。
脚本索引配置为:
"index": "esstress_1_${var1}_${var2}"
。运行索引替换为:
esstress_1_20230106_20230105
。
离线同步任务如何自定义表名?
如果您表名较规律,例如orders_20170310、orders_20170311和orders_20170312,按天区分表名称,且表结构一致。您可以结合调度参数通过脚本模式配置离线同步任务自定义表名,实现每天凌晨自动从源数据库读取前一天表数据。
例如,今天是2017年3月15日,自动从源数据库中读取orders_20170314的表的数据导入,以此类推。
在脚本模式中,修改来源表的表名为变量,例如orders_${tablename}。由于按天区分表名称,且需要每天读取前一天的数据,所以在任务的参数配置中,为变量赋值为tablename=${yyyymmdd}。
更多调度参数的使用问题请参考文档调度参数支持的格式
配置离线同步节点时,无法查看全部的表,该如何处理?
您在配置离线同步节点时,选择来源区域仅默认显示所选数据源中的前25张表。如果数量过大,您可以输入表名进行搜索或使用脚本模式开发。
读取MaxCompute(ODPS)表数据时,添加一行注意事项
可以输入常量,输入的值需要使用英文单引号包括,例如'abc'、'123'等。
可以配合调度参数使用,如'${bizdate}' 等,调度参数具体使用请参考文档调度参数支持的格式。
可以输入你要同步的分区列,如分区列有pt等。
如果您输入的值无法解析,则类型显示为'自定义'。
不支持配置odps函数。
如果您手工编辑添加的列显示自定义(例如添加了MaxCompute分区列,LogHub数据预览未预览到的列),不会影响实际任务执行。
读取MaxCompute(ODPS)表数据时,如何同步分区字段?
请在字段映射处选择添加一行,输入分区列名,如分区列有pt等;
读取MaxCompute(ODPS)表数据时,如何同步多个分区数据?
读取数据所在的分区信息。
ODPS的分区配置支持Linux shell通配符,*表示0个或多个字符,?表示任意一个字符。
默认情况下,读取的分区必须存在,如果分区不存在则运行的任务会报错。如果您希望当分区不存在时任务仍然执行成功,则可以切换至脚本模式执行任务,并在ODPS的Parameter中添加
"successOnNoPartition": true
配置。
例如,分区表test包含pt=1,ds=hangzhou、pt=1,ds=shanghai、pt=2,ds=hangzhou、pt=2,ds=beijing四个分区,则读取不同分区数据的配置如下:
如果您需要读取pt=1,ds=hangzhou分区的数据,则分区信息的配置为
"partition":"pt=1,ds=hangzhou”
。如果您需要读取pt=1中所有分区的数据,则分区信息的配置为
"partition":"pt=1,ds=*”
。如果您需要读取整个test表所有分区的数据,则分区信息的配置为
"partition":"pt=*,ds=*"
。
此外,您还可以根据实际需求设置分区数据的获取条件(以下操作需要转脚本模式配置任务):
如果您需要指定最大分区,则可以添加
/*query*/ ds=(select MAX(ds) from DataXODPSReaderPPR)
配置信息。如果需要按条件过滤,则可以添加相关条件
/*query*/ pt+表达式
配置。例如/*query*/ pt>=20170101 and pt<20170110
表示获取pt分区中,20170101日期之后(包含20170101日期),至20170110日期之前(不包含20170110日期)的所有数据。
/*query*/
表示将其后填写的内容识别为一个where条件。
如何处理表列名有关键字导致同步任务失败的情况?
报错原因:column中含有保留字段,或者 column配置中含有数字开头的字段。
解决方法:数据集成同步任务转脚本模式配置,对column配置中的特殊字段添加进行转义。脚本模式配置任务请参考:通过脚本模式配置离线同步任务。
MySQL的转义符为
`关键字`
。Oracle和PostgreSQL的转义符为
"关键字"
。SQlServer的转义符为
[关键字]
。
MySQL为场景示例:
以MySQL数据源为例:
执行下述语句,新建一张表aliyun。
create table aliyun (`table` int ,msg varchar(10));
执行下述语句,创建视图,为table列取别名。
create view v_aliyun as select `table` as col1,msg as col2 from aliyun;
说明table是MySQL的关键字,在数据同步时,拼接出来的代码会报错。因此需要通过创建视图,为table列起别名。
不建议使用关键字作为表的列名。
通过执行上述语句,为有关键字的列取列名。在配置同步任务时,选择v_aliyun视图代替aliyun表即可。
读取Loghub同步某字段有数据但是同步过来为空
此插件字段大小写敏感,请检查loghub reader的column配置。
读取Loghub同步少数据
数据集成取的是数据进入loghub的时间,请在Loghub控制台检查数据元数据字段receive_time是否在任务配置的时间区间内。
读取Loghub字段映射时读到的字段不符合预期
如果出现此现象请在界面手动编辑column。
读取kafka配置了endDateTime来指定所要同步的数据的截止范围,但是在目的数据源中发现了超过这个时间的数据
kafka Reader在读数据的时候,是以batch的形式进行的,在读到的一批数据中,如果有超过endDateTime的,则停止同步,但是超出endDateTime的这部分数据也会被写入到目的端数据源。
您也可以通过skipExceedRecord配置项来指定是否同步超出的数据。详细使用方法见Kafka Reader。【不建议设置为不同步,会有造成丢数据】
您可以通过配置kafka的max.poll.records配置项来指定一次拉取数据的量,结合并发数,来控制可能超出的数据量。超出的数据量 < max.poll.records * 并发数
Kafka中数据量少,但是任务出现长时间不读取数据也不结束,一直运行中的现象是为什么?
分析原因:
这种情况通常是因为指定了同步结束策略未到达指定结束位点,此时对于所有读到位点处于读取起始位点和读取结束位点之间数据的分区,全部需要读到至少一条位点大于或等于指定结束位点的记录,任务才会退出,否则会一直重试拉取数据。
解决办法:
这种情况下建议减少Kafka分区数量,或者定时往Kafka每个分区写入一条心跳记录帮助同步任务满足结束条件。
写入OSS出现随机字符串如何去除?
OSS Writer写入的文件名,OSS使用文件名模拟目录的实现。OSS对于Object的名称有以下限制:使用"object": "datax",写入的Object以datax开头,后缀添加随机字符串。文件数由实际切分的任务数有关。
如果您不需要后缀随机UUID,建议您配置"writeSingleObject" : "true",详情请参见OSS Writer文档的writeSingleObject说明。
详情请参考文档:[OSS writer](OSS Writer)
MySQL分库分表如何将分表同步到一张MaxCompute中
您可以参考MySQLreader插件文档进行任务配置:MySQL Reader
数据同步任务where条件没有索引,导致全表扫描同步变慢
场景示例
执行的SQL如下所示。
select bid,inviter,uid,createTime from `relatives` where createTime>='2016-10-2300:00:00'and reateTime<'2016-10-24 00:00:00';
从2016-10-25 11:01:24.875开始执行,到2016-10-25 11:11:05.489开始返回结果。同步程序在等待数据库返回SQL查询结果,MaxCompute需等待很久才能执行。
分析原因
where条件查询时,createTime列没有索引,导致查询全表扫描。
解决方法
建议where条件使用有索引相关的列,提高性能,索引也可以补充添加。
目的端MySQL表字符集为utf8mb4时,同步到MySQL中的中文字符出现乱码时,如何处理?
选择通过连接串的方式添加数据源,建议JDBC格式修改为:jdbc:mysql://xxx.x.x.x:3306/database?com.mysql.jdbc.faultInjection.serverCharsetIndex=45
,详情请参见配置MySQL数据源。
使用API方式同步的时候,支持使用来源端的(例如MaxCompute)函数做聚合吗?例如源表有a、b两列作为Lindorm的主键
API方式同步不支持使用来源端函数,需要先在来源端函数上处理好后再导入数据。
同步的数据表,是否只能使用Alter方式来修改TTL?
TTL是在表上设置的,同步任务配置时没有此选项。
Elasticsearch Reader如何同步对象Object或Nested字段的属性?(例如同步object.field1)
需要同步对象字段属性,只支持使用脚本模式,脚本模式下配置如下multi,column按属性.子属性进行配置。
"multi":{
"multi":true
}
可以参看如下样例进行配置:
#例子:
##es内的数据
"hits": [
{
"_index": "mutiltest_1",
"_type": "_doc",
"_id": "7XAOOoMB4GR_1Dmrrust",
"_score": 1.0,
"_source": {
"level1": {
"level2": [
{
"level3": "testlevel3_1"
},
{
"level3": "testlevel3_2"
}
]
}
}
}
]
##reader配置
"parameter": {
"column": [
"level1",
"level1.level2",
"level1.level2[0]"
],
"multi":{
"multi":true
}
}
##写端结果:1行数据3列,列顺序同reader配置,
COLUMN VALUE
level1: {"level2":[{"level3":"testlevel3_1"},{"level3":"testlevel3_2"}]}
level1.level2: [{"level3":"testlevel3_1"},{"level3":"testlevel3_2"}]
level1.level2[0]: {"level3":"testlevel3_1"}
存储在ODPS的string类型同步至ES后,两侧缺少引号,如何处理?源端JSON类型的string是否可以同步为ES中的NESTED对象?
显示字符前后多两个双引号为“Kibana”工具显示问题,实际数据并没有前后双引号,请使用curl命令或postman查看实际数据情况。获取数据curl命令如下:
//es7 curl -u username:password --request GET 'http://esxxx.elasticsearch.aliyuncs.com:9200/indexname/_mapping' //es6 curl -u username:password --request GET 'http://esxxx.elasticsearch.aliyuncs.com:9200/indexname/typename/_mapping'
可以配置ES写入字段type为nested类型,以同步ODPS中JSON类型的string数据至ES存储为nested形式。如下同步name字段到es中为nested格式。
同步配置:配置name的type为nested。
同步结果:name是nested对象类型。
源端数据为string "[1,2,3,4,5]"
,如何以数组形式同步至ES中存储?
ES期望写入数组类型有两种配置方式,您可以按照源端数据形式,选择对应的同步方式进行配置。
写入ES为数组类型以JSON格式解析源端数据。例如,源端数据为"[1,2,3,4,5]",配置
json_array=true
解析源端数据,以数组形式写入ES字段,配置ColumnList为json_array=true
。向导模式配置:
脚本模式配置:
"column":[ { "name":"docs", "type":"keyword", "json_array":true } ]
写入ES为数组类型以分隔符解析源端数据。例如,源端数据为”1,2,3,4,5“,配置分隔符splitter=”,”解析以数组形式写入ES字段。
限制:
一个任务仅支持配置一种分隔符,分隔符(splitter)全局唯一,不支持多Array字段配置不同的分隔符,例如,字源端列col1="1,2,3,4,5" , col2="6-7-8-9-10", splitter无法针对每列单独配置使用。
splitter可以配置为正则,例如,源端列值为"6-,-7-,-8+,*9-,-10", 可以配置splitter:".,.",支持向导模式。
向导模式配置:splitter: 默认为"-,-"
脚本模式配置:
"parameter" : { "column": [ { "name": "col1", "array": true, "type": "long" } ], "splitter":"," }
自建的索引中nested的属性类型type为keyword,为什么自动生成之后类型会变成 keyword?(自动生成是指配置cleanup=true
执行同步任务)
#原来mappings
{
"name":"box_label_ret",
"properties":{
"box_id":{
"type":"keyword"
}
}
#cleanup=true重建之后,变成了
{
"box_label_ret": {
"properties": {
"box_id": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}}}}
}
分析原因:
对于nested类型,Elasticsearch Writer在处理的时候只采用最上层的mappings,使ES自适应下面的复合类型,属性type改成text ,添加fields:keyword 是ES自适应行为,不会影响ES的使用。如果在意这个mappings的格式,可参见数据集成侧同步任务能力说明。
解决方案:
您需要同步前先建立预期的ES索引mappings,再修改ES同步任务cleanup为false后执行同步任务。
向ES写入数据时,会做一次无用户名的提交,但仍需验证用户名,导致提交失败,因此提交的所有请求数据都被记录,导致审计日志每天都会有很多,如何处理?
分析原因:
HttpClient事先规定每次建立通信时会先走一次无权限请求,返回授权需求后(根据返回指定鉴权方式)再进行带授权请求。每次ES写入数据时需要建立通信,所以每次写入数据都会有一次无权限请求。导致每次数据写入都会记录到审计日志中。
解决方案:
您需要在脚本模式下添加
"preemptiveAuth":true
配置。
Elasticsearch writer配置了Settings,为什么在创建索引时不生效?
问题原因:
#错误配置 "settings": { "index": { "number_of_shards": 1, "number_of_replicas": 0 } } #正确配置 "settings": { "number_of_shards": 1, "number_of_replicas": 0 }
解决方案:
Settings设置只在创建索引时才会生效,创建索引包括:索引不存在和
cleanup=true
两种情况,当cleanup=true
时,Settings的配置不需要使用“index" 。
如何同步至ES中为Date日期类型?
有如下两种方式配置日期写入,您可以按需求进行选择。
根据reader端读取字段的内容直接写入ES Date字段:
配置origin:true,读取内容直接写入ES。
配置"format"表示在通过ES写入创建Mapping时,字段需要设置的format属性。
"parameter" : { "column": [ { "name": "col_date", "type": "date", "format": "yyyy-MM-dd HH:mm:ss", "origin": true } ] }
时区转换:如果需要数据集成帮助您进行时区转换,则添加Timezone参数。
"parameter" : { "column": [ { "name": "col_date", "type": "date", "format": "yyyy-MM-dd HH:mm:ss", "Timezone": "UTC" } ] }
Elasticsearch Writer指定外部version导致写入失败,如何处理?
配置了type:version,目前es不支持指定外部version功能。
"column":[ { "name":"id", "type":"version" }, ]
解决方案:
需要取消 type":"version"配置,Elasticsearch Writer暂不支持外部version指定。
非结构化数据源,单击数据预览字段无法映射,如何处理?
问题现象:
在用户单击数据预览时,出现如下提示,大致含义是字段的字节数超长。
问题原因:为了避免OOM,数据源服务在处理数据预览的请求时会判断字段的长度,如果单个列超过1000字节,则会出现上述提示,此提示并不会影响任务的正常运行,可以忽略该错误直接运行DataX任务。
说明在文件存在且连通性正常的情况下,导致数据预览失败的情况还有:
文件单行字节数超限制,限制为10MB。此时不显示数据,类似于上述提示。
文件单行列数超限制,限制为1000列。此时仅显示前1000列,并在第1001列给出提示。
MongoDB Reader是否大小写敏感?
在数据读取时,用户配置的Column.name
为大小写敏感,如配置有误,会导致读出数据为null。例如:
MongoDB源数据为:
{ "MY_NAME": "zhangsan" }
同步任务的Column配置为:
{ "column": [ { "name": "my_name" } ] }
则由于同步任务的配置与源数据大小写不一致,会导致数据读取异常。
怎么配置MongoDB Reader超时时长?
超时时长的配置参数为cursorTimeoutInMs
,默认为600000ms(10分钟),参数含义为MongoDB Server执行Query总耗时,不包含数据传输时长。若全量读取的数据较大,可能导致报错:MongoDBReader$Task - operation exceeded time limitcom.mongodb.MongoExecutionTimeoutException: operation exceeded time limit
。
MaxCompute如何实现列筛选、重排序和补空等
通过配置MaxCompute Writer,可以实现MaxCompute本身不支持的列筛选、重排序和补空等操作。例如需要导入的字段列表,当导入全部字段时,可以配置为"column": ["*"]
。
MaxCompute表有a、b和c三个字段,您只同步c和b两个字段,可以将列配置为"column": ["c","b"]
,表示会把Reader的第一列和第二列导入MaxCompute的c字段和b字段,而MaxCompute表中新插入的a字段会被置为null。
MaxCompute列配置错误的处理
为保证写入数据的可靠性,避免多余列数据丢失造成数据质量故障。对于写入多余的列,MaxCompute Writer将报错。例如MaxCompute表字段为a、b和c,如果MaxCompute Writer写入的字段多于三列,MaxCompute Writer将报错。
MaxCompute分区配置注意事项
MaxCompute Writer仅提供写入到最后一级分区的功能,不支持写入按照某个字段进行分区路由等功能。假设表一共有三级分区,在分区配置中必须指明写入至某个三级分区。例如,写入数据至一个表的第三级分区,可以配置为pt=20150101, type=1, biz=2
,但不能配置为pt=20150101, type=1
或者pt=20150101
。
MaxCompute任务重跑和failover
MaxCompute Writer通过配置"truncate": true
,保证写入的幂等性。即当出现写入失败再次运行时,MaxCompute Writer将清理前述数据,并导入新数据,以保证每次重跑之后的数据都保持一致。如果在运行过程中,因为其他的异常导致任务中断,便不能保证数据的原子性,数据不会回滚也不会自动重跑,需要您利用幂等性的特点进行重跑,以确保数据的完整性。
truncate为true的情况下,会将指定分区或表的数据全部清理,请谨慎使用。
源表有默认值,通过数据集成创建的目标表,默认值、非空属性等会保留吗?
创建目标表时候,DataWorks只会保留源表的列名、数据类型、注释等信息,不会保留源表的默认值、约束(包含非空约束、索引等)。
离线集成任务配置切分键时,联合主键是否可以作为切分键?
离线集成任务不支持将联合主键作为切分键。
向包含主键自增列的目标表写入数据,需要如何配置OTS Writer?
OTS Writer的配置中必须包含以下两条:
"newVersion": "true", "enableAutoIncrement": "true",
OTS Writer中不需要配置主键自增列的列名。
OTS Writer中配置的primaryKey条数+column条数需要等于上游OTS Reader数据的列数。
在时序模型的配置中,如何理解_tag
和is_timeseries_tag
两个字段?
示例:某条数据共有三个标签,标签为:【手机=小米,内存=8G,镜头=莱卡】。
数据导出示例(OTS Reader)
如果想将上述标签合并到一起作为一列导出,则配置为:
"column": [ { "name": "_tags", } ],
DataWorks会将标签导出为一列数据,形式如下:
["phone=xiaomi","camera=LEICA","RAM=8G"]
如果希望导出
phone
标签和camera
标签,并且每个标签单独作为一列导出,则配置为:"column": [ { "name": "phone", "is_timeseries_tag":"true", }, { "name": "camera", "is_timeseries_tag":"true", } ],
DataWorks会导出两列数据,形式如下:
xiaomi, LEICA
数据导入示例(OTS Writer)
现在上游数据源(Reader)有两列数据:
一列数据为:
["phone=xiaomi","camera=LEICA","RAM=8G"]
。另一列数据为:6499。
现希望将这两列数据都添加到标签里面,预期的写入后标签字段格式如下所示:则配置为:
"column": [ { "name": "_tags", }, { "name": "price", "is_timeseries_tag":"true", }, ],
第一列配置将
["phone=xiaomi","camera=LEICA","RAM=8G"]
整体导入标签字段。第二列配置将
price=6499
单独导入标签字段。
日期时间类型数据写入文本时,如何保留毫秒或者指定自定义日期时间格式?
同步任务转脚本模式后,在配置任务页面的"setting"部分增加以下配置项:
"common": {
"column": {
"dateFormat": "yyyyMMdd",
"datetimeFormatInNanos": "yyyyMMdd HH:mm:ss.SSS"
}
}
其中:
dateFormat表示源端DATE(不带时分秒)类型转文本时的日期格式。
datetimeFormatInNanos表示源端DATETIME/TIMESTAMP(带时分秒)类型转文本时的日期格式,最多可指定到毫秒。
报错信息及解决方案
数据同步报错:[TASK_MAX_SLOT_EXCEED]:Unable to find a gateway that meets resource requirements. 20 slots are requested, but the maximum is 16 slots.
可能原因:
设置并发数太大导致没有足够的资源。
解决方案:
减小离线同步任务的并发数设置。
如果您使用向导模式配置离线同步任务,需要调小配置通道控制中的任务期望最大并发数,详情可参见通过向导模式配置离线同步任务。
如果您使用脚本模式配置离线同步任务,需要调小配置通道控制中的concurrent参数,详情可参见通过脚本模式配置离线同步任务。
数据同步报错:OutOfMemoryError: Java heap space
出现上述报错后,您需要:
如果插件配置支持的参数中有batchsize或者maxfilesize,可以调小对应的值。
您可以查看各插件是否支持上述参数,进入支持的数据源与读写插件文档后,单击对应插件查看参数详情。
调小并发数。
如果您使用向导模式配置离线同步任务,需要调小配置通道控制中的任务期望最大并发数,详情可参见通过向导模式配置离线同步任务。
如果您使用脚本模式配置离线同步任务,需要调小配置通道控制中的concurrent参数,详情可参见通过脚本模式配置离线同步任务。
如果是文件同步,例如同步OSS文件等,请减少读取的文件数。
读取OSS数据报错:AccessDenied The bucket you access does not belong to you.
数据源配置的ak用户没有该bucket的权限,请为OSS数据源配置的ak用户授予该bucket相应权限。
写入Redis使用hash模式存储数据时,报错:Code:[RedisWriter-04], Description:[Dirty data]. - source column number is in valid!
产生原因:
Redis在使用hash模式存储时,hash的attribute和value要成对出现。例如:
odpsReader: "column":[ "id", "name", "age", "address", ]
,目标端在配置RedisWriter: "keyIndexes":[ 0 ,1],在Redis中,id和name将作为key,age将作为attribute,address将作为value存到Redis中的hash类型的Redis中,如果odps源端只配置了两列,则不可以使用hash模式去存Redis缓存,会报该异常。解决方案:
假如只想用两列,那就配置Redis的String模式去存信息,如果必须要用hash存,源端至少配置三列。
读取PostgreSQL数据报错:org.postgresql.util.PSQLException: FATAL: terminating connection due to conflict with recovery
问题场景:离线同步工具同步PostgreSQL数据时,报错如下:
org.postgresql.util.PSQLException: FATAL: terminating connection due to conflict with recovery
可能原因:出现该情况的原因是从数据库中拉取数据的时间较长,请增加max_standby_archive_delay和max_standby_streaming_delay的参数值,详情请参见Standby Server Events
写入/读取MySQL报错:Application was streaming results when the connection failed. Consider raising value of 'net_write_timeout/net_read_timeout、' on the server.
报错原因:
net_read_timeout:datax将RDS MySQL根据splitpk对MySQL的数据进行拆分成数条等量的取数sql(select取数语句),执行时某条sql执行时间超过RDS侧允许的最大运行时间。
net_write_timeout:等待将一个block发送给客户端的超时时间过小导致。
解决方案:
在数据源URL的连接上增加该参数,net_write_timeout/net_read_timeout设置稍微大一些,或者在RDS控制台调整该参数。
改进建议:
如果任务可以重跑建议设置任务自动重跑。
例如:jdbc:mysql://192.168.1.1:3306/lizi?useUnicode=true&characterEncoding=UTF8&net_write_timeout=72000
离线同步至MySQL报错:[DBUtilErrorCode-05]ErrorMessage: Code:[DBUtilErrorCode-05]Description:[往您配置的写入表中写入数据时失败.]. - com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: No operations allowed after connection closed
报错原因:
MySQL中参数wait_timeout
默认时间为8小时,当达到默认时间时,如果仍然在获取这数,会导致同步任务中断。
解决方案:
修改MySQL的配置文件my.cnf(Windows系统下是my.ini),在MySQL模块下面加上参数单位(秒),设置为:wait_timeout=2592000 interactive_timeout=2592000
,再重启登录MySQL,输入如下语句:show variables like ‘%wait_time%’
,查看是否设置成功。
读取MySQL数据库报错:The last packet successfully received from the server was 902,138 milliseconds ago
CPU使用正常,内存使用较高可能导致连接被断开。
如果您确认可以自动重跑的话,建议您设置任务出错自动重跑,详情参考文档:时间属性配置说明
离线同步报错:Communications link failure
读取报错
问题现象:
读取数据时,报错如下:
Communications link failure The last packet successfully received from the server was 7,200,100 milliseconds ago. The last packet sent successfully to the server was 7,200,100 milliseconds ago. - com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure
可能原因:
数据库执行SQL查询速度慢,导致MySQL读超时。
解决方法:
排查是否设置了where过滤条件,以确保筛选字段已添加索引。
排查源数据表的数据是否太多。如果数据太多,建议拆分为多个任务。
查询日志找到执行阻塞的SQL,咨询数据库管理员解决。
写入报错
问题现象:
写入数据时,报错如下:
Caused by: java.util.concurrent.ExecutionException: ERR-CODE: [TDDL-4614][ERR_EXECUTE_ON_MYSQL] Error occurs when execute on GROUP 'xxx' ATOM 'dockerxxxxx_xxxx_trace_shard_xxxx': Communications link failure The last packet successfully received from the server was 12,672 milliseconds ago. The last packet sent successfully to the server was 12,013 milliseconds ago. More...
可能原因:
慢查询导致SocketTimeout。TDDL默认连接数据的SocketTimeout是12秒,如果一个SQL在MySQL端执行超过12秒仍未返回,会报4614的错误。当数据量较大或服务端繁忙时,会偶尔出现该错误。
解决方法:
建议数据库稳定后,重新运行同步任务。
联系数据库管理员调整该超时时间。
离线同步报错:Duplicate entry 'xxx' for key 'uk_uk_op'
报错现象:
Error updating database. Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry 'cfc68cd0048101467588e97e83ffd7a8-0' for key 'uk_uk_op'
。可能原因:数据集成同步任务不允许同一时间运行相同节点的不同实例(即相同JSON配置的同步任务不能同一时间运行多个,例如5分钟为周期的同步任务,由于上游延迟,在0点5分时调起了原本0点0分的实例和0点5分的实例,这样会导致其中一个实例无法调起,或者任务实例在运行时又进行了补数据、重跑等操作)。
解决方案:错开实例运行时间,如果为小时任务建议设置自依赖。
离线同步报错:plugin xx does not specify column
出现上述报错,有可能是因为同步任务的字段映射配置不正确,或者是插件没有正确配置column。
检查是否有做字段映射。
检查插件是否有正确配置column。
读取MaxCompute(ODPS)表数据报错:The download session is expired.
报错现象:
Code:DATAX_R_ODPS_005:读取ODPS数据失败, Solution:[请联系ODPS管理员]. RequestId=202012091137444331f60b08cda1d9, ErrorCode=StatusConflict, ErrorMessage=The download session is expired.
可能原因:
离线同步读取MaxCompute数据时,使用的是MaxCompute的tunnel命令来进行上传下载数据。Tunnel的Session在服务端的生命周期为24小时,所以离线同步任务如果执行超过24小时任务会失败退出,关于tunnel介绍详情请参见使用说明。
解决方案:
您可以适当调大离线同步任务并发数,合理规划同步的数据量确保任务在24小时内同步完成。
写入MaxCompute(ODPS)报错block失败:Error writing request body to server
报错现象:
Code:[OdpsWriter-09], Description:[写入数据到 ODPS 目的表失败.]. - ODPS 目的表写 block:0 失败, uploadId=[202012081517026537dc0b0160354b]. 请联系 ODPS 管理员处理. - java.io.IOException: Error writing request body to server。
可能原因:
可能原因1:数据类型异常,即来源数据不符合odps数据类型规范。比如4.2223这个数据值写入odps的decimal(18,10)数据类型的场景。
可能原因2:odps块/通信异常等
解决方案:
请转换数据类型,使用符合数据类型规范的数据。
RestAPI Writer报错:通过path:[] 找到的JSON串格式不是数组类型
RestAPI Writer提供两种写入模式,当同步多条数据的时候需要将dataMode配置为multiData,详情请参见RestAPI Writer,同时需要在RestAPI Writer脚本中新增参数dataPath:"data.list"。
配置Column时不需要加“data.list ”前缀。
离线同步源端是亚马逊的RDS时报错:Host is blocked
连接亚马逊的RDS返回Host is blocked
时,您需要关闭亚马逊负载均衡健康检查,关闭后就不会再报出block问题。
读取MongoDB报错:no master
目前DataWorks同步任务暂不支持从库读取数据, 如果您配置从库读取,将会报该错误:no master
。
读取MongoDB报错:MongoExecutionTimeoutException: operation exceeded time limit
分析原因:
游标超时引起。
解决方法:
调大参数cursorTimeoutInMs的值。
离线同步读取MongoDB报错:DataXException: operation exceeded time limit
需要通过增大任务并发数和读取的BatchSize数。
离线同步读取Elasticsearch报错:ERROR ESReaderUtil - ES_MISSING_DATE_FORMAT, Unknown date value. please add "dataFormat". sample value:
分析原因:
Elasticsearch Reader无法对date类型字段日期格式解析,因为对应es数据源中有date字段的mapping没有配置format。
解决方法:
配置dateFomat参数,格式与ES date字段的format相同,采用“||”进行分隔,format需要包含所用date类型的格式。如下所示:
"parameter" : { "column": [ "dateCol1", "dateCol2", "otherCol" ], "dateFormat" : "yyyy-MM-dd||yyyy-MM-dd HH:mm:ss", }
将ES数据库中的所有date字段,mapping设置为format格式。
离线同步读取Elasticsearch报错:com.alibaba.datax.common.exception.DataXException: Code:[Common-00], Describe:[您提供的配置文件存在错误信息,请检查您的作业配置 .] - 配置信息错误. 您提供的配置信息不是合法的JSON格式: illegal ref, [ . 请按照标准json格式提供配置信息.
分析原因:
受fastjson关键字的限制,可能在索引或者列中存在$ref这类关键字。
解决方法:
Elasticsearch Reader暂不支持同步字段中带有关键字$ref的索引,详情请参见Elasticsearch Reader。
离线同步写入Elasticsearch报错:version_conflict_engine_exception.
分析原因:
触发了ES的乐观锁的机制,当前版本号应该是xxx,但是更新命令传过来的版本号是另一个,所以才会出现版本冲突,update的时候,同时有人在删索引数据。
解决方案:
检查确认是否有删数据的行为。
任务同步方式将Update写改为Index。
离线同步写入Elasticsearch报错:illegal_argument_exception.
分析原因:
Column字段在配置similarity、properties等高级属性时,需要other_params才能让插件识别。
解决方案:
Column里配置
other_params
,other_params
里增加similarity,如下所示:{"name":"dim2_name",...,"other_params":{"similarity":"len_similarity"}}
ODPS Array字段类型数据离线同步至ElasticSearch报错:dense_vector
分析原因:
目前离线同步写入ElasticSearch不支暂不支持
dense_vector
类型,类型,仅支持如下类型:ID,PARENT,ROUTING,VERSION,STRING,TEXT,KEYWORD,LONG, INTEGER,SHORT,BYTE,DOUBLE,FLOAT,DATE,BOOLEAN,BINARY, INTEGER_RANGE,FLOAT_RANGE,LONG_RANGE,DOUBLE_RANGE,DATE_RANGE, GEO_POINT,GEO_SHAPE,IP,IP_RANGE,COMPLETION,TOKEN_COUNT,OBJECT,NESTED;
解决方案:
针对ElasticSearch writer不支持的类型,处理方式如下:
不建议使用ElasticSearch writer建立索引mapping,需要使用客户自建的mapping。
对应的类型改成NESTED。
修改配置为:
dynamic = true
,cleanup=false
。
离线同步数据至本地Hive报错:Could not get block locations.
分析原因:
可能存在mapred.task.timeout参数设置时间过短,Hadoop将任务终止,并清理临时目录,则后续将找不到临时数据。
解决方案:
可以调大mapred.task.timeout参数值。
MongoDB同步任务运行报错:no such cmd splitVector
可能原因:
在同步任务运行时,默认优先使用
splitVector
命令进行任务分片,在部分MongoDB版本中,不支持splitVector
命令,进而会导致报错no such cmd splitVector
。解决方案:
进入同步任务配置页面后,单击顶部的转换脚本按钮。将任务修改为脚本模式。
在MongoDB的parameter配置中,增加参数
"useSplitVector" : false
以避免使用
splitVector
。
MongoDB离线同步报错:After applying the update, the (immutable) field '_id' was found to have been altered to _id: "2"
报错现象:
同步任务中,以向导模式为例,当配置了写入模式(是否覆盖)为是,且配置了非
_id
字段作为业务主键,可能会出现此问题。可能原因:
写入数据中,存在_id与配置的业务主键(如上述配置示例的
my_id
)不匹配的数据。解决方案:
方案一:修改离线同步任务,确保配置的业务主键与_id一致。
方案二:进行数据同步时,将_id作为业务主键。
离线任务,运行报错:MongoDBReader$Task - operation exceeded time limitcom.mongodb.MongoExecutionTimeoutException: operation exceeded time limit.
报错内容:数据同步任务时,任务运行失败,错误提示为
MongoDBReader$Task - operation exceeded time limitcom.mongodb.MongoExecutionTimeoutException: operation exceeded time limit
。可能原因:全量拉取数据过大导致的。
如何处理:
加大并发。
减小BatchSize。
Reader端parameter参数中,增加
cursorTimeoutInMs
配置,可以尝试设置大些,例如3600000ms。