利用InformationSchema与阿里云交易和账单管理API实现MaxCompute费用对账分摊统计

本文涉及的产品
云原生大数据计算服务 MaxCompute,5000CU*H 100GB 3个月
云原生大数据计算服务MaxCompute,500CU*H 100GB 3个月
简介: 利用MaxCompute InformationSchema和阿里云交易和账单管理API 实现MaxCompute费用对账分摊统计一、需求场景分析非常多的用户选择MaxCompute按量付费模式构建自己的数据平台,利用MaxCompute按量付费模型极大地减少不必要的费用支持,仅为实际运行的作业付费。

利用MaxCompute InformationSchema与阿里云交易和账单管理API 实现MaxCompute费用对账分摊统计
一、需求场景分析
很多的企业用户选择MaxCompute按量付费模式构建自己的数据平台,利用MaxCompute按作业付费的计费模型,在获得高性能的同时避免"IDLE"状态的不必要资源费用支出,仅为实际使用付费。
那么在一个规模比较大的公司,企业购买了MaxCompute服务,会支撑企业内部的不同部门、个人来使用MaxCompute来开展数据处理分析。为了更好地识别数据平台使用方的周期性花费成本,优化数据资源的使用,就有必要对作业的费用进行统计,从而确认不同人员或归属部门的作业数量、作业费用、作业时长、作业资源使用量等指标。基于这些指标进行成本分摊、作业优化等管理工作。
阿里云交易和账单系统包含了MaxCompute产品的费用信息及费用明细,通过关联交易和账单系统的计费明细与MaxCompute项目的作业明细或某时间段的账单费用,可以获得使用用户、作业明细信息(如提交人账号、作业SQL内容、作业资源使用大小等信息)与计费明细或账单费用间的关系,从而开展分析。
本文将介绍如果自动化实现MaxCompute按量付费项目的作业费用统计,您也可以通过阿里云交易和账单系统API获取其他需要的费用信息,扩展分析场景。
二、方案设计思路
1、获得MaxCompute项目历史作业明细
MaxCompute Information_Schema服务是MaxCompute产品的开放元数据服务,通过Information_Schema提供的一组视图,用户可以自助地查询访问到项目内的准实时的table,column,function等全量元数据信息,同时也提供了项目内近期的作业历史明细,供使用者自助查询使用。
通过元数据服务Information_Schema里面的作业历史表tasks_history视图,可以查询到准实时的项目作业历史明细。包括:项目名称、任务名称、Instance id、开始时间、结束时间、任务复杂度、任务CPU使用情况等字段。
image

备注:Information_Schema目前在中国公共云已全面开放,详情见产品文档,国际Region即将开放。
2、获取作业的计费明细数据
用户可以通过费用中心账号总览消费记录去查询具体的消费情况。
同时,格式阿里云交易和账单管理OpenAPI为用户提供管理阿里云产品售卖和财资能力,通过该api可以程序化获取MaxCompute作业计费明细数据。
调用QueryUserOmsData接口(阿里云的账单系统OMS),可以查询到具体计量信息编号、数据分类、存储、SQL读取量、公网上下行流量等字段信息。
3、关联计费明细与作业明细
通过表关联,查询到需要计算的数据结果

select 
distinct 
t.task_schema,
o.MeteringId,
t.owner_id,
t.operation_text,
o.type,
o.endtime,
o.computationsqlinput,
o.computationsqlcomplexity,
t.cost_cpu,o.starttime,
t.cost_mem 
from  information_schema.tasks_history t 
right join OdpsFeeDemo o 
on t.inst_id = o. meteringid 
and t.task_schema = o.projectid
where o.type = "ComputationSql";

这些数据可以通过作业ID与计费明细数据进行关联后,您就获取各个作业明细的费用信息(例如,SQL费用=数据扫描量*复杂度) ,从而可以开展不同视角的分析。
image
需要强调的是:MaxCompute的计费都是以阿里云费用中心的出账结果及费用明细为准。

三、具体实现步骤(含参考代码)
1.查询元数据服务里面的作业历史表tasks_history
例如,您登录访问的当前项目为 myproject1,在 myproject1 中,可以通过查询 INFORMATION_SCHEMA.tables 获得当前 myproject1 中所有表的元数据信息。

odps@ myproject1 > select * from information_schema.tables; 

INFORMATION_SCHEMA 同时包含了作业历史视图,可以查询到当前项目内的作业历史信息,使用时注意添加日期分区进行过滤,例如。

odps@ mypoject1 > select * from information_schema.tasks_history where ds=’yyyymmdd’ limit 100;
odps@ myproject1 > desc package information_schema.systables;

image

查询历史表字段属性

odps@ myproject1 > desc information_schema.tasks_history;

如下如所示:
image

2.使用阿里云交易和账单管理API获取费用明细和分摊统计
方法1:手工下载上传方式
(一)首先在MaxCompute中创建结果输出表OMS表,建表语句如下:

CREATE TABLE IF NOT EXISTS OdpsFeeDemo(
ProjectId          STRING COMMENT '项目编号',
MeteringId         STRING COMMENT '计量信息编号',
Type                  STRING COMMENT '数据分类',
Storage            STRING COMMENT '存储(Byte)',
EndTime            STRING COMMENT '结束时间',
ComputationSqlInput  STRING COMMENT 'SQL读取量',
ComputationSqlComplexity  STRING COMMENT 'SQL复杂度',
StartTime          STRING COMMENT '开始时间',
OdpsSpecCode       STRING COMMENT '规格类型'
);

方法一:手动从视图下载oms账单详细费用,将数据上传(tunnel upload)到odps对应输出表

手动下载步骤:
https://help.aliyun.com/product/87964.html?spm=a2c4g.750001.list.245.5e907b138Ik9xM
image
image
进入阿里云用户中心:https://usercenter2.aliyun.com/home
返回旧版

费用中心>消费记录>使用记录
选择产品类型,填写使用期间,计算粒度,导出CSV格式
image

把oms数据定期取下来,然后上传到odps中创建的结果输出表(OdpsFeeDemo)
tunnel upload C:UsersDesktopaa.txt project.tablename ;
(二)进行表关联,将最终结果存储在上面创建的MaxComputeFee中

select 
distinct 
t.task_schema,
o.MeteringId,
t.owner_id,
o.type,
o.endtime,
o.computationsqlinput,
o.computationsqlcomplexity,
t.cost_cpu,o.starttime,
t.cost_mem 
from information_schema.tasks_history t 
right join OdpsFeeDemo o 
on t.inst_id = o. meteringid 
and t.task_schema = o.projectid
where o.type = “ComputationSql”;

方法2:程序化API下载费用明细数据&上传到MaxCompute后分析
(一)在odps创建oms表OdpsFeeDemo,参考如下:

CREATE TABLE IF NOT EXISTS OdpsFeeDemo(
ProjectId          STRING COMMENT '项目编号',
MeteringId         STRING COMMENT '计量信息编号',
Type                  STRING COMMENT '数据分类',
Storage            STRING COMMENT '存储(Byte)',
EndTime            STRING COMMENT '结束时间',
ComputationSqlInput  STRING COMMENT 'SQL读取量',
ComputationSqlComplexity  STRING COMMENT 'SQL复杂度',
StartTime          STRING COMMENT '开始时间',
OdpsSpecCode       STRING COMMENT '规格类型'
);

通过API下载OMS系统数据并上传到odps对于表格中
代码参考如下:
1) 服务启动类Application

package com.alibaba.odps;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;

/**
 * @ClassName: Application
 * @Description: 服务启动类
 * @Author: ***
 * @Data: 2019/7/30 17:15
 **/
@SpringBootApplication
@EnableScheduling
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

2) 从odps接收数据ReceiveData

package com.alibaba.odps.controller;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.bssopenapi.model.v20171214.QueryUserOmsDataRequest;
import com.aliyuncs.bssopenapi.model.v20171214.QueryUserOmsDataResponse;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.exceptions.ServerException;
import com.aliyuncs.profile.DefaultProfile;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.gson.Gson;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

/**
 * @ClassName: ReceiveData
 * @Description: 接收数据
 * @Author: LiuJianwei
 * @Data: 2019/7/30 17:18
 **/
@Component
public class ReceiveData {

    @Value("${table}")
    private String table;

    @Value("${odps.accessKeyId}")
    private String accessKeyId;

    @Value("${odps.accessKeySecret}")
    private String accessKeySecret;

    @Value("${file.save.path}")
    private String fileSavePath;

    @Autowired
    private OdpsServer odpsServer;

    protected final ObjectMapper objectMapper = new ObjectMapper();

    {
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    }

//    String[] fileds = {"DBVersion", "InstanceId", "NetworkIn", "NetworkOut", "Storage", "Memory", "Region", "ProviderId",
//           "DBType", "EndTime", "StartTime", "InstanceUseType", "InstanceName"};
    String[] fileds = {"ProjectId","MeteringId","Type","Storage","EndTime","ComputationSqlInput","ComputationSqlComplexity","StartTime","OdpsSpecCode"};

    @Scheduled(cron = "${cron}")
    public void queryUserOmsData() {
        //获取昨天的开始日期和结束日期
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        String yesterday = format.format(DateUtils.addDays(new Date(), -1));
        //String yesterday = "2019-07-29";
        String startTime = yesterday + "T00:00:00Z";
        String endTime = yesterday + "T23:59:59Z";
        DefaultProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKeyId, accessKeySecret);
        IAcsClient client = new DefaultAcsClient(profile);
        for (String tab : table.split(",")) {
            QueryUserOmsDataRequest request = new QueryUserOmsDataRequest();
            request.setTable(tab.trim());
            request.setDataType("HOUR");
            request.setStartTime(startTime);
            request.setEndTime(endTime);
            try {
                QueryUserOmsDataResponse response = client.getAcsResponse(request);
                String data = new Gson().toJson(response);
                //将数据插入
                odpsServer.writeDataToOdps(data, yesterday, tab.trim());
                //将查询到的数据保存到TXT中
                writeDataToTxt(data, yesterday);
            } catch (IOException | ServerException e) {
                e.printStackTrace();
            } catch (ClientException e) {
                System.out.println(e);
                System.out.println("ErrCode:" + e.getErrCode());
                System.out.println("ErrMsg:" + e.getErrMsg());
                System.out.println("RequestId:" + e.getRequestId());
            }
        }
    }

    public void writeDataToTxt(String data, String yesterday) throws IOException {
        String path = fileSavePath + File.separator + yesterday + ".txt";
        FileWriter writer = new FileWriter(new File(path));
        if (StringUtils.isNotEmpty(data)) {
            JSONObject json = objectMapper.readValue(data, JSONObject.class);
            JSONObject datas = json.getJSONObject("data");
            if (datas.containsKey("omsData")) {
                List<Map<String, Object>> list = (List<Map<String, Object>>) datas.get("omsData");
                if (!list.isEmpty()) {
                    for (Map<String, Object> map : list) {
                        StringBuilder sb = new StringBuilder();
                        for (String key : fileds) {
                            if (map.containsKey(key)) {
                                sb.append(map.get(key));
                            } else {
                                sb.append(" ");
                            }
                            sb.append(",");
                        }
                        sb.setLength(sb.length() - 1);
                        sb.append("\r\n");
                        writer.write(sb.toString());
                    }
                }
            }
        }
        writer.flush();
        writer.close();
    }
}

3) 将接收数据上传到MaxCompute项目里建好的oms表,类名:OdpsServer

package com.alibaba.odps.controller;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import com.alibaba.fastjson.JSONObject;
import com.aliyun.odps.Odps;
import com.aliyun.odps.account.AliyunAccount;
import com.aliyun.odps.data.Record;
import com.aliyun.odps.data.RecordWriter;
import com.aliyun.odps.tunnel.TableTunnel;
import com.aliyun.odps.tunnel.TableTunnel.UploadSession;
import com.aliyun.odps.tunnel.TableTunnel.UploadStatus;
import com.aliyun.odps.tunnel.TunnelException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

/**
 * @ClassName: OdpsServer
 * @Description: 将数据写入ODPS中
 * @Author: LiuJianwei
 * @Data: 2019/7/30 17:23
 **/
@Component
public class OdpsServer implements InitializingBean {

    @Value("${odps.accessKeyId}")
    private String accessKeyId;

    @Value("${odps.accessKeySecret}")
    private String accessKeySecret;

    @Value("${odps.project}")
    private String project;

    @Value("${odps.url}")
    private String url;

    private UploadSession ossUploadSession;

    private UploadSession rdsUploadSession;

    private UploadSession odpsUploadSession;

    private String OSSTableName = "MaxComputeFee";

    private String RDSTableName ="RDS";

    private String ODPSTableName ="OdpsFeeDemo";

    protected final ObjectMapper objectMapper = new ObjectMapper();

    {
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    }

    public void writeDataToOdps(String data, String yesday, String tab) {
        List<Map<String, Object>> dataList = new ArrayList<>();
        if (StringUtils.isNotEmpty(data)) {
            try {
                JSONObject json = objectMapper.readValue(data, JSONObject.class);
                JSONObject datas = json.getJSONObject("data");
                if (datas.containsKey("omsData")) {
                    dataList = (List<Map<String, Object>>)datas.get("omsData");
                }
                if (dataList.isEmpty()) {
                    return;
                }
                //数据不为空,开发往ODPS中写入数据
                if (tab.equals("oss")) {
                    for (Map<String, Object> map : dataList) {
                        UploadSession session = getSession(OSSTableName);
                        RecordWriter writer = session.openRecordWriter(session.getAvailBlockId());
                        Record record = session.newRecord();
                        writer.write(record);
                        if (writer != null) {
                            writer.close();
                            session.commit(new Long[] {0L});
                        }
                    }
                } else if (tab.equals("rds")) {
                    for (Map<String, Object> map : dataList) {
                        UploadSession session = getSession(RDSTableName);
                        RecordWriter writer = session.openRecordWriter(session.getAvailBlockId());
                        Record record = session.newRecord();
                        record.set("dbversion", map.get("DBVersion").toString());
                        record.set("instanceid", map.get("InstanceId").toString());
                        record.set("networkin", map.get("NetworkIn").toString());
                        record.set("networkout", map.get("NetworkOut").toString());
                        record.set("storage", Long.valueOf(map.get("Storage").toString()));
                        record.set("memory", map.get("Memory").toString());
                        record.set("region", map.get("Region").toString());
                        record.set("providerid", map.get("ProviderId").toString());
                        record.set("dbtype", map.get("DBType").toString());
                        record.set("endtime", map.get("EndTime").toString());
                        record.set("starttime", map.get("StartTime").toString());
                        record.set("instanceusetype", map.get("InstanceUseType").toString());
                        record.set("instancename", map.get("InstanceName").toString());
                        writer.write(record);
                        if (writer != null) {
                            writer.close();
                            session.commit(new Long[] {0L});
                        }
                    }
                } else if (tab.equals("odps")) {
                    for (Map<String, Object> map : dataList) {
                        UploadSession session = getSession(ODPSTableName);
                        RecordWriter writer = session.openRecordWriter(session.getAvailBlockId());
                        Record record = session.newRecord();
                        record.set("projectid", map.containsKey("ProjectId") ? map.get("ProjectId").toString() : "");
record.set("meteringid", map.containsKey("MeteringId") ? map.get("MeteringId").toString() : "");
record.set("type", map.containsKey("Type") ? map.get("Type").toString() : "");
record.set("storage", map.containsKey("Storage") ? map.get("Storage").toString() : "");
record.set("endtime", map.containsKey("EndTime") ? map.get("EndTime").toString() : "");
record.set("computationsqlinput", map.containsKey("ComputationSqlInput") ? map.get("ComputationSqlInput").toString() : "");
record.set("computationsqlcomplexity", map.containsKey("ComputationSqlComplexity") ? map.get("ComputationSqlComplexity").toString() : "");
record.set("starttime", map.containsKey("StartTime") ? map.get("StartTime").toString() : "");
record.set("odpsspeccode", map.containsKey("OdpsSpecCode") ? map.get("OdpsSpecCode").toString() : "");

                        writer.write(record);
                        if (writer != null) {
                            writer.close();
                            session.commit(new Long[] {0L});
                        }
                    }
                }
            } catch (Exception e) {
                throw new RuntimeException();
            }
        }
    }

    private UploadSession getSession(String tableName) {
        try {
            if (tableName.equals(OSSTableName)) {
                if (!this.ossUploadSession.getStatus().equals(UploadStatus.NORMAL)) {
                    this.ossUploadSession = createNewSession(tableName);
                }
                return this.ossUploadSession;
            } else if (tableName.equals(RDSTableName)) {
                if (!this.rdsUploadSession.getStatus().equals(UploadStatus.NORMAL)) {
                    this.rdsUploadSession = createNewSession(tableName);
                }
                return this.rdsUploadSession;
            }else if (tableName.equals(ODPSTableName)) {
                if (!this.odpsUploadSession.getStatus().equals(UploadStatus.NORMAL)) {
                    this.odpsUploadSession = createNewSession(tableName);
                }
                return this.odpsUploadSession;
            }

        } catch (TunnelException | IOException e) {
            throw new RuntimeException(e);
        }
        return null;
    }

    private UploadSession createNewSession(String tableName) {
        try {
            AliyunAccount account = new AliyunAccount(accessKeyId, accessKeySecret);
            Odps odps = new Odps(account);
            odps.setEndpoint(url);
            odps.setDefaultProject(project);
            TableTunnel odpsTunnel = new TableTunnel(odps);
            UploadSession session = odpsTunnel.createUploadSession(project, tableName);
            return session;
        } catch (TunnelException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        this.ossUploadSession = createNewSession(OSSTableName);
        this.rdsUploadSession = createNewSession(RDSTableName);
        this.odpsUploadSession = createNewSession(ODPSTableName);
    }

}

4) 配置文件
image

#配置accessKeyId
odps.accessKeyId=******** 
#配置accessKeySecret
odps.accessKeySecret=********
#配置project
odps.project=工作空间
#配置url
odps.url=http://service.odps.aliyun.com/api
#配置table
table=odps
ds#配置定时任务时间设置
cron=0/1 0/1 * * * ?

5) 现在将数据上传到odps里面对应的表,然后进行关联

select 
distinct 
t.task_schema,
o.MeteringId,
t.owner_id,
o.type,
o.endtime,
o.computationsqlinput,
o.computationsqlcomplexity,
t.cost_cpu,o.starttime,
t.cost_mem 
from information_schema.tasks_history t 
right join OdpsFeeDemo o 
on t.inst_id = o. meteringid 
and t.task_schema = o.projectid
where o.type = “ComputationSql”;
相关实践学习
基于MaxCompute的热门话题分析
本实验围绕社交用户发布的文章做了详尽的分析,通过分析能得到用户群体年龄分布,性别分布,地理位置分布,以及热门话题的热度。
SaaS 模式云数据仓库必修课
本课程由阿里云开发者社区和阿里云大数据团队共同出品,是SaaS模式云原生数据仓库领导者MaxCompute核心课程。本课程由阿里云资深产品和技术专家们从概念到方法,从场景到实践,体系化的将阿里巴巴飞天大数据平台10多年的经过验证的方法与实践深入浅出的讲给开发者们。帮助大数据开发者快速了解并掌握SaaS模式的云原生的数据仓库,助力开发者学习了解先进的技术栈,并能在实际业务中敏捷的进行大数据分析,赋能企业业务。 通过本课程可以了解SaaS模式云原生数据仓库领导者MaxCompute核心功能及典型适用场景,可应用MaxCompute实现数仓搭建,快速进行大数据分析。适合大数据工程师、大数据分析师 大量数据需要处理、存储和管理,需要搭建数据仓库?学它! 没有足够人员和经验来运维大数据平台,不想自建IDC买机器,需要免运维的大数据平台?会SQL就等于会大数据?学它! 想知道大数据用得对不对,想用更少的钱得到持续演进的数仓能力?获得极致弹性的计算资源和更好的性能,以及持续保护数据安全的生产环境?学它! 想要获得灵活的分析能力,快速洞察数据规律特征?想要兼得数据湖的灵活性与数据仓库的成长性?学它! 出品人:阿里云大数据产品及研发团队专家 产品 MaxCompute 官网 https://www.aliyun.com/product/odps&nbsp;
目录
相关文章
|
1月前
|
存储 运维 监控
API明细日志及运维统计日志全面提升API可运维性
在数字化转型的大潮中,数据已成为企业最宝贵的资产之一。而数据服务API可快速为数据应用提供数据接口。面对越来越多的API以及越来越多的应用调用,如何快速查看API的服务情况、异常情况及影响范围,以及查看API的调用详情,进行API的性能优化、错误排查变得越来越重要,本文将介绍如何配置和开通API运维统计及明细日志,以及如何查看日志进行介绍。
|
2天前
|
存储 人工智能 数据管理
|
1天前
|
机器学习/深度学习 分布式计算 数据挖掘
MaxFrame 性能评测:阿里云MaxCompute上的分布式Pandas引擎
MaxFrame是一款兼容Pandas API的分布式数据分析工具,基于MaxCompute平台,极大提升了大规模数据处理效率。其核心优势在于结合了Pandas的易用性和MaxCompute的分布式计算能力,无需学习新编程模型即可处理海量数据。性能测试显示,在涉及`groupby`和`merge`等复杂操作时,MaxFrame相比本地Pandas有显著性能提升,最高可达9倍。适用于大规模数据分析、数据清洗、预处理及机器学习特征工程等场景。尽管存在网络延迟和资源消耗等问题,MaxFrame仍是处理TB级甚至PB级数据的理想选择。
18 4
|
9天前
|
SQL DataWorks 数据可视化
阿里云DataWorks评测:大数据开发治理平台的卓越表现
阿里云DataWorks是一款集数据集成、开发、分析与管理于一体的大数据平台,支持多种数据源无缝整合,提供可视化ETL工具和灵活的任务调度机制。其内置的安全体系和丰富的插件生态,确保了数据处理的高效性和安全性。通过实际测试,DataWorks展现了强大的计算能力和稳定性,适用于中小企业快速搭建稳定高效的BI系统。未来,DataWorks将继续优化功能,降低使用门槛,并推出更多灵活的定价方案,助力企业实现数据价值最大化。
|
9天前
|
分布式计算 大数据 数据处理
技术评测:MaxCompute MaxFrame——阿里云自研分布式计算框架的Python编程接口
随着大数据和人工智能技术的发展,数据处理的需求日益增长。阿里云推出的MaxCompute MaxFrame(简称“MaxFrame”)是一个专为Python开发者设计的分布式计算框架,它不仅支持Python编程接口,还能直接利用MaxCompute的云原生大数据计算资源和服务。本文将通过一系列最佳实践测评,探讨MaxFrame在分布式Pandas处理以及大语言模型数据处理场景中的表现,并分析其在实际工作中的应用潜力。
38 2
|
1月前
|
存储 分布式计算 大数据
【赵渝强老师】阿里云大数据生态圈体系
阿里云大数据计算服务MaxCompute(原ODPS)提供大规模数据存储与计算,支持离线批处理。针对实时计算需求,阿里云推出Flink版。此外,阿里云还提供数据存储服务如OSS、Table Store、RDS和DRDS,以及数据分析平台DataWorks、Quick BI和机器学习平台PAI,构建全面的大数据生态系统。
75 18
|
4天前
|
SQL 存储 分布式计算
阿里云 Paimon + MaxCompute 极速体验
Paimon 和 MaxCompute 的对接经历了长期优化,解决了以往性能不足的问题。通过半年紧密合作,双方团队专门提升了 Paimon 在 MaxCompute 上的读写性能。主要改进包括:采用 Arrow 接口减少数据转换开销,内置 Paimon SDK 提升启动速度,实现原生读写能力,减少中间拷贝与转换,显著降低 CPU 开销与延迟。经过双十一实战验证,Paimon 表的读写速度已接近 MaxCompute 内表,远超传统外表。欢迎体验!
|
1月前
|
人工智能 Cloud Native 数据管理
媒体声音|重磅升级,阿里云发布首个“Data+AI”驱动的一站式多模数据平台
在2024云栖大会上,阿里云瑶池数据库发布了首个一站式多模数据管理平台DMS:OneMeta+OneOps。该平台由Data+AI驱动,兼容40余种数据源,实现跨云数据库、数据仓库、数据湖的统一数据治理,帮助用户高效提取和分析元数据,提升业务决策效率10倍。DMS已服务超10万企业客户,降低数据管理成本高达90%。
163 19
|
1月前
|
分布式计算 Java 开发工具
阿里云MaxCompute-XGBoost on Spark 极限梯度提升算法的分布式训练与模型持久化oss的实现与代码浅析
本文介绍了XGBoost在MaxCompute+OSS架构下模型持久化遇到的问题及其解决方案。首先简要介绍了XGBoost的特点和应用场景,随后详细描述了客户在将XGBoost on Spark任务从HDFS迁移到OSS时遇到的异常情况。通过分析异常堆栈和源代码,发现使用的`nativeBooster.saveModel`方法不支持OSS路径,而使用`write.overwrite().save`方法则能成功保存模型。最后提供了完整的Scala代码示例、Maven配置和提交命令,帮助用户顺利迁移模型存储路径。
|
2月前
|
消息中间件 NoSQL Kafka
大数据-52 Kafka 基础概念和基本架构 核心API介绍 应用场景等
大数据-52 Kafka 基础概念和基本架构 核心API介绍 应用场景等
78 5

相关产品

  • 云原生大数据计算服务 MaxCompute