基于java和tunnel-sdk的OSS与ODPS之间的数据连通
来源:互联网 发布:怎么样做淘宝客赚钱 编辑:程序博客网 时间:2024/05/22 12:25
第一次写博客,心里还是有点忐忑的,之前看着周围的同学都在写博
客,总觉得如果你写的这些东西你没有真正吃透就写出来,就有点只追求
量而丢了质了。
自己主要从事大数据开发,对大数据开发有着极度的热情,感觉操作集
群时有一种站在云端的感觉!~在大数据开发的道路上一直是自己摸索,
虽然很艰难,但与唐僧师徒四人西天取经相比还是轻松的多的,每当自己
走不下去时就想一想比自己困难的人数不胜数,自己已经很幸福了。
从今天开始想要分享一些我有了一些积累和认识的东西给大家。
最近刚开始实习,接了一个简单的小任务,自己完整的写了下来,觉得特别有意思,在给大家做个分享。 公司做大数据用的是阿里云这个平台,用了几天下来,更加感觉到阿里的强大。先简单介绍一下阿里云平台上的OSS和ODPS(现在已经改名为MaxCompute)。
对象存储 OSS
阿里云对象存储服务(Object Storage Service,简称 OSS),是阿里云提供的海量、安全、低成本、高可靠的云存储服务。您可以通过调用 API,在任何应用、任何时间、任何地点上传和下载数据,也可以通过 Web 控制台对数据进行简单的管理。OSS 适合存放任意类型的文件,适合各种网站、开发企业及开发者使用。
简单来说,我认为OSS就相当于一个网盘,存一些企业的历史数据。
MaxCompute
大数据计算服务(MaxCompute,原名 ODPS)是一种快速、完全托管的 GB/TB/PB 级数据仓库解决方案。MaxCompute 向用户提供了完善的数据导入方案以及多种经典的分布式计算模型,能够更快速的解决用户海量数据计算问题,有效降低企业成本,并保障数据安全。
数据通道
TUNNEL:提供高并发的离线数据上传下载服务。用户可以使用 Tunnel 服务向 MaxCompute 批量上传或下载数据。MaxCompute Tunnel 仅提供 Java 编程接口供用户使用。计算及分析任务
1、MaxCompute 只能以表的形式存储数据,并对外提供了 SQL 查询功能。
2、UDF,MaxCompute提供了很多内建函数,也允许自定义函数来满足需求。
3、MapReduce
4、Graph:MaxCompute 提供的 Graph 功能是一套面向迭代的图计算处理框架。
简单介绍后,这里直接切入正题。
在企业里你要去做一件事,首先是因为你有需求。
这里的需求在于公司将某个表的近3个月的历史信息存在了OSS上,为了导入ODPS的表中来做数据分析,所以需要开发一个java程序来实现OSS与ODPS之间的数据连通。
实现OSS和ODPS之间数据连同的方式有好几种,最简单的可以通过阿里云平台自带的功能来实现,这里之所以需要开发一个java程序来实现是为了开发完整的java程序后可以通过定时任务来每日自动执行,因为这张表以后是每天都在做一次这样的更新操作的。
在OSS上存储的数据是按dt=”天”来存储的。
其中CommonConstants类是一个静态配置类,主要保存了一些参数,配置自己公司的即可。
- 第一步 将OSS的按 表名/dt=”天”的形式保存到本地
public class LoadFromOSS implements Callable{ private static FileUtil fileUtil=new FileUtil(); private static OSSClient ossClient=null; private static Set<String> roomSet=null; //获得前一天的日期 private static String preDateString = fileUtil.getPreDate(); /* 找到当天的所有房间号 */ public static Set<String> startLoad() { roomSet=new HashSet<String>(); String key = "example/".concat(preDateString).concat("/"); final int maxKeys = 200; String nextMarker = null; ObjectListing objectListing = null; int i = 0; do { objectListing = ossClient.listObjects(new ListObjectsRequest(CommonConstants.bucketName).withPrefix(key).withMarker(nextMarker).withMaxKeys(maxKeys)); List<OSSObjectSummary> sums = objectListing.getObjectSummaries(); for (OSSObjectSummary s : sums) { //获得匹配到的object的目录路径 System.out.println(s.getKey()); String[] subtitleArr = s.getKey().split("/"); String roomId = null; //提取roomId if (subtitleArr.length == 3) { roomId = subtitleArr[2].trim(); } //将roomId存入roomSet,以便下载时使用 if(!StringUtils.isEmpty(roomId)){ roomSet.add(roomId); } } nextMarker = objectListing.getNextMarker(); } while (objectListing.isTruncated()); return roomSet; } public static void LoadFromOss(Set<String> roomId){ //如果本地没有当天目录则创建一个 if(!fileUtil.isExists(CommonConstants.rootdir_del+preDateString)){ try { fileUtil.createDir(CommonConstants.rootdir_del+preDateString); } catch (IOException e) { e.printStackTrace(); } } int count=0; for(String room:roomId){ String key="subtitles/".concat(preDateString).concat("/").concat(room); System.out.println(++count); ossClient.getObject(new GetObjectRequest(CommonConstants.bucketName, key), new File(CommonConstants.rootdir_del+preDateString+"/"+room)); } ossClient.shutdown(); } @Override public Object call() throws Exception { System.out.println("开始下载OSS文件到本地"); Date date1=new Date(); ossClient = new OSSClient(CommonConstants.endPoint, CommonConstants.accessKeyId, CommonConstants.accessKeySecret); try { Set<String> set =startLoad(); System.out.println(set.size()); LoadFromOss(set); } catch (OSSException oe) { oe.printStackTrace(); } catch (ClientException ce) { ce.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } finally { ossClient.shutdown(); } Date date2=new Date(); Thread.sleep(5000); System.out.println("任务完成,耗时:"+(date2.getTime()-date1.getTime())/1000+"秒"); return "ok"; }}
第二步 将保存到本地的文件按需求进行简单处理
第二步针对不同的需求可以将文件里的内容做对应的处理,例如原本文件中只有两列,我希望增加一列(增加一个属性)等,这里省略。
第三步 将处理后的文件上传到ODPS上
针对表的每个分区插入相应的记录。
public class UpLoadToODPS implements Callable { private static FileUtil fileUtil=new FileUtil(); static String preDate=fileUtil.getPreDate(); private static String partition = ""; @Override public Object call() throws Exception { System.out.println("开始上传处理后的文件到ODPS"); Date date1=new Date(); Account account = new AliyunAccount(CommonConstants.accessId, CommonConstants.accessKey); Odps odps = new Odps(account); odps.setEndpoint(CommonConstants.odpsUrl); odps.setDefaultProject(CommonConstants.project); Table t = odps.tables().get(CommonConstants.table); //获取当天的日期 partition="dt="+preDate; try { if(!t.hasPartition(new PartitionSpec(partition))){ t.createPartition(new PartitionSpec(partition)); } } catch (OdpsException e) { e.printStackTrace(); } try { TableTunnel tunnel = new TableTunnel(odps); tunnel.setEndpoint(CommonConstants.tunnelUrl); PartitionSpec partitionSpec = new PartitionSpec(partition); TableTunnel.UploadSession uploadSession = tunnel.createUploadSession(CommonConstants.project, CommonConstants.table, partitionSpec); System.out.println("Session Status is : " + uploadSession.getStatus().toString()); RecordWriter recordWriter = uploadSession.openRecordWriter(0); Record record = uploadSession.newRecord(); File file=new File(CommonConstants.rootdir_delc+preDate); File[] flist=file.listFiles(); BufferedReader br=null; for(File f:flist){ br=fileUtil.getBR(f); String line=null; while((line=br.readLine())!=null){ String[] fields=line.split("_"); record.setString(0,fields[0]); record.setString(1,fields[1]); recordWriter.write(record); } br.close(); } recordWriter.close(); uploadSession.commit(new Long[]{0L}); System.out.println("upload success!"+ file.getName()); } catch (TunnelException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } Date date2=new Date(); Thread.sleep(5000); System.out.println("任务完成,耗时:"+(date2.getTime()-date1.getTime())/1000+"秒"); return "ok"; }}
- 基于java和tunnel-sdk的OSS与ODPS之间的数据连通
- 基于ODPS的SQL语句
- 基于ODPS的MR开发
- 基于ODPS的SQL语句
- 基于ODPS的SQL语句
- 关于odps的sdk怎么实现
- ODPS数据倾斜导致的问题
- 基于OSS的文件系统设计
- java的oss存储
- ODPS之Tunnel上传下载
- ODPS Tunnel download
- 阿里云OSS javascript SDK,基于Node.js的一次考验
- android sdk 与java jdk之间的对应关系
- 基于websocket的前端与后端之间的数据交互
- QT 与 QT creator 和 QT SDK 之间的区别
- 大数据的弄潮儿:阿里产品dataX和ODPS的使用方法
- c++和java之间的数据转换
- ODPS的SQL
- 解决$.ajax的回调函数值和SpringMVC返回String时冲突的问题
- 内网网站发布到外网的路由器端口映射方法
- selenium python中关于iframe的定位
- scrollview嵌套recycleview
- 设计模式--JDK动态代理的实现与原理解析(2)
- 基于java和tunnel-sdk的OSS与ODPS之间的数据连通
- 朵唯S2l 驱动安装 刷机 Imei号找回方案(应该也适合同类国产机)
- 毕业那年
- FOF常用的七种投资策略全解析
- Python实现结构体
- MAPREDUCE使用(整理)
- hihocoder Challenge 29 D. 不上升序列
- Android selector配合setSelected使用时的坑
- VS C语言xml文件读取