揭秘!闲鱼拉新投放系统如何设计

背景

闲鱼目前已经是国内最大的闲置物品交易平台。随着闲鱼体量的增长和用户规模不断扩大,闲鱼App上的一个普通banner抑或是feeds中的一张普通的卡片,每天都可能被数以千万计的人看到。

为了更好地服务好广大的用户群体,更加个性化的内容推荐和更加精细化的素材投放就显得尤为必要了。今天我们来聊一聊如何设计一个可以精准触达用户、运营快速试错、解放开发生产力的投放系统。

思路分析

投放是什么?举例来说,往城市广场的一块广告牌上在不同时段不同场景下更换广告画就是一种投放,当然互联网技术带来了人的维度,不同用户看到的广告画可能也是不一样的。我们来看下这样一个系统应该包含哪些功能。

1、我们把“城市广场上的那块广告牌”叫资源位,那么需要一个服务端接口来获取需要透出的素材。
2、不同资源位需要透出的素材格式可能是不一样的,可能是banner,可能是feeds,可能是运营自定义的手填数据,可能是任何合理的数据结构。
3、同一个资源位,不同时段,针对不同平台、不同人群,透出的素材可能是不一样的,那么就需要有一个服务来在一堆素材中筛选出适合资源位的内容。在资源位命中了多个素材的时候,还需要有一些机制来裁决出最终透出的那一个。

详细设计

我们设计的投放系统扮演的是前端实体资源位和后端多种数据源之间的桥梁的角色。它负责从各个业务数据源中根据一定规则筛选出在特定资源位上需要透出的数据,基本的数据流如下图所示:

资源位

所谓资源位,在我们这个体系内,是指前端页面上的实体坑位。是技术同学在产品开发中创建的。理所当然,资源位需要消费的数据结构是在开发阶段就确定了,比如banner、feeds或者结构非常灵活的手填数据等。

在我们这个体系里,我们用一个 schema 描述资源位需要消费的数据结构。

这个 schema 是用 json 描述的。技术同学在前端页面上开发实体资源位后,需要在我们的系统中创建对应的虚拟资源位,并通过一个图形化的 json schema 编辑器来定义这个资源位需要消费的数据结构

投放物料

上述 schema 定义了一个资源位所需要消费的数据的格式。但是光有 schema 是不够的,因为资源位要消费的数据,而不是数据结构本身。在我们的系统中,我们用一个动态表单模块根据schema生成动态的表单,产品运营同学通过动态表单生产的数据,我们称之为投放物料。资源位消费的就是投放物料。

对于一些手填数据,表单直接产生的数据就是资源位可用的了。但是对于 Feeds 之类的,表单往往只能定义 Feeds 的一些诸如选品等特征字段。对于这类特殊类型的数据源,服务端就不能简单的直接返回数据了,需要根据这些特征字段,做一些数据查询和数据解析工作,再返回给前端一个完整规范的数据。

投放单元

前述文章说到,同一个banner,可能对新用户投放的是红包,对年轻男孩子投放的是手机数码内容,对年轻女孩子投放的是美妆服饰。我们把这个连接了资源位、投放物料与多个投放因子的桥梁叫做投放单元。

那么投放单元需要有多少个投放因子呢?其实是视业务而定的,我们认为基础的投放因为应该包含 投放时段、投放人群、投放平台、投放AB配置等。

当资源位向投放系统发起请求拉取数据时,投放系统在这个资源位上挂载的所有投放单元中根据投放因子筛选出命中的投放单元,最后将命中的投放单元上挂载的投放物料返回给前端的投放资源位。当命中了多个投放单元时,需要有些方法来裁决出最终胜出的那一个。这个方法简单点做,可以在投放单元中配一个权重,筛选时最后选择权重高的那个,也可以引入算法决策,根据投放的 ctr 数据做排序。

投放计划

投放计划是产品运营对多个资源位管理形式。简单来说,一个投放计划下,可以挂载多个关联的资源位。试想一下,一次大促活动可能涉及到几十个资源位的投放,将这些资源位组织到同一个投放计划中进行管理,可以更加方便操作以及查看投放效果。

端侧接入

对于前端来说,我们希望通过提供一个封装的npm包,通过简单调用,传入resourceId(资源位ID) 即可获取数据。

这种调用方式对业务调用方来说是比较优雅的,但是对页面性能来说却是不省心的。因为一个页面往往由很多个资源位组成,每个资源位单独发起请求就会形成大量的并发请求,不仅页面性能会降低,还会对服务器产生比较大的qps压力。

针对这种情况,我们做了一个小优化。服务端提供一个批量查询的接口,前端SDK内部,每10ms 对模块的请求调用做一次聚合,将单个资源位的数据获取转化成批量的查询。负面影响是对部分资源位的数据加载造成最大10ms的延时,优点是提升了页面整体的性能,有效减小了服务端QPS压力。

效果

上述投放系统在我们的拉新业务实践中run得非常好,已为闲鱼应用内的数百个资源位提供投放能力支持,每天服务数以千万记的闲鱼用户。既实现了资源位的精细化投放,提高了单个资源位的利用率,又赋能运营更自由地进行各种拉新投放实验,减小试错成本,还减少了技术同学频繁参与运营实验改造的开发工作量,解放了技术同学的生产力。

总结

上述文章介绍了一个简易的投放系统的设计思路,本质上是一个连接前端实体资源位和服务端多种数据源的桥梁的设计。

其中有很多能力是依赖了团队内部其它同学努力的成果,比如:
1、描述资源位数据结构的 json schema如何设计
2、根据json schema动态生成的表单怎么实现
3、人群校验的服务和能力
4、AB测试的能力
5、feeds 的选品服务
4、个性化动态banner能力

还有很多可以优化的点,比如数据回流如何做得更好,怎样引入算法能力对策略筛选进行优化。。。持续优化、持续为业务创造价值是我们一直坚持努力的方向。


原文链接
本文为云栖社区原创内容,未经允许不得转载。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/518790.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Springboot/Cloud集成Sentinel 和 入门实战

文章目录一、Springboot/Cloud集成Sentinel1. spring-cloud-alibaba依赖2. 引入 Sentinel starter3. 配置application.yml3. 接入限流埋点4. 访问接口5. sentinel控制台二、入门实战2.1. 流控管理2.2. 快速访问请求一、Springboot/Cloud集成Sentinel 1. spring-cloud-alibaba依…

Java-变量、常量

变量 public class Demo06 {// 类变量 staticstatic double salary 888;// 实例变量: 从属于对象; 如果不自行初始化,这个类型的默认值是 0 0.0// 布尔值 : 默认是false// 除了基本类型,其余都是nullString name;int age;public …

为什么kill进程后socket一直处于FIN_WAIT_1状态

本文介绍一个因为conntrack内核参数设置和iptables规则设置的原因导致TCP连接不能正常关闭(socket一直处于FIN_WAIT_1状态)的案例,并介绍conntrack相关代码在conntrack表项超时后对新报文的处理逻辑。 案例现象 问题的现象: ECS上有一个进程&#xff0…

Docker 开发环境的滑坡

作者 | Micah Adams责编 | 徐威龙封图| CSDN 下载于视觉中国最近,我构建了一个本地开发环境,该环境使用 Docker 进行一些关键的集成测试。 在我要完成这项工作时,我意识到在开始这项工作之前,我没有考虑到这么做的一些意义深远影响…

Springboot全局异常统一处理返回json

文章目录1. 创建一个枚举、封装异常的错误码等信息2. 创建一个自定义异常类继承RuntimeException。3. 自定义异常4. 抛出异常5. 测试1. 创建一个枚举、封装异常的错误码等信息 package com.gblfy.distributedlimiter.enums;public enum ServiceErrCode {REQ_PARAM_ERR(10001, …

TableStore: 海量结构化数据分层存储方案

前言 表格存储是阿里云自研分布式存储系统,可以用来存储海量结构化、半结构化的数据。表格存储支持高性能和容量型两种实例类型。高性能使用SSD的存储介质,针对读多写多的场景都有较好的访问延时。容量型使用的是SSD和SATA混合的存储介质。对写多的场景…

Java-基本运算符

运算符 public class Demo01 {public static void main(String[] args) {// 二元运算符// Ctrl D : 复制当前行到下一行int a 10;int b 20;int c 25;int d 25;System.out.println(ab);System.out.println(a-b);System.out.println(a*b);System.out.println(a/(double)b); …

蚂蚁金服终端实验室演进之路

0. 背景 作为国民级 App,支付宝客户端需要为亿级用户提供多元化的服务,因此应用的稳定性与可靠性面临巨大的挑战,需要不断地完善和优化。 今天,让我们站在服务质量的全方位监控与优化的角度,从蚂蚁终端实验室的演进之…

2020年边缘计算最新前沿报告:如何与核心云、5G、AI协同?如何打造新业态和部署运营?...

作者 | 唐汝林、陈琪责编 | 屠敏头图 | CSDN 下载自东方 IC数据来源 | 华信咨询设计研究院有限公司在数字经济的时代浪潮中,作为关键生产要素的数字技术的快速变革已成为新常态。正当人工智能开始崭露头角时,云计算的边缘化延伸趋势又成为了另一个新焦点…

Springboot/Cloud集成Sentinel进阶实战

文章目录一、自定义限流处理1. 自定义处理类2. 请求一次测试3. 重新配置流控规则4. 重新测试5. controller二、方法限流处理2.1. 创建接口2.2. 创建接口实现类2.3. 接口调用2.4. 请求2.5. 设置流控规则一、自定义限流处理 自定义限流文档 1. 自定义处理类 package com.gblfy…

若依SQL Server开发使用教程

1. sys_menu表中的将菜单ID修改为自动ID,解决不能增加菜单的问题,操作流程如下: 解决方案如下 菜单栏->工具->选项 点击设计器,去掉阻止保存要求更新创建表的更改选项,点确认既可以保存了 2 自动生成代码找不表的解决方案…

java基础 代理

1.代理是什么? 代理(Proxy)是一种设计模式。提供了对目标对象另外的访问方式,即通过代理对象访问目标对象。 有一个类我们无法更改,但我们希望在原有类上加上我们自己的逻辑(增强),这时就可以…

使用EMR Spark Relational Cache跨集群同步数据

背景 Relational Cache是EMR Spark支持的一个重要特性,主要通过对数据进行预组织和预计算加速数据分析,提供了类似传统数据仓库物化视图的功能。除了用于提升数据处理速度,Relational Cache还可以应用于其他很多场景,本文主要介绍…

异构计算黄金时代下,超强异构计算服务器FP5468G2将会带来哪些变革?

就在几年前,计算领域还是通用计算的天下。此一时,彼一时,随着计算密集型领域的快速崛起,面对移动互联网、大数据和云计算需求的爆炸式增长,传统的单一CPU方案越来越力不从心。另一方面,半导体技术在纵向提速…

基于External-DNS的多集群Ingress DNS实践

概要 External-DNS提供了编程方式管理Kubernetes Ingress资源的DNS的功能,方便用户从Ingress管理DNS解析记录。而在kubernetes federation v2环境中,使用External-DNS可以快速的管理多个联邦集群的Ingress DNS解析,降低用户的操作成本。下面…

在执行Dockerfile时出现Get https://registry-1.docker.io/v2/错误的解决方案

文章目录1. 登录阿里云2. 找到镜像加速3. 使用阿里云镜像1. 登录阿里云 没有就注册,不要文为什么要用阿里云镜像,没办法,就是快! https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors 2. 找到镜像加速 复制内容: {&qu…

Java基础--反射

1.概念 什么是反射? (1)Java反射机制的核心是在程序运行时动态加载类并获取类的详细信息,从而操作类或对象的属性和方法。 本质是JVM得到class对象之后,再通过class对象进行反编译,从而获取对象的各种信息…

做可交互的统计图表,这套图形语法不容错过

选好可视化 “一图胜千言”,是最直观的数据可视化魅力。以图表来传达和沟通信息,其效率远超枯燥乏味的数据表达。 有需求就有市场。数据可视化崭露头角后,各个厂商出备的产品、解决方案,开发者自研的可视化工具、操作平台都如雨…

Centos7 docker 安装 zookeeper

# 默认下载最新版本 docker pull zookeeper# 指定版本下载 docker pull zookeeper:3.5.8# 创建zk容器 docker run -di -p 2181:2181 --namezk zookeeper:3.5.8# 查看正在运行的容器 docker ps# 防火墙开放2181端口firewall-cmd --zonepublic --add-port2181/tcp --permanent# 重…

10分钟带你逆袭kafka之路

作者:故事凌 1. kafka概述 ##1.1 kafka简介 Apache Kafka 是一个快速、可扩展的、高吞吐的、可容错的分布式“发布-订阅”消息系统, 使用 Scala 与 Java 语言编写,能够将消息从一个端点传递到另一个端点,较之传统的消息中 间件…