目录
核心存储-jimdb
商品优惠券的分布式任务系统
门店券的高可用
基于用户券数据的分布式存储
优惠券中台
当下移动互联网盛行的时代,APP用户爆发式增长,随着用户越来越多,用户对APP的购物体验要求越来越高,对于我们的挑战难度也随之增大。优惠券促销作为京东到家重要而又非常高效的促销手段,承载着过亿用户日均百万订单的购物体验,在整个京东到家业务中,扮演着重要角色。当用户进入我们的APP进行购物时,我们会将优惠券信息贯穿于用户每次访问过程,让用户快速感知活动力度。
将线下实体的人、货、场搬到线上京东到家的用户、商品、门店,我们通过优惠券促销将三者进行紧密关联,为用户提供优质的购物体验,又为线下门店开辟了线上资源,万千好物,即时可达。下面我将围绕商品、门店、人和优惠券来阐述优惠券核心架构设计。
核心存储-jimdb
为满足优惠券系统峰值百万级的TPS和亿级的QPS,我们使用Redis缓存存储我们面向C端的所有数据,保证了单次请求在毫秒级别,缓存治理和监控依托京东自研JimDB分布式内存数据库,具备自动弹性扩容、失效转移、主从灾备、流量过载报警等机制功能。
商品优惠券的分布式任务系统
为实现品类化运营,以商品券为主的营销场景越来越多,平台内数以万计的商品坑位需增加优惠券的利益点,为保证活动时效,需要强大的分布式任务系统来构建商品券缓存。
商品券缓存结构是String类型, key=券ID+门店ID+商品ID,value=券信息。商品券缓存构建时数据量级比较大,极限情况下一张多商家券可包含1000家门店和5000个商品。构建商品券缓存的任务数量级达到500W,整个构建过程需要在10分钟内完成。百万级的任务基于门店编号拆分成N个队列,保存至MYSQL数据表中,分布式任务1S启动一次,开启N个线程读取待执行任务。如任务产生积压,可通过横向扩容加大其吞吐能力。
使用分布式Worker处理百万级数据量的构建任务优势如下:
1.可追溯,我们先将数据进行持久化,针对每一条数据的处理都有完整记录。
2.可伸缩,如果想取消展示商品券,可以直接剔除任务表当前商品记录,同样也可以插入一条。
3.可权重,任务表中会有权重字段,针对一些重要活动,可以根据权重优先进行构建,优先展示。
4.可无锁,针对同一条数据不同写操作记录,存储在相同表中,可使用mysql乐观锁保证数据最终一致性。
门店券的高可用
到家主营o2o线上线下本地即时零售业务,基于lbs定位地理围栏内的门店为区域用户提供服务,所以最小销售粒度为门店,优惠券是到家重要的营销工具,为承载C端高流量营销场景,以门店维度的优惠券数据缓存是核心数据源之一。以下为门店券缓存的功能模块:
主题功能模块:门店优惠券、门店运费券、门店红包。目前门店未领券将近50-100张,热门门店可达200张。用户已领券大促时将近50-200张。对于未领券,有多维度库存校验,其中包括券总领取库存量、每个用户对某张券最大领取量、每个用户今日最大领取量;用户请求一次门店主页大概会涉及优惠券500-1000次缓存io交互。券信息比较多,同时券数量多,会导致缓存出流量高,门店券集群高达1.5g/s出流量。虽然有复杂的业务场景和高并发的流量,但是接口平均tp99 可做到100ms以内,门店主页优惠券接口日常tp99 50ms。
设计和优化方案:
数据源拆分:根据不同业务场景和流量入口,数据源拆分为门店优惠券、门店运费券、门店红包三套数据源。这样在单一业务场景不带出其他数据,减少缓存出流量,将大key按业务拆分为小key。
精简缓存:尽量精简缓存key,减少key的大小。同时对缓存value中的券信息字段属性进行精简,比如couponId精简为字母a进行替代。
批量查询:对于可以批量的场景尽量批量查询,使用mget一次获取,减少io。
应用隔离:将高流量的c端应用和核心交易流程进行隔离,减少高流量场景对结算页用券流程产生影响。
基于用户券数据的分布式存储
用户券是用户在领券成功后,用户和券之间的绑定关系,主要数据来源有两方面:用户浏览APP时主动领取;系统基于画像的定向推送。主要用于结算页提单,为用户带来实际优惠。
用户券主要的存储为数据库+redis,数据库主要做数据持久化,为数据部门提供有力支撑。redis是C端APP的主要数据源,为系统提供高可用。同时redis数据可通过数据库回溯,用于保证数据完整性。redis缓存结构是Hash类型,key=用户ID,field=用户券唯一ID,value=用户+券信息。领券接口TPS日常峰值达15万/min,大促期间峰值达45万/min,目前日平均发券量在5000万左右,大促期间日发券量可达上亿,总量规模约40亿左右,在系统初期我们设计单库1024张表进行存储,现阶段,增长量达10倍以上,当前单库存储已无法满足,我们又进行了分布式数据库存储,将数据再次拆分。
1. 分库分表存储,将单库*1024表拆分为8库 * 1024,增加8倍的总容量。
2. 定时定期将冷热数据进行归档隔离,归档用户已过期券,40亿条记录减少到15亿条记录,提升单表查询性能。
3. 在未来3-5年之内,可以保证数据可持续健康增长。
优惠券中台
在京东到家优惠券作为引流拉新,激活转化,促进持续消费的钩子产品,上层业务玩法层出不穷,如:线下门店拉新、自助营销定向推送、兑换红包、赔付券、品牌券等等。在日常开发中,随着不断业务迭代,玩法越来越多,我们也面临着一些问题和挑战:
面对问题和挑战,我们从系统架构上进行挑战和优化:
1.将业务层和服务层进行水平合并,抽象成中台服务,
2.业务层抽象成业务中台,多个独立业务系统组成,主要是维护不同业务玩法的逻辑和流程,当优惠券进行需求对接时,我们优先考虑在业务中台进行功能开发,保证业务的隔离性,便于后期维护和迭代
3.服务层抽象成技术中台,提供最基础最通用数据服务,以 RPC 协议形式向外提供建券、领券、展示券和用券等功能,针对一些更为通用的逻辑,比如风控,应该下沉到技术中台,一处修改,到处受用。
4.业务中台和技术中台之间通过Token进行鉴权和业务身份识别,同时Token也会绑定到业务方各自维护的券信息上,
在领券服务时,验证业务方接口传递的Token和券信息上Token是否一致,能起到一定安全拦截。
通过这次优惠券中台的实践,我们很大程度上完善了系统的健壮性和可扩展性,也提高了我们迭代开发需求的吞吐能力。