0


猿创征文|阿里云MaxCompute存取性能测试报告

猿创征文|阿里云MaxCompute存取性能测试报告

文章目录


前言

前几天公司给我安排了个任务,让我去测试一下阿里云DataWork下的MaxCompute的存取性能,这不,测试报告来了。

MaxCompute介绍

MaxCompute(ODPS)是适用于数据分析场景的企业级SaaS(Software as a Service)模式云数据仓库,以Serverless架构提供快速、全托管的在线数据仓库服务,消除了传统数据平台在资源扩展性和弹性方面的限制,最小化用户运维投入,使用户可以经济并高效地分析处理海量数据。

MaxCompute适用于100 GB以上规模的存储及计算需求,最大可达EB级别,并且MaxCompute已经在阿里巴巴集团内部得到大规模应用。MaxCompute适用于大型互联网企业的数据仓库和BI分析、网站的日志分析、电子商务网站的交易分析、用户特征和兴趣挖掘等。

官方学习路线:https://www.alibabacloud.com/zh/getting-started/learningpath/maxcompute

查询测试报告

测试方案一

多线程SQL查询

查询场景:

  • 单表查询,只查询单字段,共610万条数据
  • 每次查询一万条(服务端限制了只能一次查一万)

测试结果如下:
启动时间线程数花费时间10:11203m10s10:16302m28s10:21501m37s10:23701m9s10:261001m3s10:2720046s10:2940044s10:3050043s
由于这波操作属于IO密集型,故提高线程数可以有效的减少花费时间,提高到100-200时性价比应该是最高的。

核心代码:

@Testpublicvoidtest6()throwsInterruptedException{// 查询code值String codeQuery =String.format("select distinct code from %s;", table);List<Map<String,Object>> list =MaxComputeUtil.queryData(codeQuery ,true);
        log.info("获得code数据共{}条", list.size());// 建立线程池ThreadPoolExecutor pool =newThreadPoolExecutor(20,20,0,TimeUnit.SECONDS,newArrayBlockingQueue<>(500));for(Map<String,Object> map : list){String code =(String) map.get("code");
            pool.execute(newTest(code));}
        pool.shutdown();boolean awaitTermination = pool.awaitTermination(300,TimeUnit.SECONDS);if(!awaitTermination) log.warn("运行超时");
        log.info("执行完毕,所有数据,共{}条",Test.count);}
@Slf4jclassTestimplementsRunnable{publicstaticlong count =0;privatefinalString sql ="select code from table where code= '%s' and pt = 1;";privatefinalString code ;publicTest(String code){this.code= code;}@Overridepublicvoidrun(){int now =1;int size =10000;int sum =0;while(true){List<Map<String,Object>> list =MaxComputeUtil.queryPageData(
            sum += list.size();if(list.size()< size)break;}
        log.info("运行完毕,共{}条数据", sum);
        count += sum;}}

测试方案二

使用TableTunnel DownloadSession 进行数据下载

这个是官方推荐使用的批量传输通道,是一套可以查询数据和存入数据的SDK,可以用来代替SQL。

但是不知道为什么这个速度特别慢,总是卡在一个地方不动,一卡一卡的,一点也不流畅。

首先获取连接会话的时候,直接等了4分钟才连接上:

image-20220901112318069

但是我去开启UploadSession进行数据上传(这个后面有讲),也没有像这样等待这么久,速度一般也就是一两秒,偶尔连接的时候会要10多秒。

我猜测可能是由于使用这个DownloadSession的客户端比较多,服务端资源提供不过来?或者是我们的网络和这个会话服务端的网络连接不通畅?连接上之后,每获取几条十几条数据就要等待一段时间,最终跑 118,064 条数据,花费时间13分钟,建议直接ban掉。

使用建议

使用方案一的多线程SQL查询,一次虽然只能查询一万条,但是多线程查询下速度还是可以接受的。

写入测试报告

首先我新建了一张表,表结构如下:

-- 此表结构取自官方文档:https://www.alibabacloud.com/help/zh/maxcompute/latest/use-the-maxcompute-client-create-tables#section-gwe-8vc-iwxcreatetableifnotexists t_salary_write_test
(
    age             BIGINTcomment'年龄',
    job             STRING comment'工作类型',
    marital         STRING comment'婚否',
    education       STRING comment'教育程度',
    credit          STRING comment'是否有信用卡',
    housing         STRING comment'是否有房贷',
    loan            STRING comment'是否有贷款',
    contact         STRING comment'联系方式',month           STRING comment'月份',
    day_of_week     STRING comment'星期几',
    duration        STRING comment'持续时间',
    campaign        BIGINTcomment'本次活动联系的次数',
    pdays           DOUBLEcomment'与上一次联系的时间间隔',
    previous        DOUBLEcomment'之前与客户联系的次数',
    poutcome        STRING comment'之前市场活动的结果',
    emp_var_rate    DOUBLEcomment'就业变化速率',
    cons_price_idx  DOUBLEcomment'消费者物价指数',
    cons_conf_idx   DOUBLEcomment'消费者信心指数',
    euribor3m       DOUBLEcomment'欧元存款利率',
    nr_employed     DOUBLEcomment'职工人数',
    fixed_deposit   BIGINTcomment'是否有定期存款');

测试方案一

单线程,本地生成数据和SQL语句进行插入,每次插入一条数据,测试结果:
测试时间插入数据条数耗时15:08201m52s15:10528s15:121048s
这个测不动,太慢了。。。时间都花在提交任务上去了,其实执行没花多少时间。

生成SQL的类

具体内容我过几天单独写一篇博客来讲😋到时候我把链接贴在这里

纯手搓,可以适用不同的表,主要是利用反射机制获取对象当中的字段和字段值,然后拼接成SQL语句,实现了单数据插入和批量插入的生成方法。

需要注意对其中的特殊部分进行特殊处理,字符串之类的字段是需要添加引号的。

测试方案二

多线程,每个线程都单独插入5条数据,测试结果:
测试时间线程数耗时15:20225s15:22532s15:241029s15:252042s15:265052s15:281001m30s15:312002m59s15:385009m32s
这个也测不动,太慢了,直接放弃。

测试方案三

使用官方SDK中的TableTunnel(UploadSession)进行批量传输(官方推荐),https://www.alibabacloud.com/help/zh/maxcompute/latest/simple-upload

以下是使用单线程的传输速度。
测试时间插入数据条数耗时17:2410002.5s17:24100003.3s17:2910000012.4s
这速度就很快了,前面两种方案直接ban掉。

官方文档的解释是这种传输方式建议用在上传大量数据的场景(>64M)下进行使用,因为它里面需要构建一东西,比较消耗资源(这个说明的具体地方我找不到了,贴个大概的),https://www.alibabacloud.com/help/zh/maxcompute/latest/data-upload-and-download-overview。

核心代码:

@TestpublicvoiduploadSessionTest(){int count =1000;TableTunnel.UploadSession uploadSession =MaxComputeUtil.getUploadSession(tableName,"pt=1");// 生成TunnelBufferedWriter的实例try(RecordWriter recordWriter = uploadSession.openBufferedWriter()){for(int i =0; i < count; i++){// 创建一条新记录和新的待插入数据Recordrecord= uploadSession.newRecord();BankData bankData =generateData(newBankData());// 把数据转换到 record 对象当中generateRecord(record, bankData);// 调用write接口写入数据。
                recordWriter.write(record);}// uploadSession提交,结束上传。
            uploadSession.commit();
            log.info("commit ok!");}catch(TunnelException|IOException|IllegalAccessException e){
            e.printStackTrace();}}

数据填充:

private<T>voidgenerateRecord(Recordrecord,T object)throwsIllegalAccessException{// 通过反射Field[] fields = object.getClass().getDeclaredFields();for(Field field : fields){
            field.setAccessible(true);record.set(field.getName(), field.get(object));}}

创建UploadSession的方法:

publicstaticTableTunnel.UploadSessiongetUploadSession(String tableName,String partition){
        log.info("开始创建 UploadSession");// 创建TableTunnelTableTunnel tunnel =newTableTunnel(OdpsInstance.getInstance());// 需要指定的分区PartitionSpec partitionSpec =newPartitionSpec(partition);TableTunnel.UploadSession uploadSession;try{
            uploadSession = tunnel.createUploadSession(projectName, tableName, partitionSpec);}catch(TunnelException e){thrownewRuntimeException("创建 uploadSession 失败", e);}
        log.info("UploadSession 创建完毕");return uploadSession;}

测试方案四

使用SQL进行批量插入,将多条插入数据的SQL拼接成一条SQL(代码在上面方案一里),单线程运行。
测试时间插入数据条数耗时10:1010009s10:111000030.6s10:16100000报错
测试十万记录的报错是因为SQL太长了,导致单次发送的HTTP请求数据量过大,造成数据异常。

在这里插入图片描述

性能比单数据插入的性能高上了很多,但相比于官方推荐的批量传输方式还是慢了很多。

使用建议

上传数据的话,如果数据量比较大(十万条数据以上),使用UploadSession进行上传是会比较好的,速度很快,如果数据量不大,那么使用批量上传的SQL也是完全可以的,虽然慢一点,但是可以减少很多不必要的资源消耗。

这两种方式都可以使用多线程来提高速度,速度会比上面测试的要更快。

后记

本篇文章主要是讲MaxCompute的存取性能如何,里面的代码都是只有核心部分的,完整的代码不方便贴。不过主要还是看它的性能如何,能达到什么样的存取速度。

最后不得不说,MaxCompute做的确实很不错了,几百万条数据全部取出来只要花一分钟不到的时间,存数据也可以达到10M/s(前提是你的网速达标)。

如果本篇文章对你有帮助,欢迎点赞收藏评论关注😋,也欢迎在评论区指出文章中写的不对的和不好的地方🥰。

标签: 阿里云 odps java

本文转载自: https://blog.csdn.net/little_stick_i/article/details/126651302
版权归原作者 阿杆. 所有, 如有侵权,请联系我们删除。

“猿创征文|阿里云MaxCompute存取性能测试报告”的评论:

还没有评论