基于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类是一个静态配置类,主要保存了一些参数,配置自己公司的即可

  1. 第一步 将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";    }}
  1. 第二步 将保存到本地的文件按需求进行简单处理

    第二步针对不同的需求可以将文件里的内容做对应的处理,例如原本文件中只有两列,我希望增加一列(增加一个属性)等,这里省略。

  2. 第三步 将处理后的文件上传到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";    }}
原创粉丝点击