本文共 12425 字,大约阅读时间需要 41 分钟。
A:目前Tunnel是无法自动上传数据并自动分配到各个分区的:每一次上传只支持数据上传到一张表或表的一个分区,有分区的表一定要指定上传的分区,多级分区一定要指定到末级分区。关于JAVA SDK可参考:。
A:分区需要首先创建好,在使用SDK上传数据时指定。您也可以先把数据上传到MaxCompute上的表中,再用SQL语句动态分区。
tunnel upload D:\test test/pt="time"
在 DataIDE上进行分区上传为什么报错:FAILED: error occurred while running tunnel command
?A:DataIDE是不支持MaxCompute Tunnel命令行工具的upload语句的。
A:Block 的概念:一个 block 对应一个HTTP request,多个 block 的上传可以并发而且是原子的,一次同步请求要么成功要么失败,不会污染其他的 block。
重传retry有次数的限制的,当重传的次数超过了这个限制,就会继续上传下一个block。上传完成后,可以通过select count(*)
语句,检查是否有数据丢失。 A:Tunnel Upload命令上传是不设速度限制的。上传速度的瓶颈在网络带宽以及服务器性能。为了提升性能,可以考虑分区分表,在多台ECS上传下载数据。
/odpscmd/bin/odpscmd
tunnel upload "$FILE" project.table
A:可参考设置命令行客户端的启动参数,在Shell中启动命令是:
/odpscmd/bin/odpscmd -e “tunnel upload "$FILE" project.table”
A:如果数据里有回车或空格,可以给数据设置不同与回车或空格的分隔符后,用-rd和-fd指定对应的分隔符实现数据的上传。如果无法更换数据中的分隔符,可以将数据作为单独一行上传,然后使用UDF解析。
例如下列数据中包含回车,使用“,”作为列分隔符rd,使用“@”作为行分隔符fd,可以正常上传:数据内容:shopx,x_id,100@shopy,y_id,200@shopz,z_id,300@
上传命令:
odps@ MaxCompute_DOC>tunnel u d:\data.txt sale_detail/sale_date=201312,region=hangzhou -s false -fd "," -rd "@";
上传结果:
+-----------+-------------+-------------+-----------+--------+| shop_name | customer_id | total_price | sale_date | region |+-----------+-------------+-------------+-----------+--------+| shopx | x_id | 100.0 | 201312 | hangzhou || shopy | y_id | 200.0 | 201312 | hangzhou || shopz | z_idd | 300.0 | 201312 | hangzhou |+-----------+-------------+-------------+-----------+--------+
A:如果数据描述字段内本身有逗号,可以考虑转换数据的分隔符为其他符号,再通过-fd
指定为其他分隔符进行上传,举例如下:
完成设置后,使用EXCEL将数据另存为CSV文件,并且利用Notepad++等文本编辑工具转码为UTF-8编码(Tunnel默认使用的编码格式),检查是否文件分隔符已变成“$”:
标题$所在地$薪资$公司$公司介绍链接$公司类型$公司规模$所属行业$工作经验$学历$所招人数$发布时间$标签$职位信息$上班地址$公司信息$页面网址$采集时间
使用TunnelUpload命令上传数据并指定分隔符(需预先在MaxCompute上创建好表格),即可成功上传:
odps@ MaxCompute_DOC>tunnel u d:\12JD.CSV JD2 -s false -fd "$";Upload session: 201808201531180d47df0b0b18fa45Start upload:d:\12JD.CSVUsing \r\n to split recordsUpload in strict schema mode: trueTotal bytes:111028 Split input to 1 blocks2018-08-20 15:31:18 upload block: '1'2018-08-20 15:31:18 upload block complete, blockid=1upload complete, average speed is 108.4 KB/sOK
A:CSV文件使用其他分隔符,可以通过 -fd参数指定。
通常来说,如果数据例有很多符号,可能与分隔符发生冲突,可以自定义数据中分隔符来避免冲突,比如$#@$@ 或者)$*#@$@$。java.lang.OutOfMemoryError:Java heap space
是什么原因?A:从报错上看是数据上传的时候的内存溢出了。目前TunnelUpload命令是支持海量数据的上传的,如果出现内存溢出,可能是因为数据的行分隔符和列分隔符设置错误,导致整个文本会被认为是同一条数据,缓存到内存里再做split,导致内存溢出报错。
这种情况下可以先拿少量的数据测试,把-td及-fd调试过了后再上传拿全量的数据。A:TunnelUpload命令上传支持文件或目录(指一级目录)的上传。
例如下述命令,上传数据为文件夹d:data,上传命令为:odps@ MaxCompute_DOC>tunnel u d:\data sale_detail/sale_date=201312,region=hangzhou -s false;
详情请参见。 colum mismatch
,但是这个文件夹下的文件单独导入时又是可以导入的,是因为文件太大吗?A:这种情况下,可以在upload命令后加上-dbr=false -s true
对数据格式进行验证。出现column mismatch通常是由于列数对不上导致的:可能性较大的原因包括列分隔符设置的不对或文件的最后有空行,导致空行进行分隔符分割的时候分不出那么多列。
D:\odps\bin\odpscmd.bat -e"tunnel upload d:\data1.txt sale_detail/sale_data=201312 -fd="$" -mbr=5 --scan=true; "
D:\odps\bin\odpscmd.bat -e"tunnel upload d:\data2.txt sale_detail/sale_data=201312 -fd="$" -mbr=5 --scan=true; "
A:当使用老版本MaxCompute命令行客户端,上传参数有--scan
的时候,续跑模式的参数传递有问题,将--scan=true
去掉重试即可。
tunnel upload /data/2018/20180813/*.json app_log /dt=20180813 -fd '@@' -acp true;
,执行报错:Unrecognized option: -acpFAILED: error occurred while running tunnel command
A:出现这种报错通常是因为是用了不支持的命令或字符。MaxCompute使用Tunnel Upload命令上传不支持通配符及正则表达式。
A:出现这种错误是因为数据格式问题,例如数据类型不对,可参考,使用-dbr true
参数忽略脏数据(多列,少列,列数据类型不匹配等情况)。-dbr参数默认用false,表示不忽视脏数据,当值为true时,将不符合表定义的数据全部忽略。
java.io.IOException: RequestId=XXXXXXXXXXXXXXXXXXXXXXXXX, ErrorCode=StatusConflict, ErrorMessage=You cannot complete the specified operation under the current upload or download status. at com.aliyun.odps.tunnel.io.TunnelRecordWriter.close(TunnelRecordWriter.java:93) at com.xgoods.utils.aliyun.maxcompute.OdpsTunnel.upload(OdpsTunnel.java:92) at com.xgoods.utils.aliyun.maxcompute.OdpsTunnel.upload(OdpsTunnel.java:45) at com.xeshop.task.SaleStatFeedTask.doWork(SaleStatFeedTask.java:119) at com.xgoods.main.AbstractTool.excute(AbstractTool.java:90) at com.xeshop.task.SaleStatFeedTask.main(SaleStatFeedTask.java:305)
A:这个错误的提示是当前已经是在上传或下载中,所以无法再操作。
RequestId=20170116xxxxxxx, ErrorCode=StatusConflict, ErrorMessage=You cannot complete the specified operation under the current upload or download status. java.io.IOException: RequestId=20170116xxxxxxx, ErrorCode=StatusConflict, ErrorMessage=You cannot complete the specified operation under the current upload or download status.at com.aliyun.odps.tunnel.io.TunnelRecordWriter.close(TunnelRecordWriter.java:93)
A:由上述报错可见,这个问题是在准备close这个writer时出现的,可能有以下几种情况:
A:Jar包不能超过10M, 如果Jar超过10M,建议转用MaxCompute Tunnel Upload命令行上传数据。
A:Tunnel Upload命令行通常不会限制需上传的数据大小。
A:建议使用-h true
参数,跳过table header.
A:使用Tunnel批量数据通道SDK来导入MaxCompute数据库。目前支持的是6万个分区。
分区数量过多,会给统计和分析带来极大的不便。MaxCompute会限制单个作业中最多不能超过一定数量的instance。作业的instance和用户输入的数据量和分区数量是密切相关的,所以建议首先评估下业务,选择合适的分区策略,避免分区过多带来的影响。关于分区表的更多信息请参考。此外,MaxCompute也支持通过Python SDK来进行Tunnel批量上传,请参考中的数据上传/下载配置。odps tunnel recordWriter.close()
时报错,报错内容如下:ErrorCode=StatusConflict, ErrorMessage=You cannot complete the specified operation under the current upload or download status.
A:这个报错说明session的状态错误,建议重新创建个session重新上传一下数据。从报错上看,很可能是前面的操作里已经close了这个session,或者已经commit了。对于不同的分区,需要每个分区都是单独的一个session。
为了防止多次commit导致的这种报错,可以先检查数据上传是否已经传成功,如果失败的话重新上传一次。可参考。A:MaxCompute Java SDK在0.21.3-public版本之后新增了BufferredWriter的SDK,简化了数据上传,并且提供了容错功能。
BufferedWriter对用户隐藏了block的概念:从用户角度看,就是在session上打开一个writer然后进行写记录即可。具体实现时,BufferedWriter先将记录缓存在客户端的缓冲区中,并在缓冲区填满之后打开一个http连接进行上传。BufferedWriter会尽最大可能容错,保证数据上传上去。使用方法请参考。A:这种情况很可能是因为数据编码格式不对导致上传到表的数据不对,或者是分隔符使用错误。建议规范原始数据后上传.
A:可以shell脚本方式执行Tunnel Upload命令行上传实现。可通过/odpscmd/bin/odpscmd -e
执行脚本,并在脚本内粘贴表格配置。
A:
小文件产生的原因:MaxCompute使用的分布式文件系统是按块Block存放,通常文件大小比块大小小的文件(默认块大小为64M),叫做小文件。目前MaxCompute有以下场景可以产生小文件:小文件过多会带来以下影响:
查看表中的小文件数量命令:
desc extended + 表名
小文件处理方式
不同原因产生的小文件,需要有不同的处理方法:(1)Reduce过程中产生的小文件使用insert overwrite源表(或分区),或者写入到新表删除源表。(2)Tunnel数据采集过程中产生的小文件ALTER合并模式,通过命令行进行合并:set odps.merge.cross.paths=true;set odps.merge.max.partition.count=100; --默认优化10个分区,此时设置为优化100个分区。ALTER TABLE tablename [PARTITION] MERGE SMALLFILES;
A:Tunnel Upload命令行不支持正则表达式。如果数据使用空格作为列分隔符,或需要对数据做正则表达式过滤时可借助MaxCompute的UDF自定义函数功能。
首先,将数据作为单列数据上传。本例中原始数据如下,列分割符为空格,行分隔符为回车,并且需要取的部分数据在引号内,部分数据例如"-"需要被过滤。这种复杂的需求可通过正则表达式实现。10.21.17.2 [24/Jul/2018:00:00:00 +0800] - "GET https://help.aliyun.com/document_detail/73477.html" 200 0 81615 81615 "-" "iphone" - HIT - - 0_0_0 001 - - - -10.17.5.23 [24/Jul/2018:00:00:00 +0800] - "GET https://help.aliyun.com/document_detail/73478.html" 206 0 49369 49369 "-" "huawei" - HIT - - 0_0_0 002 - - - -10.24.7.16 [24/Jul/2018:00:00:00 +0800] - "GET https://help.aliyun.com/document_detail/73479.html" 206 0 83821 83821 "-" "vivo" - HIT - - 0_0_0 003 - - - -
为使数据单列上传,首先在MaxCompute项目空间内创建一个单列的表格用于接收数据:
odps@ bigdata_DOC>create table userlog1(data string);
使用一个不存在的列分隔符 "u0000"上传数据,从而达到不分割列的效果:odps@ bigdata_DOC>tunnel upload C:\userlog.txt userlog1 -s false -fd "\u0000" -rd "\n";
完成原始数据上传后,使用MaxCompute IntelliJ IDEA编写一个Python UDF(您也可以使用JAVA UDF,注意使用Python UDF需提交工单申请权限),详情可参见。使用代码如下: from odps.udf import annotatefrom odps.udf import BaseUDTFimport re #此处引入正则函数regex = '([(\d\.)]+) \[(.*?)\] - "(.*?)" (\d+) (\d+) (\d+) (\d+) "-" "(.*?)" - (.*?) - - (.*?) (.*?) - - - -' #使用的正则表达式# line -> ip,date,request,code,c1,c2,c3,ua,q1,q2,q3@annotate('string -> string,string,string,string,string,string,string,string,string,string,string') #请注意string数量和真实数据保持一致,本例中有11列。class ParseAccessLog(BaseUDTF): def process(self, line): try: t = re.match(regex, line).groups() self.forward(t[0], t[1], t[2], t[3], t[4], t[5], t[6], t[7], t[8], t[9], t[10]) except: pass
完成函数的编写后,选择上传代码。
上传时请注意选择当前使用的项目。
完成上传后,注册函数并填写函数名称,本例中函数名称为ParseAccessLog。
函数上传完成后,就可以使用编写的UDF函数处理上传到表格userlog1的原始数据了,注意不要写错列的名称,本例中为data。您可以使用正常的SQL语法,新建一个表格userlog2用于存放处理后的数据。
odps@ bigdata_DOC>create table userlog2 as select ParseAccessLog(data) as (ip,date,request,code,c1,c2,c3,ua,q1,q2,q3) from userlog1;
完成处理后,可以观察到目标表已创建,数据成功分列。
+----+------+---------+------+----+----+----+----+----+----+----+| ip | date | request | code | c1 | c2 | c3 | ua | q1 | q2 | q3 |+----+------+---------+------+----+----+----+----+----+----+----+| 10.21.17.2 | 24/Jul/2018:00:00:00 +0800 | GET https://help.aliyun.com/document_detail/73477.html | 200 | 0 | 81615 | 81615 | iphone | HIT | 0_0_0 | 001 || 10.17.5.23 | 24/Jul/2018:00:00:00 +0800 | GET https://help.aliyun.com/document_detail/73478.html | 206 | 0 | 4936 | 4936 | huawei | HIT | 0_0_0 | 002 || 10.24.7.16 | 24/Jul/2018:00:00:00 +0800 | GET https://help.aliyun.com/document_detail/73479.html | 206 | 0 | 83821 | 83821 | vivo | HIT | 0_0_0 | 003 |+----+------+---------+------+----+----+----+----+----+----+----+
java.io.IOException: Error writing request body to server
?A:这是一个上传数据到服务器的时的异常,通常是因为上传过程中的网络链接断开/超时导致的:
解决方法:
A:配置文件odps_config.ini里除了endpoint之外还需要配置tunnel_endpoint。请参考进行配置。目前只有上海region不需要设置tunnel endpoint
A:目前MaxCompute使用Tunne lUpload命令行不支持限速,需要通过SDK单独处理。
A:如果上传数据太慢,可以考虑使用-threads参数将数据切片上传,例如将文件切分为10片上传:odps@ bigdata_DOC>tunnel upload C:\userlog.txt userlog1 -threads 10 -s false -fd "\u0000" -rd "\n";
A:按照Tunnel压缩后的带宽进行计费。
转载地址:http://fiukx.baihongyu.com/