时间:2021-07-01 10:21:17 帮助过:43人阅读
可以看到,SQLTask不能处理超过1万条记录,但是Tunnel刚好可以,两者存在互补。所以可以基于两者实现数据的导出。以下用一个代码的例子来实现:
private static final String accessId = "userAccessId";
private static final String accessKey = "userAccessKey";
private static final String endPoint = "http://service.odps.aliyun.com/api";
private static final String project = "userProject";
private static final String sql = "userSQL";
private static final String table = "Tmp_" + UUID.randomUUID().toString().replace("-", "_");//其实也就是随便找了个随机字符串作为临时表的名字
private static final Odps odps = getOdps();
public static void main(String[] args) {
System.out.println(table);
runSql();
tunnel();
}
/*
* 把SQLTask的结果下载过来
* */
private static void tunnel() {
TableTunnel tunnel = new TableTunnel(odps);
try {
DownloadSession downloadSession = tunnel.createDownloadSession(
project, table);
System.out.println("Session Status is : "
+ downloadSession.getStatus().toString());
long count = downloadSession.getRecordCount();
System.out.println("RecordCount is: " + count);
RecordReader recordReader = downloadSession.openRecordReader(0,
count);
Record record;
while ((record = recordReader.read()) != null) {
consumeRecord(record, downloadSession.getSchema());
}
recordReader.close();
} catch (TunnelException e) {
e.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
}
/*
* 保存这条数据
* 数据量少的话直接打印后拷贝走也是一种取巧的方法。实际场景可以用Java.io写到本地文件,或者写到远端数据等各种目标保存起来。
* */
private static void consumeRecord(Record record, TableSchema schema) {
System.out.println(record.getString("username")+","+record.getBigint("cnt"));
}
/*
* 运行SQL,把查询结果保存成临时表,方便后面用Tunnel下载
* 这里保存数据的lifecycle为1天,所以哪怕删除步骤出了问题,也不会太浪费存储空间
* */
private static void runSql() {
Instance i;
StringBuilder sb = new StringBuilder("Create Table ").append(table)
.append(" lifecycle 1 as ").append(sql);
try {
System.out.println(sb.toString());
i = SQLTask.run(getOdps(), sb.toString());
i.waitForSuccess();
} catch (OdpsException e) {
e.printStackTrace();
}
}
/*
* 初始化MaxCompute(原ODPS)的连接信息
* */
private static Odps getOdps() {
Account account = new AliyunAccount(accessId, accessKey);
Odps odps = new Odps(account);
odps.setEndpoint(endPoint);
odps.setDefaultProject(project);
return odps;
}
有时候我们希望把数据导出后用文本文件来保存,但是有时候会希望保存到数据库或者其他的别的什么地方。为了避免重复造轮子,阿里开源了工具DataX。通过配置配置文件,可以很方便的导出MaxCompute里的数据到目标数据源。
工具的安装自不必多说,关于插件的配置,可以看到有分为Reader和Writer,还有一个用来配置整个任务的诸如速度并发限制的Setting。通过配置Reader和Writer,可以很方便地适配不同的数据源。
细心的你可能已经发现,这个解掉了数据下载后保存的问题,但是还是没解决数据的生成以及两个步骤之间的调度依赖的问题。
这里隆重为大家介绍阿里云大数据开发套件这个产品,我们可以在里面运行SQL、配置任务同步(基于dataX实现),还可以设置自动周期性运行还有多任务之间的依赖,彻底解决了前面的所有烦恼。
我们先创建一个工作流,里面可以有一个SQL节点和一个数据同步节点。如图
里面配置的SQL作业和同步作业的配置如图:
注意SQL这里的创建表我先执行了一下再去配置同步(否则表都没有,同步任务没办法配置)
运行测试后,可以看到日志里显示
2016-12-17 23:43:46.394 [job-15598025] INFO JobContainer -
任务启动时刻 : 2016-12-17 23:43:34
任务结束时刻 : 2016-12-17 23:43:46
任务总计耗时 : 11s
任务平均流量 : 31.36KB/s
记录写入速度 : 1668rec/s
读出记录总数 : 16689
读写失败总数 : 0
到mysql里查一下,数据也进去了。
阅读原文请点击
导出SQL运行结果的方法总结
标签:container 参考 工作流 product 存在 dom idt 开发 put