实时计算如何帮助淘宝实现在线「实时选品」?

简介: 随着淘宝内容化的深入发展,实时选品的需求越来越强烈。对于某些实时性要求较高的产品(SPU)而言,运营小二希望自己圈定产品池可以当天实时生效,以供创作者写文章使用。该需求对选品的实时性要求较高,比较适合流式计算的特点。因此,本文采用Blink实时流计算技术来实现该功能,实际应用中取得较好效果。

一、背景介绍

      随着淘宝内容化的深入发展,实时选品的需求越来越强烈。对于某些实时性要求较高的产品(SPU)而言,运营小二希望自己圈定产品池可以当天实时生效,以供创作者写文章使用。该需求对选品的实时性要求较高,比较适合流式计算的特点。因此,本文采用Blink实时流计算技术来实现该功能,实际应用中取得较好效果。

二、解决方案

2.1 问题分析

      要实现实时选品的需求,需要解决如下几个问题:
  • 实时触发问题:流计算必须要有触发数据源,用户提交的特征数据存储在idb中,idb如何与Blink计算流程建立关联?
  • 中间状态存储问题:Blink计算过程中,依据业务场景需要记录上一次中间计算状态,如何存储这些中间状态,并在需要时实时读取?
  • 实时生效问题:Blink计算结果需要最终在搜索引擎生效,Blink如何跟搜索引擎交互,使计算结果实时生效?
  • 增量问题:如果没有增量过程,离线全量切换数据期间,会覆盖部分已更新的数据,入如何增量追数据?
     
      针对上述问题,可采用TT+Blink+Hbase+Swift的方式解决。流程中引入TT可解决实时触发问题,引入Hbase解决中间存储问题,引入Swift解决实时生效和增量问题。TT、Hbase和Swift介绍如下:
  • TT日志:阿里日志采集系统,用户可以对日志进行订阅,TT与idb(数据库)、Blink有较好支持,是idb和Blink交互的重要媒介。
  • Hbase:开源的非关系型分布式数据库,与Blink有较好的接口交互,可用于存储和读取中间计算状态。
  • Swift:阿里搜索事业部自主研发的消息系统,目前主搜索实时都是基于该系统进行消息传输的,可基于该系统解决引擎实时生效和增量问题。

2.2 实现流程

      Blink流程被分为“日志解析节点”、“Query拆分节点”、“请求SP服务节点”、“数据处理节点”、“回写TT节点”、“Swift消息节点”6个节点,每次实时计算大致经历如下几部分:
  • 用户提交选品特征数据,数据保存到idb(数据库)并同步到TT日志。
  • TT日志更新会触发Blink任务,日志解析节点会先解析TT日志,获取选品特征数据。
  • Query拆分节点先预估SPU数量,然后根据SPU数量确定并发请求数,并拼接Sp参数。
  • 请求Sp服务节点并发请求Sp服务,获取SPU信息。
  • 数据计算节点从Hbase中读取中间状态数据,根据业务逻辑进行计算。
  • 计算结果回写Hbase数据库,用于下次计算使用。
  • 回写TT节点和Swift消息节点同时回写TT和Swift。
  • dump接受Swift消息,将数据更新至引擎,实现数据实时生效。
  • TT记录计算结果,回写ODPS,用于离线全量计算。

2.3 实现细节

      选品功能的实现主要在于Blink任务的开发,开发Blink任务前,需先了解UDF、UDTF、UDAF的概念。
      Blink开发主要集中在UDF的实现上,首先根据流计算的过程,划分出多个计算节点(例如实现流程中的“Query拆分节点”和“请求Sp节点”都是独立的计算节点),然后针对每个节点的实现逻辑,确定UDF分类,实现UDF类。以“请求Sp节点”为例说明具体实现过程:
  • 节点分析:“请求Sp节点”的业务场景是一个“一对多”的过程,因此采用UDTF类型实现。
  • 封装UDTF类:该类需要继承TableFunction,其中T为自己定义的pojo,用于向下个运行节点传递。
  • 节点输出:需要定义自己的Pojo类(上一步提到的T),这样节点的输出才能在下个节点中看到。
  • 主函数流程串联:Blink开发流程需要一个主函数将各个计算节点关联起来,达到流计算的目的,建议主函数用Scala语言开发,代码更加通俗易懂。

2.4 参考代码

      以下是“请求Sp节点”的UDTF实现代码,基本思路是将请求Sp的返回结果并发输出到下一级节点上。

public class SearchEngineUdtf extends TableFunction<EngineFields> {

    private static final Logger logger = LoggerFactory.getLogger(SearchEngineUdtf.class);

    /**
     * 请求引擎获取召回字段
     * @param params
     */
    public void eval(String params) {
        SpuSearchResult<String> spuSearchResult = SpuSearchEngineUtil.getFromSpuSearch(params);
        if(spuSearchResult.getSuccess()){
            //结果解析
            JSONObject kxuanObj = SpuSearchEngineUtil.getSpResponseJson(spuSearchResult, "sp_kxuan");
            if(null == kxuanObj || kxuanObj.isEmpty()){
                logger.error("sp query: " + spuSearchResult.getSearchURL());
                logger.error(String.format("[%s],%s", Constant.ERR_PAR_SP_RESULT,"get key:sp_kxuan data failed! "));
            }else {
                List<EngineFields> engineFieldsList = SpuSearchEngineUtil.getSpAuction(kxuanObj);
                //并发输出到数据流
                for(EngineFields engineFields : engineFieldsList){
                    collect(engineFields);
                }
            }
        }else {
            logger.error(String.format("[%s],%s",Constant.ERR_REQ_SP, "request SpuEngine failed!"));
        }

    }
}

2.5 运维发布

      目前,集群发布Blink任务并未完全实现自动化,Blink任务开发完成后,发布上线流程需要如上几步完成。任务发布完成后,可登录yarn上查看任务节点的运行情况。

三、成果总结

      功能发布上线后,运营小二圈定的万级别的SPU选品池,可实现分钟级生效,对创作者选品效率有很大提升。

四、作者简介

      作者:崔庆磊,花名:辰昕,阿里巴巴-搜索事业部-搜索系统服务平台-高级开发工程师。
15年加入阿里,主要从事内容化选品服务端开发相关工作,熟悉搜索引擎服务及流式计算等相关技术。

如果您有实时报表/实时数据大屏/实时金融风控/实时电商推荐等相关实时化数据处理需求,可以加入如下钉钉交流群!
TB1HzWqB7CWBuNjy0FaXXXUlXXa-157-150.png
相关实践学习
基于Hologres+Flink搭建GitHub实时数据大屏
通过使用Flink、Hologres构建实时数仓,并通过Hologres对接BI分析工具(以DataV为例),实现海量数据实时分析.
实时计算 Flink 实战课程
如何使用实时计算 Flink 搞定数据处理难题?实时计算 Flink 极客训练营产品、技术专家齐上阵,从开源 Flink功能介绍到实时计算 Flink 优势详解,现场实操,5天即可上手! 欢迎开通实时计算 Flink 版: https://cn.aliyun.com/product/bigdata/sc Flink Forward Asia 介绍: Flink Forward 是由 Apache 官方授权,Apache Flink Community China 支持的会议,通过参会不仅可以了解到 Flink 社区的最新动态和发展计划,还可以了解到国内外一线大厂围绕 Flink 生态的生产实践经验,是 Flink 开发者和使用者不可错过的盛会。 去年经过品牌升级后的 Flink Forward Asia 吸引了超过2000人线下参与,一举成为国内最大的 Apache 顶级项目会议。结合2020年的特殊情况,Flink Forward Asia 2020 将在12月26日以线上峰会的形式与大家见面。
相关文章
|
人工智能 JavaScript 数据可视化
AI + 低代码技术揭秘(五):代码生成和解析管道
VTJ系统实现Vue单文件组件(SFC)与内部DSL双向转换,通过@vtj/parser和@vtj/coder支持代码开发与可视化低代码设计无缝集成,适用于多平台代码生成与解析。
480 0
|
XML 缓存 JSON
为什么浏览器中有些图片、PDF等文件点击后有些是预览,有些是下载
为什么浏览器中有些图片、PDF等文件点击后有些是预览,有些是下载
1370 0
|
消息中间件 存储 负载均衡
RocketMQ 5.0 架构解析:如何基于云原生架构支撑多元化场景
RocketMQ 5.0 架构解析:如何基于云原生架构支撑多元化场景
1856 130
|
人工智能 自然语言处理 小程序
用户说 | 文科生的我用DeepSeek+AI程序员半小时开发了一个小程序
用户说 | 文科生的我用DeepSeek+AI程序员半小时开发了一个小程序
用户说 | 文科生的我用DeepSeek+AI程序员半小时开发了一个小程序
用通义万象做一个动态海报庆祝4月24日中国航天日
这段文案描述了一幅动画海报的设计理念,融合传统与现代、科技与梦想。画面以上海黄浦江为背景,明月升起象征传统,火箭升空代表科技探索。穿着旗袍的女孩和多元人群展现文化传承,火箭化为飞船遨游宇宙寓意人类追求未知。古代天文仪器与现代科技呼应,体现历史与未来的对话。整体传达对科技成就的喜悦及对未来的美好期许,致敬中国科学家与宇航员,祝福祖国繁荣昌盛。
|
安全 物联网安全 物联网
IoT安全危机:智能家居的隐秘威胁
随着物联网技术的发展,智能家居日益普及,但其安全隐患也逐渐显现。本文探讨了智能家居的安全现状、风险及防范措施,强调了企业和用户共同提升安全意识的重要性,旨在构建一个安全可靠的智能家居环境。
|
人工智能 并行计算 Java
一文彻底搞清楚数字电路中的运算器
运算器(ALU)是数字电路的核心组件,负责执行算术和逻辑运算。其设计直接影响计算机系统的性能与效率。本文详细介绍了运算器的基本结构、功能分类、设计原理及实现方法。通过分析1位全加器、多位加法器、减法器的设计,结合74LS181N芯片和Logisim仿真工具的应用,展示了4位加/减法运算器的实现案例。同时探讨了多级运算器集成、标志位应用及现代优化方向,如超前进位加法器和并行计算技术。运算器的设计需兼顾功能完备性和性能优化,未来将向更高集成度和更低功耗发展。
2146 0
|
人工智能 自然语言处理 自动驾驶
AutoGLM的一小步,人机交互进化的一大步
55年前,阿姆斯特朗登月时说:“这是个人的一小步,却是人类的一大步。”如今,这句话被用来形容智谱的AutoGLM。11月29日,智谱发布了AutoGLM Web、GLM-PC等产品,标志着AI从对话机器人进化为能自主执行复杂任务的智能体。AutoGLM能跨应用操作、执行超长任务,甚至支持“无人驾驶”上网,预示着人机交互新时代的到来。
796 2
|
Java
线程池中线程抛了异常,该如何处理?
【8月更文挑战第27天】在Java多线程编程中,线程池(ThreadPool)是一种常用的并发处理工具,它能够有效地管理线程的生命周期,提高资源利用率,并简化并发编程的复杂性。然而,当线程池中的线程在执行任务时抛出异常,如果不妥善处理,这些异常可能会导致程序出现未预料的行为,甚至崩溃。因此,了解并掌握线程池异常处理机制至关重要。
1393 0
|
安全 5G 网络安全
什么是 Wi-Fi 热点?
【8月更文挑战第24天】
5159 0