本文通过案例为您介绍如何使用实时计算完成数据的实时处理、多类目的管理。
背景信息
以下是天猫工程师利用实时计算实现实时多类目成交总额管理的案例。
多类目成交总额管理案例
说明 为了聚焦核心逻辑,订单数据格式做了大量精简,只保留了与案例有关的属性。
SQL结构图
操作步骤如下:

- 创建数据总线DataHub源表
系统订单是实时产生的,源表语句如下。
CREATE TABLE source_order ( id VARCHAR,-- 商品ID。 buyer_id VARCHAR, --买家ID。 site VARCHAR,--商品类别。 pay_time VARCHAR,--订单支付时间。 buy_amount DOUBLE, --订单金额。 wap VARCHAR--购买方式。 ) WITH ( type='datahub', endPoint='http://dh-cn-hangzhou.aliyun-inc.com', project='yourProjectName',--DataHub中Poject的名称。 topic='yourTopicName',--DataHub Poject中Topic的名称。 roleArn='yourRoleArn',--指定角色的roleArn。 batchReadSize='500' );
- 创建RDS结果表
RDS结果表语句如下。
CREATE TABLE ads_site_block_trd_pay_ri ( id VARCHAR, site VARCHAR, data_time VARCHAR, all_alipay BIGINT, all_ord_cnt BIGINT, primary key(id,site,data_time) ) WITH ( type= 'rds', url = 'yourRDSDatabaseURL',--RDS数据库URL。 tableName = 'yourDatabaseTableName',--RDS数据库中的表名。 userName = 'yourDatabaseUserName',--登录数据库的用户名。 password = 'yourDatabasePassword'--登录数据库的密码。 );
- 创建一个View视图
根据商品ID、商品类别、买家ID和订单支付时间做分组操作。
CREATE VIEW tmp_ads_site_block_trd_pay_ri AS SELECT id id, mod(HASH_CODE(`a`.buyer_id),4096) hash_id, site site, date_format(`a`.pay_time , 'yyyy-MM-dd HH:mm:ss' , 'yyyyMMddHH') data_time, SUM(cast(buy_amount as bigint)) all_alipay, count(distinct `a`.buyer_id) all_ord_cnt FROM source_order `a` GROUP BY id , site , mod(HASH_CODE(`a`.buyer_id),4096) , date_format(`a`.pay_time , 'yyyy-MM-dd HH:mm:ss' , 'yyyyMMddHH') ;
- 数据聚合后插入RDS结果表
把分组好的数据聚合后插入RDS结果表中,语句如下。
INSERT INTO ads_site_block_trd_pay_ri SELECT id, site, `a`.data_time, CAST(sum(all_alipay) AS BIGINT) as all_alipay, CAST(sum(all_ord_cnt) AS BIGINT) as all_ord_cnt FROM tmp_ads_site_block_trd_pay_ri `a` GROUP BY id , site , `a`.data_time ;
常见问题
Q:如何解决数据倾斜?
A:假如您的ID数据非常大,根据您的ID进行分组计算可能会造成机器热点从而导致数据倾斜,计算性能会很差。
mod(HASH_CODE(`a`.buyer_id),4096) hash_id
使用HASH_CODE这个离散函数来分离数据热点,然后使用MOD函数对哈希值进行分组操作。这样做的优点是规范每个节点数据的数量,避免大量数据的堆积导致数据倾斜(4096指的是分组的数量,可以根据数据的大小进行分组操作)。HASH_CODE函数详情请参见HASH_CODE。
Q:您得到的UV量是否准确?
A:直接使用count(distinct,buyer_id)
会出现计算不准的问题。请使用GROUP BY mod(HASH_CODE(a.buyer_id),4096)
,把相同buyer_id
过滤去重后,再进行SUM
操作,就可以避免这样的错误产生。
CREATE VIEW tmp_ads_site_block_trd_pay_ri AS
SELECT
id id,
mod(HASH_CODE(`a`.buyer_id),4096) hash_id,
site site,
date_format(`a`.pay_time , 'yyyy-MM-dd HH:mm:ss' , 'yyyyMMddHH') data_time,
SUM(cast(buy_amount as bigint)) all_qty_cnt,
count(distinct `a`.buyer_id) all_ord_cnt
FROM
source_order `a`
GROUP BY id , site , mod(HASH_CODE(`a`.buyer_id),4096) , date_format(`a`.pay_time , 'yyyy-MM-dd HH:mm:ss' , 'yyyyMMddHH') ;
DEMO示例以及源代码
根据上文介绍的成交总额管理解决方案,为您创建了一个包含完整链路的DEMO代码,您可以参考示例代码,注册上下游数据,制定您的多类目成交总额管理解决方案。使用示例时,您需要使用DataHub作为源表提供流数据,RDS作为结果表来存储结果数据。
在文档使用中是否遇到以下问题
更多建议
匿名提交