MaxCompute Tunnel上传典型问题场景

摘要: 关于MaxCompute Tunnel上传的全部问题,您想知道的都在这里,持续更新哦!若是您有任何疑惑和需求,欢迎留言!html

数据问题
Q:使用Tunnel Java SDK上传数据,上传数据能够自动分配到各个分区吗?
A:目前Tunnel是没法自动上传数据并自动分配到各个分区的:每一次上传只支持数据上传到一张表或表的一个分区,有分区的表必定要指定上传的分区,多级分区必定要指定到末级分区。关于JAVA SDK可参考:Java SDK。java

Q:使用Tunnel Java SDK上传数据,若是是分区表,SDK可以动态根据数据建立不一样的分区吗?
A:分区须要首先建立好,在使用SDK上传数据时指定。您也能够先把数据上传到MaxCompute上的表中,再用SQL语句动态分区。正则表达式

Q:使用Tunnel命令行tunnel upload D:test test/pt="time" 在 DataIDE上进行分区上传为何报错:FAILED: error occurred while running tunnel command?
A:DataIDE是不支持MaxCompute Tunnel命令行工具的upload语句的。shell

Q:利用Tunnel命令行工具上传数据时,共分为50个block,开始一切正常,可是在第22个block时,出现Upload fail,retry 5次后,直接跳过开始上传第23个block,为何会发生这种状况?
A:Block 的概念:一个 block 对应一个HTTP request,多个 block 的上传能够并发并且是原子的,一次同步请求要么成功要么失败,不会污染其余的 block。
重传retry有次数的限制的,当重传的次数超过了这个限制,就会继续上传下一个block。上传完成后,能够经过select count(*)语句,检查是否有数据丢失。数据库

Q:本地服务器天天采集的网站日志有10GB,须要上传至MaxCompute,在使用Tunnel Upload命令上传达到的速度约300KB/S 如何提高上传速度?
A:Tunnel Upload命令上传是不设速度限制的。上传速度的瓶颈在网络带宽以及服务器性能。为了提高性能,能够考虑分区分表,在多台ECS上传下载数据。json

Q:如何在Shell脚本中将一个TXT文件中的数据上传到MaxCompute的表中, 即把这两条命令组合成一条?命令以下:
/odpscmd/bin/odpscmd缓存

tunnel upload "$FILE" project.table服务器

A:可参考客户端设置命令行客户端的启动参数,在Shell中启动命令是:
/odpscmd/bin/odpscmd -e “tunnel upload "$FILE" project.table”网络

Q:MaxCompute使用TunnelUpload命令上传数据,若是数据里面有回车或空格为何上传失败?
A:若是数据里有回车或空格,能够给数据设置不一样与回车或空格的分隔符后,用-rd和-fd指定对应的分隔符实现数据的上传。若是没法更换数据中的分隔符,能够将数据做为单独一行上传,而后使用UDF解析。session

例以下列数据中包含回车,使用“,”做为列分隔符rd,使用“@”做为行分隔符fd,能够正常上传:

数据内容:

shopx,x_id,100@
shopy,y_id,200@
shopz,z_i
d,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_id
d 300.0 201312 hangzhou
Q:MaxCompute使用TunnelUpload命令上传数据,使用的","进行列分割, 如今description字段里, 数据有逗号, 或者" "符号, 这种状况怎么分割?

A:若是数据描述字段内自己有逗号,能够考虑转换数据的分隔符为其余符号,再经过-fd指定为其余分隔符进行上传,举例以下:

用户有一个岗位需求的EXCEL数据在Windows环境下须要经过Tunnel Upload命令上传,表格内自己包含“,”。首先可经过Windows环境设置EXCEL转换为CSV文件的默认分隔符:Win7系统在控制面板 时钟、语言和区域 选择 更改日期、时间或数字格式,点击其余设置。本例中考虑到原始数据中没有“字符,设置分隔符为”字符,设置分隔符为“”,以下图所示:

图片描述

完成设置后,使用EXCEL将数据另存为CSV文件,而且利用Notepad++等文本编辑工具转码为UTF-8编码(Tunnel默认使用的编码格式),检查是否文件分隔符已变成“$”:

标题$所在地$薪资$公司$公司介绍连接$公司类型$公司规模$所属行业$工做经验$学历$所招人数$发布时间$标签$职位信息$上班地址$公司信息$页面网址$采集时间

使用TunnelUpload命令上传数据并指定分隔符(需预先在MaxCompute上建立好表格),便可成功上传:

odps@ MaxCompute_DOC>tunnel u d:12JD.CSV JD2 -s false -fd "$";
Upload session: 201808201531180d47df0b0b18fa45
Start upload:d:12JD.CSV
Using rn to split records
Upload in strict schema mode: true
Total bytes:111028 Split input to 1 blocks
2018-08-20 15:31:18 upload block: '1'
2018-08-20 15:31:18 upload block complete, blockid=1
upload complete, average speed is 108.4 KB/s
OK
Q:MaxCompute使用Tunnel Upload命令上传数据。Tunnel Upload命令默认使用逗号分割的,但数据CSV文件也是用逗号分割的:文件里面有一列数据里面自己就含有用引号引发来的逗号。这种状况如何处理?
A:CSV文件使用其余分隔符,能够经过 -fd参数指定。

一般来讲,若是数据例有不少符号,可能与分隔符发生冲突,能够自定义数据中分隔符来避免冲突,好比#@#@@ 或者)#@#@@$。

Q:MaxCompute使用Tunnel Upload命令上传数据时失败,内存溢出报错java.lang.OutOfMemoryError:Java heap space是什么缘由?
图片描述

A:从报错上看是数据上传的时候的内存溢出了。目前TunnelUpload命令是支持海量数据的上传的,若是出现内存溢出,多是由于数据的行分隔符和列分隔符设置错误,致使整个文本会被认为是同一条数据,缓存到内存里再作split,致使内存溢出报错。

这种状况下能够先拿少许的数据测试,把-td及-fd调试过了后再上传拿全量的数据。

Q:MaxCompute使用Tunnel Upload命令上传数据,须要上传不少个数据文件到一个表中,是否有方法写一个脚本就能够把文件夹下的全部数据文件循环上传上去?
A:TunnelUpload命令上传支持文件或目录(指一级目录)的上传。

例以下述命令,上传数据为文件夹d:data,上传命令为:

odps@ MaxCompute_DOC>tunnel u d:data sale_detail/sale_date=201312,region=hangzhou -s false;

详情请参见Tunnel命令操做。

Q:导入文件夹会报错:字段不匹配colum mismatch,可是这个文件夹下的文件单独导入时又是能够导入的,是由于文件太大吗?
图片描述

A:这种状况下,能够在upload命令后加上-dbr=false -s true对数据格式进行验证。出现column mismatch一般是因为列数对不上致使的:可能性较大的缘由包括列分隔符设置的不对或文件的最后有空行,致使空行进行分隔符分割的时候分不出那么多列。

Q:MaxCompute使用Tunnel Upload命令上传两个文件,上传完第一个文件命令结束以后,第二个文件不会上传是什么缘由?没有报错信息,就是第一个文件上传以后第二个文件上传命令不执行了。上传命令以下:
D:odpsbinodpscmd.bat -e"tunnel upload d:data1.txt sale_detail/sale_data=201312 -fd="$" -mbr=5 --scan=true; "

D:odpsbinodpscmd.bat -e"tunnel upload d:data2.txt sale_detail/sale_data=201312 -fd="$" -mbr=5 --scan=true; "

A:当使用老版本MaxCompute命令行客户端,上传参数有--scan的时候,续跑模式的参数传递有问题,将--scan=true 去掉重试便可。

Q:MaxCompute使用Tunnel Upload命令把一个目录下的全部文件上传到一个表里,而且想要自动创建分区,具体的命令是 tunnel upload /data/2018/20180813/*.json app_log /dt=20180813 -fd '@@' -acp true; ,执行报错:
Unrecognized option: -acp
FAILED: error occurred while running tunnel command
A:出现这种报错一般是由于是用了不支持的命令或字符。MaxCompute使用Tunnel Upload命令上传不支持通配符及正则表达式。

Q:MaxCompute使用Tunnel Upload命令上传文件数据报错,是否有像MySQL的-f的强制跳过错误数据继续进行上传的命令?
A:出现这种错误是由于数据格式问题,例如数据类型不对,可参考Tunnel命令操做,使用-dbr true参数忽略脏数据(多列,少列,列数据类型不匹配等状况)。-dbr参数默认用false,表示不忽视脏数据,当值为true时,将不符合表定义的数据所有忽略。

Q:MaxCompute使用Tunnel Upload命令上传文件数据报错以下是为何?
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:这个错误的提示是当前已是在上传或下载中,因此没法再操做。

Q:MaxCompute使用Tunnel SDK上传文件数据报错重复提交是为何?
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时出现的,可能有如下几种状况:

对一个已经关闭的writer作了关闭操做。
这个writer对应的session已经关闭。
该session已经被提交过。

能够针对上述可能出现的缘由进行排查,好比打印当前writer和session的状态。
Q:MaxCompute使用Tunnel SDK上传数据时,编写完UDF打成Jar包后上传,对Jar包大小有要求吗?
A:Jar包不能超过10M, 若是Jar超过10M,建议转用MaxCompute Tunnel Upload命令行上传数据。

Q:MaxCompute使用Tunnel Upload命令行上传数据,对数据大小有限制吗?
A:Tunnel Upload命令行一般不会限制需上传的数据大小。

Q:MaxCompute使用Tunnel Upload命令行上传CSV文件,如何跳过第一行表头上传其余数据?
A:建议使用-h true参数,跳过table header.

Q:使用Tunnel批量数据通道SDK来导入MaxCompute数据库是否有分区限制?
A:使用Tunnel批量数据通道SDK来导入MaxCompute数据库。目前支持的是6万个分区。

分区数量过多,会给统计和分析带来极大的不便。MaxCompute会限制单个做业中最多不能超过必定数量的instance。做业的instance和用户输入的数据量和分区数量是密切相关的,因此建议首先评估下业务,选择合适的分区策略,避免分区过多带来的影响。

关于分区表的更多信息请参考分区。

此外,MaxCompute也支持经过Python SDK来进行Tunnel批量上传,请参考Python SDK中的数据上传/下载配置。

Q:要一次性上传8000W的数据,最后在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致使的这种报错,能够先检查数据上传是否已经传成功,若是失败的话从新上传一次。可参考多线程上传示例。

Q:如何使用TunnelBufferedWriter规避使用Tunnel SDK进行批量数据上传出错的问题?
A:MaxCompute Java SDK在0.21.3-public版本以后新增了BufferredWriter的SDK,简化了数据上传,而且提供了容错功能。

BufferedWriter对用户隐藏了block的概念:从用户角度看,就是在session上打开一个writer而后进行写记录便可。具体实现时,BufferedWriter先将记录缓存在客户端的缓冲区中,并在缓冲区填满以后打开一个http链接进行上传。

BufferedWriter会尽最大可能容错,保证数据上传上去。使用方法请参考BufferedWriter使用指南。

Q:MaxCompute使用TunnelUpload命令行上传CSV文件,为何导入成功后原文本中有很大一部份内容莫名消失,被“ - ”取代?
A:这种状况极可能是由于数据编码格式不对致使上传到表的数据不对,或者是分隔符使用错误。建议规范原始数据后上传.

Q:MaxCompute使用Tunnel Upload命令行上传是否支持引用一个表的配置?
A:能够shell脚本方式执行Tunnel Upload命令行上传实现。可经过/odpscmd/bin/odpscmd -e执行脚本,并在脚本内粘贴表格配置。

Q:MaxCompute使用Tunnel SDK上传数据时,常常会发现Select查询慢,SQL语句的执行性能很差的状况。
遇到相似状况,可能缘由是MaxCompute小文件过多,从而影响性能致使的。如何处理小文件过多的问题?
A:
小文件产生的缘由:

MaxCompute使用的分布式文件系统是按块Block存放,一般文件大小比块大小小的文件(默认块大小为64M),叫作小文件。

目前MaxCompute有如下场景能够产生小文件:

Reduce计算过程会产生大量小文件;
Tunnel数据采集过程当中会生成小文件;
Job执行过程当中生成的各类临时文件、回收站保留的过时的文件等,主要分类为:
TABLE_BACKUP:回收站中超过保留天数的表
FUXI_JOB_TMP:做业运行临时目录
TMP_TABLE:做业运行中产生的临时表
INSTANCE:做业运行时保留在meta表中的日志
LIFECYCLE:超过生命周期的的数据表或分区
INSTANCEPROFILE:做业提交及执行完成后的profile信息
VOLUME_TMP:没有meta信息,但在pangu上有路径的数据
TEMPRESOURCE:用户自定义函数使用的一次性临时资源文件
FAILOVER:系统发生failover时保留的临时文件
小文件过多会带来如下影响:

影响Map Instance性能:默认状况下一个小文件对应一个instance,形成浪费资源,影响总体的执行性能。
过多的小文件给分布式文件系统带来压力,且影响空间的有效利用,严重时会直接致使文件系统不可用。
查看表中的小文件数量命令:

desc extended + 表名

小文件处理方式
不一样缘由产生的小文件,须要有不一样的处理方法:

(1)Reduce过程当中产生的小文件

使用insert overwrite源表(或分区),或者写入到新表删除源表。

(2)Tunnel数据采集过程当中产生的小文件

调用Tunnel SDK时,当buffer达到64MB时提交一次;
使用console时避免频繁上传小文件,建议积累较大时一次性上传;
若是导入的是分区表,建议给分区设置生命周期,过时不用的数据自动清理;
Insert overwrite源表(或分区):
ALTER合并模式,经过命令行进行合并:set odps.merge.cross.paths=true;
set odps.merge.max.partition.count=100; --默认优化10个分区,此时设置为优化100个分区。
ALTER TABLE tablename [PARTITION] MERGE SMALLFILES;
临时表

在用临时表建议建立时都加上生命周期,到期后垃圾回收自动回收。
Q:MaxCompute使用Tunnel Upload命令行上传数据,若是数据使用空格做为列分隔符,或须要对数据作正则表达式过滤时该如何处理?
A:Tunnel Upload命令行不支持正则表达式。若是数据使用空格做为列分隔符,或须要对数据作正则表达式过滤时可借助MaxCompute的UDF自定义函数功能。

首先,将数据做为单列数据上传。本例中原始数据以下,列分割符为空格,行分隔符为回车,而且须要取的部分数据在引号内,部分数据例如"-"须要被过滤。这种复杂的需求可经过正则表达式实现。

10.21.17.2 [24/Jul/2018:00:00:00 +0800] - "GET https://help.aliyun.com/docum...l" 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/docum...l" 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/docum...l" 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需提交工单申请权限),详情可参见Python开发使用须知。

使用代码以下:

from odps.udf import annotate
from odps.udf import BaseUDTF
import 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/docum... 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/docum... 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/docum... 206 0 83821 83821 vivo HIT 0_0_0 003

Q:MaxCompute使用Tunnel Upload命令上传数据,如何实现批量上传一个目录下的多个文件到同一张表,而且每一个文件放在不一样的分区内?
A:能够巧妙的利用Shell脚本实现上述功能,本章节中以在Windows环境下配合odpscmd客户端使用Shell脚本举例,Linux环境下原理相同。
Shell脚本内容以下。

!/bin/sh

C:/odpscmd_public/bin/odpscmd.bat -e "create table user(data string) partitioned by (dt int);" //首先建立一个分区表user,分区关键字为dt,本例中odpscmd客户端的安装路径为C:/odpscmd_public/bin/odpscmd.bat,您能够根据您的实际环境调整路径。
dir=$(ls C:/userlog) //定义变量dir,为存放文件的文件夹下全部文件的名称
pt=0 //变量pt用于做为分区值,初始为0,每上传好一个文件+1,从而实现每一个文件都存放在不一样的分区
for i in $dir //定义循环,遍历文件夹C:/userlog下的全部文件
do
let pt=pt+1 //每次循环结束,变量pt+1
echo $i //显示文件名称
echo $pt //显示分区名称

C:/odpscmd_public/bin/odpscmd.bat  -e "alter table user add partition (dt=$pt);tunnel upload C:/userlog/$i user/dt=$pt -s false -fd "%" -rd "@";" //利用odpscmd首先添加分区,而后向分区中上传文件

done
实际运行shell脚本效果以下,本例中以两个文件userlog1及userlog2举例。

图片描述

完成上传后,您能够在odpscmd客户端查看表数据。

图片描述

网络问题
Q:MaxCompute使用Tunnel Upload命令上传数据时为何报错java.io.IOException: Error writing request body to server?
A:这是一个上传数据到服务器的时的异常,一般是由于上传过程当中的网络连接断开/超时致使的:

多是用户的数据源并不是是来自本地文件,而是须要从诸如数据库等一类的地方获取,致使数据在写入的过程当中还须要等待数据获取致使的超时。目前UploadSession在上传数据的过程当中,若是600秒没有数据上传,则被认为超时。
用户经过公网的Endpoint来作数据上传,因为公网网络质量不稳定致使超时。
解决方法:

在上传的过程当中,先把获取数据,再调用Tunnel SDK上传数据。
一个block能够上传64M-1G的数据,最好不要超过1万条数据以避免带来重试的时间致使的超时。一个Session能够挂最多2万个block。

若是用户的数据是在ECS上,能够参考访问域名和数据中心配置合适的Endpoint,能够提速并节省费用。
Q:MaxCompute使用Tunnel Upload命令行上传数据,设置了经典网络的Endpoint,但为何会链接到外网的Tunnel Endpoint?
A:配置文件odps_config.ini里除了endpoint以外还须要配置tunnel_endpoint。请参考访问域名和数据中心进行配置。目前只有上海region不须要设置tunnel endpoint

Q:MaxCompute使用Tunnel Upload命令行上传数据是否支持限速?上传速率太快的话可能会占用服务器过多的I/O性能。
A:目前MaxCompute使用Tunne lUpload命令行不支持限速,须要经过SDK单独处理。

计费问题Q:MaxCompute使用Tunnel Upload命令行上传数据计费的带宽,是按照数据压缩前仍是压缩后的大小计费?A:按照Tunnel压缩后的带宽进行计费。

相关文章
相关标签/搜索