知乎、舰桥平台、营销平台、活动平台、内部投放平台、CDP(客户数据平台)、Doris、Elasticsearch(ES)、Spark、Flink、Golang
01
背景和由来
1.介绍
2.能力地图
3.快速了解什么是内部营销
上面的3个图分别为营销活动的话题页、落地页和对应的玩法(目前的这个活动是任务积分兑换玩法),与此同时连同宣传页、资源投放和对应的活动监控就形成了完整的内部营销的业务能力,这就是内部营销平台面对的业务场景。
02
业务逻辑梳理
1.内部营销的目的
目前我们接触的内部营销场景,无非是达成以上目标,促进用户增加、促进用户消费、促进内容生产、促进问题生产、促进创作者变现。
(2)促进内容生产(促进创作者增加):这部分是通过活动的手段,定向激发用户生成优质内容,如回答、短内容等。
(3)促进创作者变现:创作者是内容生态的重要组成部分,支持、激励他们创作并从中盈利,是保持内容生态的活力和吸引力的重要方式。
2.营销和用户&创作者的生命周期的关系
营销是激励过程,通过营销过程会促进如下阶段的循环。具体描述而言就是营销相当于一个发力器,会在各个生命周期的阶段,对用户推一把。在短期促进用户向营销期望的方向产生明显的行为变化,并促进用户扭转。扭转过后,如果对应生命周期的功能能够比较好地承接,用户留存是正向的,用户就完成了该方向的转化和承接。简而言之,营销可以短期改变用户行为到我们期望的目标行为,长期需要看产品力是否能承载和留住用户。以下为用户各生命周期,箭头为可通过营销动作的促进快速转变的方法。
3.内部营销的闭环逻辑
达成以上目标的过程内部营销简化后可以描述为:通过某种触达渠道进行推广,针对目标受众,使用某种激励或营销手段,促使用户或创作者达成某个转换目的。所以触达渠道、目标受众和激励或营销手段就组成了三位一体的内部营销主逻辑。
03
产品功能概念
1.CDP(客户数据平台)
2.活动平台
活动平台是进行营销活动设计和运营的地方。通常会包含活动策划、执行和分析三大步骤。
3.内部投放平台
内部投放平台是将设计好的营销活动推送给用户的平台,包括但不限于资源位投放、信息流内容投放、主动触达等。
04
业务架构
宏观架构
业务架构主要分为四层,分别是业务能力层、共享服务层、业务模型层和外部接入层。
业务能力层:这里是内部营销平台的核心业务能力,主要包括CDP、活动平台、内部投放平台和内部营销分析&诊断。
共享服务层:这里是为了搭建上面的业务能力,所抽象出来的通用共享服务,避免在技术上和业务上重复造轮子的共享服务。
业务模型层:这里主要是隔绝了接入层和业务层,将外部的各类数据和RPC抽象成在内部通用的数据模型,内部开发只理解内部模型,接入层只理解如何将物理原始事实完成接入,提高了平台开发的效率。
外部接入层:这里集成了多种外部接口和协议的接入工具,以及提供低成本快速接入新的业务事实的脚手架,降低接入成本,提高接入效率。
子系统架构
活动平台
CDP(客户数据平台)
内部投放平台
用户行为系统UBS(UserBehaviorSystem)from大数据团队
内容事件中心CEC(ContentEventCenter)
舰桥事实共享服务
05
挑战及难点突破
1.活动平台难点突破
任务达标->获得积分以及积分消耗->获得奖励->奖励到付,不多不少
任务达标->获得积分:可靠事件队列+幂等+最终一致
这种情况使用可靠事件队列发生任务完成下发积分的消息。积分系统监听该消息,配合积分系统和任务系统间唯一key做幂等性保障了atmostonce,再通过无限重试保障了atleastonce。从而保障最终一致。
积分消耗->获得奖励->奖励到付:TCC
活动平台中存在的几个子系统:任务框架、瓜分框架、抽发刮兑奖模块、用户奖品模块、权益模块。其中最核心的一个工作是,在任务达标后产生的任务完成记录,任务完成后在用户奖品中的获得奖励记录和奖励实际下发到用户这三者全局一致,不多且不少。
针对这一问题我们的解决方案是使用TCC模式的分布式事务,TCC是“Try-Confirm-Cancel”三个单词的缩写,是由数据库专家PatHelland在2007年撰写的论文《LifebeyondDistributedTransactions:AnApostate’sOpinion》中提出,具体如上。
奖品和权益的库存上限
在整体的奖品和权益下发过程中,存在两个库存,一个是活动的奖品有最大上限,另一个是某权益,例如超赞包,有最大上限。为了解决在完成任务和用户兑换过程中的承载能力,我们通过预占提交+MQ和定时脚本同步状态的方式来保障高并发下的库存限制,具体如上。
活动总积分下发上限-分而治之
分而治之,提前将积分按照号段划分成多块,每次完成任务后,随机进入一个存活号段(如果号段内无积分的话,则认为该号段失活)进行发放,如果有号段存活,完成发放;如果所有号段失活,则返回超发并拒绝。
复杂任务系统的抽象
原子任务
目前活动平台->玩法引擎->任务框架的难点是如何将复杂的任务流程和架构进行适当的抽象,从而方便配置和实现。原子任务的配置,一个原子任务的复杂性主要来自任务自身的灵活性和业务特征增多,会随着业务发展可选项和灵活程度越来越大,涉及的规则的适配性,特征的完备性就决定了一个任务系统可扩展的上限。在这里我们将任务按照模板类型进行拆分,同时将每个模板的子模板通过可配置的规则引擎予以解决。
任务编排
另一方面,当原子任务支持后,任务间的依赖关系以及任务的类型和性质差异性,都使得任务管理变得富有挑战。这就需要我们寻找一种方法来抽象这些复杂性,使得在面对大量的具体任务时,我们可以有一个整体、宏观的角度去理解和控制这些任务。
对此,我们如上图,将不同模板类型的任务进行抽象。我们必须抽离出任务的共性元素,例如任务的分类、优先级、依赖关系,从而建立一个易于理解和操作的抽象结构。同时这种抽象结构需要能够灵活地适应新的任务类型和状况,以便于我们更好地应对未来可能出现的挑战。
通过实施这样的抽象化策略,我们能够更好地理解和掌控复杂的任务系统,并针对其共性的部分做到可扩展的、通用的设计。同时降低了新人理解和上手整个系统的难度,从而提升了工作效率。
2.内部投放平台难点突破
投放渠道多
如上图的部分渠道所示,在进行内部投放过程中,所面临的一个特别复杂和棘手的问题,就是投放的触达点散布在APP、PC的各个位置,同时不同资源负责人也不同,因此不可避免地在进行投放过程中,需要与各个业务线进行深入的沟通,这无疑会提高投放的成本和难度。
用户定向难
在执行具体内容投放时,寻找和匹配目标用户是一个复杂的过程。在这个过程中我们的目标是让更多的人能看到并提高点击、阅读等转化率。目前我们积累了3种方法:运营人工圈人群包定向;策略自动圈人群包定向;算法内容找人定向。其中第二点是舰桥提供的策略,根据内容属性找到用户兴趣,快速生成对应的人群包并进行投放。第三点需要推荐团队细致地对内容信息和用户画像进行深入分析,并完成合理的匹配策略和匹配过程。
任务链路长&状态密集
如上图所示,在内部投放平台的建设中,一项复杂且具挑战性的问题是任务链路很长以及任务的状态密集。投放的过程中,整个链路线路径需要经历多个关键步骤,包括任务的创建、目标群体的生成、投放任务的提交、任务状态的更新、投放数据的更新等等。这些步骤不仅需要在不同状态间进行细致的操作和状态的扭转,还要伴随着各种子节点的降级处理和重试策略。
简单来说就是,当任务在链路中传递时,需要处理大量的状态转换,并且需要有可靠的方法来处理可能的失败情况。如此迂回复杂的过程,客观上加大了任务的调度难度。我们依靠舰桥提供的一整套完整的任务链路,底层基于Workflow框架来处理这个问题。这不仅优化了工作流程,更重要的是确保了任务在传输中的可靠性,为高质量的完成任务提供了可能。
资源管理
在投放过程中进行有效的资源管理,一方面提升资源投放的转换效果,另一方面也能控制资源使用,以防止资源的过度使用或滥用。如何通过一种机制来保证资源的合理分配,也是这一业务建设的难题。
针对此问题,我们运用舰桥建立的一套虚拟组作为唯一标志。在这套机制中,我们提供了为不同虚拟组赋予不同资源量的能力,并由资源负责人和资源申请人拉齐资源配比。同时,我们还引入了成本和效果分析,并辅以奖惩机制,仅将资源分配给那些能够有效使用它的团队,确保资源得到最有效的利用。
这套策略不仅使资源的使用变得更为高效,还通过奖惩机制对利用效率的监控,使得价值观正确且更加符合公司需要的内容得以被分发。我们会定期分析资源使用的实际效果,评估和调整我们的资源分配策略,进而促进资源的有效利用和优化。
借助这套机制,我们解决了资源配置的问题,可以专注于优化投放效果,消除资源滥用的可能性,确保我们的资源得到最有效的利用。
3.CDP(客户数据平台)查询性能调优
背景与难点
当前CDP系统中有两大功能,第一大功能是人群定向,另外一大功能是人群洞察。基于这两大功能有一个底层的功能是建设各种用户的画像特征。当我们完成拆解之后就会发现人群定向的这部分功能是运营侧或业务侧的痛点。
场景要求
人群圈选,针对热点运营。运营侧在日常工作中会持续跟进发生的各种热点事件,当发生了某些热点事件后,要快速地圈选出人群包发布Psuh和推荐。如果圈选过程需要好几分钟,就会错过热点事件。
难点
第一个数据量极大,如上图标注。
性能优化(1)
第一阶段优化我们通过了以下几点来解决这两个问题:
倒排索引和按条件查询
首先,倒排索引方面,我们将查询条件由原先的andornot改成了bitmap函数的交并差;同时把连续数值打散成为离散标签。举例:用户的年龄是大于0,小于100的int型,如果按照数字顺序进行筛选,运营侧是不好把控的,圈选的过程中会导致使用效果不理想。因此我们把按照顺序排列的年龄打上另外的标签,称为年龄段,比如18-25,0-18等。
查询逻辑变更
原先的查询条件是where条件中的and、or、not,现在经过复杂的手段,把原先的查询条件修改成bitmap_and,bitmap_or,bitmap_not,我们通过业务代码,将外部运营通过可视化后台配置的and、or、not的逻辑全部改为函数式的逻辑,相当于把where条件放到了函数和聚合逻辑之中。
但经过优化之后还会存在2个问题:
第一个问题是单一的bitmap过大,第二个问题是bitmap的空间分散。这两个问题集中导致每次进行交并差聚合时网络IO特别高。
底层Doris中用的是brpc。在数据交换的过程中,因为每一个单一的bitmap都很大,就会导致brpc传输拥堵,有时甚至会出现上百兆的bitmap进行交换的情况。上百兆的bitmap进行交并差计算时性能很低,基本上我们想要它达到1分钟圈选人群,1秒钟进行人群预估是不可能的。
性能优化(2)
基于仍存在的问题,我们进行了第二阶段的优化。
分而治之
第二阶段的核心思路是分治。当我们进行了第一波上线后,发现人群预估能力是分钟级别,圈选基本上要到10分钟开外了。分治的思路是将全站的用户全部打成连续自增ID后,按照某个程度进行分组。比如说0-100万是一组,100万-200万是一组...逐渐分为几个组别。全站用户的交并差,可以等价于分组之后的交并差结果之和。
数据预置
算子优化
全部放到某一个物理机上之后,就可以把聚合的算子由原先bitmap_and_not的bitmapnot和bitmapcount替换成一个函数来实现。此时基于Doris团队的新版本,增加了类似bitmap_and_not_count的组合函数后,性能相对于原先的嵌套函数有了比较明显的优化。
4.舰桥共享事实服务离线事实导入性能提升9倍
问题及背景
CDP(客户数据平台)依赖的舰桥事实共享服务中,面向人群圈选、画像洞察的功能是基于Doris建设的。其中标签数据更新分为:
离线批量更新:数据源->Spark->BrokerLoad->Doris。
实时流式更新:数据源->Flink->RoutineLoad->Doris。
SparkLoad介绍
原始数据存储在hive表中,用doris来做实时数据分析工具,doris本身支持hive外表,但性能存在瓶颈,为了提升doris分析性能,初期的方案是定期把hive表的数据,通过brokerload从hdfs导入到doris中,过程如图:
这个方案开始运行还算平稳,后期随着数据量的增加和导入任务数的增多,问题逐渐出现。直接表现就是:
问题发现
观察监控可以发现:导入任务运行时CPU下降的比较明显,同时磁盘I/O保持在低水平(SSD盘),说明在导入时cpu算力是个瓶颈,因为导入时需要排序、解压缩、分桶计算,这些都是CPU密集型的操作。
同时Yarn集群的算力存在潮汐现象,集群空闲可以将成长导入过程的计算卸载到Spark上,以充分发挥各自的优势。
踩坑集锦及问题解法
最终效果
上面关键问题解决后跑了一个全量的任务,数据1.2TB,数据行数1100亿+,整体耗时缩短至55分钟,相比之前brokerload需要8小时,整体导入性能提升了9倍以上,数据导入的时效性问题得到解决,同时集群的负载也降低了。
5.CDP圈人&活动分析&投放诊断场景,极限压榨集群性能-全局向量化
(1)使用场景
OLAP引擎bitmap倒排表,通过交并差,快速预估并完成筛选、打包能力。
追踪明细表:每一时刻的数据明细,用于浏览和异常异动报警计算使用。
(2)集群配置
集群
配置
旧集群(未开向量化1.0.0)
3FE+32BE内存256G;CPU64核;磁盘:32*4THDD
新集群(向量化1.1.2版本)
3FE+19BE内存256G;CPU64核;磁盘:19*4THDD
两个除BE个数外其他配置均保持一致
(3)核心场景查询耗时对比
案例1:多维度(以6种维度为例)筛选、单表查询、单日期指标宽表、数据聚合SUM,每天数据量为1.8亿+
关闭查询缓存、关闭向量化查询:6.99sec
关闭查询缓存、开启向量化查询:2.00sec
关闭查询缓存、关闭向量化查询:56.99sec
关闭查询缓存、开启向量化查询:8.31sec
案例3:单表查询、COUNT计数,每天数据量为1.8亿+
关闭查询缓存、关闭向量化查询:3.25sec
关闭查询缓存、开启向量化查询:0.64sec
案例4:3张表查询;A、B、C表每天的数据量分别为1.8亿+、150万+、其中B表涉及BITMAP聚合,A表涉及每天数据SUM聚合、COUNT聚合;A、B先聚合再与C表JOIN,子表再依次JOIN;查询过程中JOIN次数共为6次。
关闭查询缓存、关闭向量化查询:7.87sec
关闭查询缓存、开启向量化查询:3.17sec
案例5:明细分析、单表查询、每天的数据量为5亿+
关闭查询缓存、关闭向量化查询:7.06sec
关闭查询缓存、开启向量化查询:4.23sec
案例6:向量化查询在SQL实现逻辑优化中的应用关闭
以theme&iw1.0版本领域所属theme&iw为例,现将领域所属theme规则应用于领域所属iw,规则如下:
关闭查询缓存、关闭向量化查询:0.38sec
关闭查询缓存、开启向量化查询:0.27sec
案例7:圈人-普通圈人条件、数据量100w+
关闭查询缓存、关闭向量化查询:2.7sec
关闭查询缓存、开启向量化查询:0.2sec
案例8:圈人-复杂条件圈人,数据量10亿+
关闭查询缓存、关闭向量化查询:27.62sec
关闭查询缓存、开启向量化查询:2.47sec
案例9:圈人-分表join圈人,数据量1亿+
关闭查询缓存、关闭向量化查询:3.21sec
关闭查询缓存、开启向量化查询:0.88sec
结果汇总如图所示
根据以上线上真实结果所示,Doris1.1.2版本相比Doris1.0.0版本性能提升显著,对于大部分场景有2倍以上提升,少部分查询有近14倍的性能提升,效果好于预期。
(4)调优实践
FE下发fragment超时问题
sendfragmenttimeout.backendid:xx,host:x.x.x.x
支持返回二进制bitmap数据
Github链接:
06
未来展望
内部营销平台发展的大方向是:营销数字化->营销自动化(MA)->营销智能化。
1.内部营销全面数字化
为应对这些问题,我们采用了AB实验这一数据驱动的归因工具。举例来说,如果我们在两种UI设计之间无法抉择,那么我们便可以通过AB实验来确定到底是设计A更优秀,还是设计B更出色。
为了实现此目标,我们计划将AB实验功能整合到了我们的内部营销平台的活动平台和内部投放平台中,从而增强了我们的活动页、文案等的AB测试能力。这一集成不仅将提升我们的系统效能、为我们提供科学的决策依据,而且将为我们未来的目标定制化营销方案提供强大的支持和保障。
2.内部营销自动化
营销之父科特勒2022的演讲中提到:剧变时代,好营销的27条准则中,第一条就是:未来的营销会越来越自动化,人工智能也会更多地参与到市场营销之中。但最好的营销方式仍然是人与人之间的沟通,我仍会用H2H(humantohuman)来表达这一概念。人与人之间的表达才是最关键的,无论是与物流、消费者、生产者或分销商沟通。他强调了营销自动化和人工智能在未来营销中的重要地位,但我们明白,即使在高度自动化的背景下,H2H(humantohuman)也是不可忽视的。舰桥平台一直以来的策略是将高科技融入人际互动中的。
INTRODUCTION
候容
知乎
舰桥平台Leader
李宁宁
舰桥平台架构师
自20年入职知乎,专注私域社交、用户和账号服务、实时数据处理及内容运营架构等领域。擅长对团队现有架构的深刻洞察,发掘并应对业务发展中遇到的各种瓶颈,尤其是那些可以通过架构优化提升业务迭代效率的难题。策划并推动用户体系构建、实时数据处理和内容运营架构向更具前瞻性和可持续性的方向演进。带领研发团队成功实施关键架构的升级,使平台服务更加稳固、灵活,为应对未来挑战打下坚实基础。