一、背景
1.1 什么是精细化运营?
- 用户画像:注重用户细分,深入分析用户,从用户行为、设备、渠道等维度分析用户,获得尽可能完整的用户图像。
- 精准投放:有效利用流量,不同于以往的粗放管理,更注重准确性,更注重用户保留和转化,充分挖掘现有流量的价值。
- 数据价值最大化:从多元化的数据分析角度,注重数据价值的最大化。
1.2 为什么要做?
在过去,为了提升用户从估价到下单各个阶段的转化率,业务会经常性地做一些活动投放或者用户召回等运营活动。这些活动往往都是粗投,没有细分用户群体。一是导致最终的转化率并不理想,二是不便于对不同群体的用户进行差异化的运营。
因此,希望搭建一个平台,能够根据各个阶段数据的变化,不断调整运营策略,使 ROI 最大化。
二、C2B视角下的精细化运营
C2B长期运营以来,已经有较细致的数据支撑,但如何利用这部分数据,来帮助我们的业务更好地发展,是我们想要去实现精细化运营平台的初衷。
不同的数据指标如何联动?如何用这些数据帮助我们做出决策?通过分析细化数据后,如何能够帮助我们召回更多的用户?
以用户下单后取消的数据举例:
- 用户表示价格太低:我们是否可以给这部分用户主动发放加价券,通过价格刺激再次下单?
- 用户表示备份清除麻烦:我们主动推送给用户一些清除的教程或者视频。
- 用户表示不信任平台:我们可以1v1外呼,通过客服来向用户介绍并引导,赢得用户信任。
C2B精细化运营体系
2.1 模块划分
- 用户划分: 通过不同的渠道/方式,尽可能的划分用户具体
标签画像:依赖大数据配合来获取用户画像,做到千人千面
- 估价未下单原因
- 下单后取消原因
- 质检后退回原因
- .....
收集反馈:通过一些渠道,收集用户的反馈信息
显性数据:满意度问卷调查、订单评价体系
隐性数据:客服反馈用户进线问题、IM咨询、NPS贬低回访
热点事件:已知的一些热点事件
新机发布
6.18&双11
线索收集:其它业务渠道的用户行为
B2C购机、浏览等
- 转化手段: 能够刺激用户转化的,并能搭载在触达方式里的手段
加价券、红包
1v1客服
数据清除教程
……
触达方式: 搭载着转化手段,能够精准触达至目标用户
push、短信
运营位
外呼、私域
……
三、系统设计
以任务为基础元素,通过创建计划驱动任务的执行。
3.1 任务
其实就是上文提到的触达方式,目前支持的触达方式有
- 运营类:弹窗、中通、挂件
- 推送类:push、短信
- 外呼类:私域外呼
运营通过后台创建任务,并配置任务所需的素材:如跳转链接、图片等。
任务
3.2 计划
任务创建以后,并不能被真正的使用到,需要创建计划来驱动任务的执行,计划包含以下功能:
- 时间配置:计划的开始以及结束时间
- 受众的用户:全量用户或者定向的用户群体
- 灰度:是否AB,AB实验id,AB实验组对应的任务
- 任务:具体通过哪种任务触达
计划
计划和任务关系
创建计划流程
对应上文:
- 通过用户画像平台、或者一些产品线索收集用户(B2C购机等),从而获得特定用户群体。
- 通过任务的方式来搭载我们的触达方式。
- 不同的触发方式里内嵌我们的转化手段。例如:运营位对特定群体用户发放高额加价券。
我们最终打造了一套以阿拉丁(C2B营销系统)为基础,精细化运营平台为桥梁的精细化运营能力。
精细化运营系统
3.3 遇到的难点
设计时,我们使用了Redis存储运营上传的用户数据,计划开始前完成对已上传用户文件解析储存,在任务结束时删除计划对应的用户群体。
zset缓存下用户数据后,当数据量过多时,会存在大key问题,导致在一些push场景,遍历用户数据时,会存在耗时较高的情况。
解决方案:通过用户token/uid 对key进行分片,将用户数据分散在N个Redis key中,避免单个key过大。
分片方式
//获取分片索引
private String getClusterKey(String key, String member) {
int hash = Hashing.murmur3_32().hashString(member, Charsets.UTF_8).asInt();
hash = Math.abs(hash);
final int clusterIndex = (hash & (CommonConstant.CLUSTER_COUNT - 1)) + 1;
return getClusterKey(key, clusterIndex);
}
//遍历分片进行推送
private void runSingleJob(JobInfoDto jobInfoDto, PlanInfoDto planInfoDto) {
try {
PlanUserDataCondition condition = new PlanUserDataCondition();
condition.setPageCount(100);
condition.setPlanId(planInfoDto.getPlanId());
for (int i = IntelligentOperateDataCacheService.MIN_CLUSTER_INDEX; i <= IntelligentOperateDataCacheService.MAX_CLUSTER_INDEX; i++) {
condition.setClusterIndex(i);
int pageNum = 1;
while (true) {
condition.setPageNum(pageNum);
List<Long> uidList = intelligentOperateDataCacheService.listPlanUidByCondition(condition, "IntelligentOperatePushTask");
if (CollectionUtils.isEmpty(uidList)) {
log.info("BeginSendMessageUserProfilePrivateHandler 当前分片已无可执行的数据 planId={} index={}", planInfoDto.getPlanId(), i);
break;
}
if (apolloConfigService.getJobProcessSwitch()) {
log.info("开关关闭,终止....... {}", planInfoDto.getPlanId());
break;
}
CountDownLatch countDownLatch = new CountDownLatch(uidList.size());
for (Long uid : uidList) {
ThreadUtil.execute(() -> send(uid, planInfoDto, jobInfoDto, countDownLatch));
}
countDownLatch.await();
log.info("BeginSendMessageUserProfilePrivateHandler 当前页结束 planId={} jobId={} num={}", planInfoDto.getPlanId(), jobInfoDto.getJobId(), pageNum);
pageNum++;
}
}
} catch (Exception e) {
log.info("runSingleJob error, e=", e);
}
}
四、总结
本文介绍了转转C2B业务下精细化运营平台的搭建。在系统上线以来,在用户召回转化上有了一定的成效。在未来,会继续丰富系统的功能:更多的触达方式、更多的转化手段。也会持续探索系统开放性,让更多的业务可以接入使用。
关于作者
多斯,转转C2B业务研发工程师