便利蜂智能制作策略平台的探索与实践
引言
什么是策略
在各大互联网公司中,有一个很重要的岗位:策略(算法)工程师。我们知道,前端开发工程师和后端开发工程师通常会协作开发Web、App给用户使用,那策略工程师又是干什么的呢?
这要从什么是策略说起,百度百科给的解释是:
策略,指计策;谋略。一般是指:
可以实现目标的方案集合;
根据形势发展而制定的行动方针和斗争方法;
有斗争艺术,能注意方式方法。
举个例子,在便利蜂的鲜食区,我们会售卖热腾腾的包子,有鲜肉大包、奶黄包、烧卖、红糖馒头、菜团子等等。我们也会定期的根据顾客的喜好及其他因素更新包子的口味。
打个比方,假设有30种口味的包子,考虑到陈列效果等因素,只能选择其中的20种来售卖,该如何选择呢?
策略关注的几个要点:
优化目标是什么 —— 包子的销售额
限制条件是什么 —— 最多只能选择20种包子
控制变量是什么 —— 包子的种类和数量
策略的三个阶段
注:以下为策略发展的推导,方便大家理解策略“进化”的过程,并非便利蜂实际使用的策略。
人工规则。基于少量样本和人的经验总结,形成的策略。
策略 0.1 —— “人工”智能
店员/运营根据自己的经验,为每个门店选择需要订的包子种类和数量。
比如,本周每天的包子种类和数量,等于上周对应天的包子种类和数量,如果有情报信息(比如周边学校开学了),再做对应调整。
在这种方式下,可能会出现一些badcase:
上周还够卖,这周就不够了(或反之)
以前某个种类的包子卖的好,这周突然卖的不好了
店员/运营忘了或来不及做调整,最后订多订少
店越来越多,运营扛不住了(1分钟处理一家店,100家 vs 1000家)
...
人搞不定了,那就让机器来吧,于是——
策略 1.0 —— 包子区分荤素,按比例选品给量
比如选择5种荤的,5种半荤半素的,5种素的,每种的量平分。
在这种策略下,会出现新的badcase:
某店周围写字楼里IT人士很多,他们更偏好荤和半荤的种类
某店周边有健身房,健身爱好者们对素包子情有独钟
...
统计分析。基于一定量的历史样本,对于简单变量,通过统计分析得到最优解。
策略 2.0 —— 根据历史预测未来
理由:基于门店周边客流及其特点是平稳的,可以根据历史的情况来预测未来。
统计过去一周工作日&休息日的包子销售情况,按此来选择包子种类和数量。
有特殊情报再特殊处理。
看起来在这种情况下,badcase会比较少,但实际上,还是会有各种各样的需求变化。
比如,虽然我喜欢吃鲜肉大包,但是让我每天去吃,吃几周我就会腻了,想换换口味。如果大家都和我类似,就会发现,即使一家门店的顾客不变,每天对包子种类的诉求汇总也是不一样的。
再比如,如果一家门店只卖某些口味的包子,顾客慢慢会产生一定的味觉疲劳与厌倦感,就需要上新的口味,那该替换之前的哪种口味,以及数量上该替换多少,都是策略(算法)需要考虑的事情。
优化算法(包括机器学习和运筹算法等)。针对某个明确的目标,利用优化算法得到近似最优解,容易处理多个变量。
策略 3.0 —— 选品分量的运筹算法
通过分析业务,将影响大的多种因素作为变量,使用精细化的约束条件,设定优化目标,使用运筹算法来求得近似最优解。
对于简单业务,通过上面统计分析的手段就可以解决了。但是对于更复杂的,就需要引入一些优化算法。
比如我们要做一件事,可以通过A、B、C三种方式达成,当只做这一件事时,通过统计分析的手段,可以去做评估选择。但是如果要做100件事,每件事都有这三种方式,组合是非常多的,靠单纯的统计分析已经不能够在有限的时间内得到较优的解,需要引入一些优化算法来提高解决问题的效率。
我们为什么需要策略
人适合做单点的精细化决策,而机器适合做大规模的决策。对于便利店来说,初期只有几家可以靠人来决策, 随着开店越来越多,就需要机器来为我们做决策,策略就应运而生了。
便利蜂使用算法(策略)的地方很多,包括选址、订货、陈列、排班等等,通过算法(策略),一是为我们节省了大量的人力成本,二来可以减少人工失误的发生,提高决策的效率和质量。
如何开发一个策略
我们已经知道什么是策略了,那么我们怎么开发一套策略呢?
开发策略通常分为几个阶段:
设计阶段
开发策略,首先需要做设计。在设计阶段,有下面一些事情要做。
分析历史数据
通过分析历史数据,我们可以发现业务上存在的一些问题。
设计策略
发现问题后,我们就可以开始设计着手设计(优化)策略,看通过什么方式,可以解决问题或降低问题的影响。
建模-策略部分
策略部分的建模主要包括三部分:
输入
策略(算法)
输出
通过对输入进行计算,得到输出,将这三部分串联起来,成为了一个完整的策略。
建模-系统部分
系统部分的建模,主要包括:
上游的调度方式
指上游如何触发策略,包括rpc、http、mq、定时(约定时间)等方式。
下游的通知方式
指跑完后如何告知下游业务方,包括rpc、http、mq、定时(约定时间)等方式。
数据的传递方式
指数据如何给到下游,包括通过缓存或数据库介质传递、通过http或rpc等直接传输。
异常处理
主要包括失败和超时的处理方式,如短信、电话通知等。
开发阶段
设计完成并通过review后,就可以进入开发了。在开发阶段,重点要做下面这些事。
技术选型
选择开发的技术栈,在便利蜂,我们的策略同学有对Java较熟悉的,也有对Python较熟悉的,此时选择自己熟悉的技术栈来开发即可。
开发代码
确定技术栈之后,就可以开始开发了。开发代码通常会经历以下过程:
查询数据源
读取配置
记录日志
记录中间结果
监控打点
写入/返回结果
自测
开发完成后,需要自测验证代码没bug,且效果符合预期。为此,通常会做以下事情:
查看日志确认逻辑
查看埋点数据确认关键节点数据正确性
对比结果数据确认符合预期
单步调试定位问题
验证阶段
在验证阶段,主要验证全量数据是否符合预期。那如何说明符合预期了呢?如果是单纯的去看数据,从百万、千万级的数据中看出问题来是很有难度的。这时我们可以采用一些手段:
经典手段:与同数据源的线上版本策略数据进行diff,对店级、分类级、品级的差异进行分析,看差异是否与策略预期相符。经典手段对偏差较大的差异容易识别出问题,但对差异较小的(如店品相差一两个)如果继续分析成本就巨大了。
高级手段:使用仿真平台。仿真平台模拟了门店的库存、到货、销售等数据,使用策略的结果,可以模拟计算得到门店的销售、废弃和机会损失数据。通过对比两版经营数据,可以预测上线后的效果,来决策是否可以上线还是需要继续优化。
上线和后评估
验证通过后,就准备要上线了,上线阶段会经历:
策略上线审批
策略发布
发布后线上结果验证
这一步主要是确认策略真的生效了,并且结果符合预期。
由于在验证时,是随机挑某些天来验证,可能出现错过一些特殊场景的情况。我们曾经出现过,在测试时用的是工作日,上线那天正好是周五,结果周末的数据呲了。
因此上线后跟测是很有必要的,一般会跟测3天以上。
对比上线前后经营指标
原有的策略开发模式
技术主导
在业务初期,我们没有专门的策略同学,技术同学接到类似“策略”的需求后,就直接在业务系统中开发了。
大概的开发模式如下图:
image-20210515222004654.png
在这种模式下,是存在问题的,主要包括:
策略和业务逻辑耦合,共用biz/service
业务在修改逻辑的时候,可能不经意间就改动了策略依赖的biz/service,导致策略出问题。 即使通过一些测试手段可以分析出修改的biz/service涉及到哪些使用方,将这些使用方全部回测的成本也是巨大的。
策略和业务对资源的依赖情况不同,存在资源浪费
比如策略可能是cpu密集型,而业务(尤其是Java服务)通常更占内存。为了保证策略和业务的可靠、稳定,需要申请足够的cpu和内存资源。而策略和业务,都有自己的高峰期,按峰值来申请资源,是一个巨大的浪费。
便利蜂是一家创业公司,对于这种浪费是要极力避免的,要把好钢用到刀刃上。
策略主导
随着业务越来越大,系统越来越复杂,一些“策略”逻辑交由专业的策略同学来负责。当时公司有一套策略平台,策略同学在上面开发策略的方式大概如下图:
image-20210515223006468.png
从图中可以看到,策略依赖的数据源,是由系统开发来负责的,开发好后,策略开发可以从上下文中直接获取。
策略开发会经历图中的1~6这些过程。当发现有问题时,改完代码后,需要继续重复1~6的过程。
由于环境的资源是有限的,这一整套流程下来,需要几十到数小时。如果开发时候小问题不断,一天下来也验证不了几次。
具体来说,这套开发流程中存在以下的问题:
语言支持能力
已有的策略平台是基于Java体系构建的,在这个体系下,如果要支持运行Python,通常会有几种方式:
在Java中直接执行Python语句或调用脚本(Jython)
使用Runtime.getRuntime( )执行Python脚本
将Python封装为服务,通过服务间通信方式调度
每种方法都有优缺点,这里不再赘述。已有平台采用的是第一种方法,即使用的Jython。Jython虽然可以方便的使用Java中的对象,但其只支持Python2,且对第三方模块的支持有限,想基于机器学习或运筹算法来开发策略时,就发现无能为力了。
环境和资源
如上面提到的,已有的策略平台使用的是Jython,多个策略是在同一个JVM中的,会互相挤占资源。
还好我们有多套测试环境,大家通常会占用一个测试环境来验证自己的策略。当同时开发的同学超过测试环境的数量时,就需要排队等待了。
而线上就没这么好运,当前面的策略由于各种原因延迟时,后面的策略就得等资源,即使并不依赖前面的策略数据。引发的现象就是,早上的跑数出了故障,一整天的都会受影响,各个业务都会延迟。
代码的维护
当前的开发模式类似Jupyter,将代码贴到页面上保存,策略就生效了。
这种模式有方便的一面,但从质量层面来看,有很多风险,比如可能上线的时候贴的不是最新的代码,或者并行开发的时候,互相覆盖等等。
执行效率
每个测试环境的资源都是固定的,有些小策略一次跑几十秒还可以接受,但一些较大的策略,跑一次接近1小时,如果发现问题修改重跑,一天下来跑不了几次。
尤其是,依赖的数据源在这期间时可能发生变化的(比如恰巧此时上游也在进行测试),两次diff结果的不一致,可能并不是自己策略的变动带来的,这就严重降低了开发自测的效率。
问题定位
当出现问题的时候,我们通常会看输入是什么,基于这个输入,走了什么逻辑导致了错误的输出。
但是当前的平台下,如果不把输入数据全部打印下来,就无法拿到的。但全部打印下来,数据量又太大,这就对排查问题造成了很大的不便,有时定位问题需要耗费很长时间(比如线上有问题,但是在测试环境缺没有问题)。
策略平台的探索
我们发现,由于存在上面提到的这些问题,策略的迭代效率提升不上来,平台亟需改造完善,为策略赋能提效。
这时我们面对几个选择:
基于现有平台进行迭代优化
现有平台是基于SSM(Spring+SpringMVC+MyBatis)开发的,策略的调度、运营和业务逻辑存在一定的耦合,如果基于此进行重构,需要重新梳理逻辑,并将业务部分剥离。而这期间,策略还需要正常迭代。
在当时来看,由于没有足够的人力,选择这种方式成本和风险均较高。
选择市面上的开源平台
市面上有一些流式或批的策略调度(执行)平台,如Flink、Spark、Storm等,这些都无法完全满足我们的需求,没法直接使用,但可作为我们策略平台的一部分。
自主构造一个全新的平台
最后选择的这种方式,选择使用Spring Cloud Dataflow作为策略的执行、调度引擎,构造一整套策略平台。
选择Spring Cloud Dataflow主要基于其可支持Java和Python类型的策略,与团队的技术栈相匹配,没有额外的学习成本,能够快速上手开发策略。
这个新的平台,主要关注以下几点:
质量
效率
成本
标准
安全
模型定义
image-20210516134139207.png
策略组(StrategyGroup)
一系列策略/算法的集合,用于区分不同的策略(团队)。数据权限管理也会基于策略组。
策略流(StrategyStream)
策略组的下一级,表示一种策略/算法。
策略会不断的迭代(版本更新),但这些版本的策略具有相似(或相同)的结构,把这部分抽象出来,叫做策略流。
策略流通常会包括三类节点:source、processor和sink:
source负责将执行进行拆分,以提高并行度;
processor是具体执行策略/算法的地方;
sink负责将执行的结果进行存储。
策略(StrategyInfo)
策略流的下一级,表示某种策略流的其中一个版本的一类节点(如source节点)。
发布和部署镜像的最小单位。
策略任务(TaskBaseInfo)
如上图的任务1和任务2,策略任务是基于策略流 + 指定版本的策略/算法。
同一种策略流可同时运行多个策略任务,通过黑白名单控制生效的门店(或其他业务code),以实现AB测试等功能。
策略任务执行(TaskExecutionInfo)
策略任务的一次触发,即为策略任务执行。
策略任务执行明细(TaskExecutionDetailInfo)
策略任务执行中的一个“分片”,source节点返回list中的每一个元素构成一个策略任务执行明细。
策略任务执行的最细粒度。
策略调度
技术选型:Storm、Spark、Flink、Spring Cloud Dataflow
Spring Cloud Dataflow(简称scdf)
https://spring.io/projects/spring-cloud-dataflow
https://dataflow.spring.io/getting-started/
其中Data Flow Server主要为scdf服务的提供方,包括Web和Shell页面的交互等。Skipper Server主要负责策略节点的部署。
由于其暴露了一系列的RESTful API,可以将scdf方便的集成到系统中:
查看stream列表
查看某个stream详情
创建/更新stream
弹性伸缩 https://dataflow.spring.io/docs/feature-guides/streams/scaling/
策略运行时
image-20210516134612259.png
策略运行时如图中描述,策略触发后,source、processor和sink节点依次进行处理,最后由source节点判定各个执行明细的状态,更新主任务的状态。
日志埋点
image-20210516134729699.png
通过EFK,将策略中的日志和中间结果埋点收集到ES和Hive中,供策略同学进行分析。
结束语
以上和大家分享了便利蜂智能制作团队在策略平台上的探索和实践,在使用的过程中,我们也不断的对平台进行改进和优化。读者朋友们有想法或建议的话,欢迎留言交流。
如果你对相关的技术、策略感兴趣,欢迎加入我们。可投递简历至:tech-hiring@bianlifeng.com(邮件标题注明:便利蜂智能制作团队)。
作者介绍
马同学,便利蜂智能制作团队的一名后端开发工程师,参与过公司ERP系统的建设,也做过鲜食制作的一些策略,后与组里的大神们一起酝酿出了此策略平台。目前正和小伙伴们一起,为“品质生活 便利中国”的使命愿景贡献自己的一份力量。
招聘官网
https://bianlifeng.gllue.me/portal/homepage
了解更多职位详情
便利蜂智能制作策略平台的探索与实践相关推荐
- 得物App数据模拟平台的探索和实践
导读 Mock是一个接口编辑模拟工具,可以快速手动或者基于YAPI创建Mock接口模拟数据调试,同时支持场景,场景组的快速切换,方便在开发期和测试阶段试验不同数据返回的UI功能逻辑. Mooncake ...
- 爱奇艺全链路自动化监控平台的探索与实践
点击"开发者技术前线",选择"星标????" 让一部分开发者看到未来 来自:爱奇艺技术团队 1 前言 互联网技术普及过程中,数据的监控对每个公司都很重要.近些年 ...
- 工商银行打造在线诊断平台的探索与实践
作者 | 刘慕雨 中国工商银行软件开发中心云计算实验室 在信息系统建设方面,工商银行一直积极探索,以开放的姿态借鉴行业先进经验,旨在为客户提供更优质的金融服务和用户体验.随着分布式架构和云计算平台在工 ...
- web平台安装程序_工商银行打造在线诊断平台的探索与实践
作者 | 刘慕雨 中国工商银行软件开发中心云计算实验室 在信息系统建设方面,工商银行一直积极探索,以开放的姿态借鉴行业先进经验,旨在为客户提供更优质的金融服务和用户体验.随着分布式架构和云计算平台在工 ...
- 京东到家自动化测试平台的探索与实践
目录 一.引言 二.维护测试用例 2.1 HTTP流量复制 2.2 微服务流量复制 2.3 自动生成种子用例 2.4 收益评估 三.自动化回归测试 3.1 接口自动化 3.1.1 设计方案 3.1.2 ...
- 有赞业务对账平台的探索与实践
一.引子 根据CAP原理,分布式系统无法在保证了可用性(Availability)和分区容忍性(Partition)之后,继续保证一致性(Consistency).我们认为,只要存在网络调用,就会存在 ...
- 新零售赛道上,便利蜂的美食牌
螳螂财经|易芳 世界上第一家真正意义上的便利店,是1946年的7-Eleven,20世纪70年代初,日本伊藤洋华堂与美国南方公司签订特许协议后,便利店在日本得到飞速发展,20世纪90年代末期进入中国, ...
- 爱奇艺智能前端异常监控平台的设计与实践
背景 前端监控一般包括三方面:异常监控.性能监控(First Meaningful Paint.First Contentful Paint等性能指标监控)及行为数据监控(PV.UV.页面停留时长等监 ...
- 爱奇艺全链路压测探索与实践
背 景 爱奇艺除了每天都为数以亿计的用户提供优质的视频服务,同时还有体育.直播.文学等业务服务于更多的圈层用户,海量的业务几乎每天都在进行营销活动,由此带来的流量随时可能会给我们的服务引入不确定性.爱 ...
最新文章
- Unity使用 16bit 压缩 Texture 颜色能均匀过渡
- ubuntu 20上安装gdbgui
- 高效幂运算(JAVA)--拆分解法、二进制解法
- win 系统 32X- 64X 任意安装方法
- 7-25 念数字 (15 分)
- 1命名规则 sentinel_Sentinel实战:为系统做限流保护
- 如何使用利用LaTeX制作个人简历
- MySQL教程(十二)—— 数据的导入与导出
- 如何使用python批量压缩图片_利用Python 批量压缩图片
- arcmap中加载底图
- 基于CAD二次开发的道路纵断面竖曲线计算原理与编程自动绘制方法(以C#为例)
- 记一次失败的面试经历
- Ubuntu 自带截图工具快捷键盘
- python隐藏源码,生成pyd文件并调用的完整过程
- 【翻译】Kinect v2程序设计(C++) Depth编
- 音视频开发 人脸标定 animoji 动态贴纸 小项目练习总结
- 软件测试基础知识bbst,海盗派测试分析MFQPPDCS海盗派.PDF
- ENVI标准格式文件转换为.tif文件——基于ENVI库函数
- python下载图片插入excel_Python向Excel中插入图片的简单实现方法
- 计算机启动后 不显示桌面,电脑开机后不显示桌面怎么办?