随着双11进入千亿时代,电商平台正在向“全球化,娱乐互动化,无线化,全渠道”发展。算法
为实现全民互动,电商平台会进行低价预售,狂欢红包,购物券,红包雨,商品半价,满n减1等多种促销方式。sql
每笔剁手操做都会经历一系列核心系统处理,如图:数据库
如此眼花缭乱的玩法,底层是多个核心系统的支撑,整个系统要保证在交易高峰下的海量订单有序,准确,顺滑。缓存
红包发放要保证精确预算控制,预算发放的红包总金额不能超过预算的金额。服务器
每条预算在数据库中是一条记录,在高并发场景下,可能会成为单热点瓶颈,维护过多的记录表,可能形成数据倾斜。网络
预算控制和用户无关,无需实现单元化。用户的红包信息则须要实现单元化,发放流程涉及到预算扣减,扣减操做后,用户须要尽快收到红包。数据结构
因单元化和非单元化的数据处于不一样数据中心,可能形成跨机房调用,也就引入了不肯定性。架构
因此红包系统和预算系统须要解决高并发场景下的预算扣减和用户收取红包的一致性。并发
分桶方案框架
经过分析历史数据,咱们将预算拆分为多个子预算,瓶颈分配到多个数据库中,根据红包发放请求的userId进行路由。在子预算余额不足时,路由到主预算中。 每一个子预算的扣减并不相等,确定有一部分子预算会出现余额不足的状况,因此主预算要比子预算多分配一些金额。当多个子预算余额很是少时,能够对子预算进行回收,避免预算分片的碎片化。
数据库优化
为提高记录表性能,须要对数据库操做进行梳理及优化。设想这个场景主要有3条sql:
更新语句是形成热点的瓶颈,为减小更新致使的独占锁,能够将3条sql合在一块儿,经过一次网络传输到达数据库服务器,同时在更新语句中设置余额大于等于0的条件,这样能够避免在扣减以前再查询一次余额,而仅仅经过判断sql错误码就能识别余额是否足,减小了对数据库的压力。
更新语句添加commit_on_success标签,保证事务成功后当即提交事务,不用等到客户端获取更新结果再发起commit,减小了一次网络交互,同时记录的独占锁能够当即释放。
更新语句添加target_affect_row 1 标签,保证若是知足条件的记录不存在,事务应该失败,而不是返回影响行数为0。
能够将多个事务封装成一个数据库的写入单位。总体优化后系统qps能够摸高到30w。
用户领取红包后须要在多个系统终端中进行红包展现,好比领了多少红包,金额是多少等。 统计这些会比较消耗数据库性能,同时展现红包也是比较高频的需求。采用缓存能够解决这个问题,可是随之而来的问题是缓存的失效处理。红包自己涉及多个生命周期,到底在哪一个缓解设置缓存失效是合理的呢?
在用户的红包每次进行状态变动时都会更新modify_time,因此采用读时更新缓存:
在业务规则角度进行了红包使用控制,每次只能使用10个红包,红包使用场景qps也很高放大到红包系统qps是10倍。每次红包使用须要更新10个红包状态,产生10条红包使用的流水,还须要产生至多10条红包相关的业务单据。
一次红包使用场景涉及到大量cpu资源进行sql解析,一次下单涉及到多个sql,对网络消耗较大。咱们采用batch insert语法优化插入性能,更新语句采用多条方式提高更新性能。在业务系统中生成一个大sql发送给数据库服务器,减小网络交互。
好比此次下单操做涉及到5个红包,能够经过一个sql将5个红包余额更新为0,同时加入金额锁保证红包的并发更新。设置语句的target_affect_row 5标签,若是某个红包已经被其余订单并发下单使用,事务会提交失败,能够经过数据库返回的错误码识别出这一状况。
上面的状况只是处理非单元化场景预算,系统须要在预算扣减以后写入单元化的用户数据中。两种数据处于不一样数据库,须要保证操做的一致性。同时在红包领取后,在1s内展现用户红包,这种状况通常采用跨库事务框架来解决。 但跨库事务不能作到严格的事务一致性,严格的事务一致会形成性能的极大降低,因而采用内部的一致性消息jbus实现。
jbus
jbus思想是业务在事务中插入一条消息记录,创建一套消息订阅和分发系统对消息进行处理。消息的记录和业务记录在一个数据库中,能够作到事务一致性。 多个消息订阅者能够共享一条消息记录,所以不会增长过多的数据库性能损耗。作到1s内消息消费,则能够保证用户看到本身领取的红包。
同时创建监控系统对消息挤压进行监控,能够及时发现消息的积压问题,同时在消费出现问题时进行流程完整性的保障。
下单系统涉及到访问物流系统获取运费模版,计算运费价格,以前的架构会调用远程服务,获取计算结果,这种方式会将下单峰值带到下游依赖的系统中,须要下游系统具有一样的峰值承载能力,提升了整个核心链路的成本,同时稳定性也带来了复杂和挑战。
流程前置处理后,下单系统再也不须要请求物流系统,而是直接访问运费模板缓存服务器,经过前置下单运费计算模块在本地计算出运费,减小了对于远程服务的调用和依赖,提高了系统性能,加强了系统稳定性。
随着业务玩法的愈来愈丰富,参与的团队愈来愈多,多个团队在一套平台开发形成的效率浪费愈来愈多。
为提高开发效率架构进行了升级,业务级代码和平台级代码分离,平台级代码对交易相关能力进行分类抽取,抽象提取对外提供支撑服务,业务方根据团队能力自助式定制逻辑开发,无需平台团队介入,大幅提升开发效率。
为达到业务和平台分离的架构目的,主要经过能力模型,配置模型,所生成对配置数据贯穿业务配置主线和业务运行主线来实现。
经过对交易建模,抽象,收敛,造成了交易基础能力层,采用功能域->能力->扩展点方式进行表达。
在下单环节中概括十几个功能域,优惠,支付,交付,价格,订单,结算,税费等,针对这些域进行能力扩展,同时开放给业务方进行定制,适应不一样业务场景需求。
同时引入产品概念,将多个域能力进行整合,对业务方提供知足业务功能的能力包,进一步提升业务研发效率。
整个架构中,业务能力,产品,场景属于平台能力,业务方定制功能都在业务包中,这样能够作到业务和平台分离,业务之间隔离,使得平台开发人员和业务开发人员之间互不干扰,提高总体协做和交付效率。
营销平台核心系统:
优惠计算系统能力:
交易系统和金钱打交道,稍有不慎会带来资损,因此数据一致性和业务正确性是平台最大的挑战。
挑战:
目标:
实时对帐: 底层基于storm流式计算框架,上层增长调度任务管理,数据源,对帐脚本管理,监控报警管理等模块。用户能够经过实现简单对帐脚本,完成数据对帐工做。实时对帐经过db的drc消息触发。
离线对帐: 经过定时任务,扫码db或定时拉取表数据,将须要对帐内容组成元数据消息,datacheck根据消息内容执行对应数据脚本对帐,获得最终结果。
交易相关核心链路每到大促时节,数据热点都会变成最须要解决的问题。同时对于数据一致性有必定的要求,因而好的缓存系统,作好防止热点数据击穿,提高热点数据访问效率就显得尤其重要。
三级缓存结构
特色:
如图:
热点数据缓存与驱除
两个小时内数据有效,在周期内针对数据访问qps和最近一次时间点进行排序,最后的驱除。 hotsensor针对周期内单位时间作滑动窗口,窗口长度采样采用1.5s或2h,采样窗口划分为20个格子,经过必定算法统计20个格子平均滑动窗口累计平均值。
hotsensor计算方式:
多级缓存场景中,某个key到下一级缓存查询,多key时须要组装每次查询结果,能够进行封装,统一代码风格。
利用平台提供模块化,可视化配置的技术组件,开放服务和元数据来快速定制独有商业形态,多个渠道数据进行沉淀,实现了“大中台,小前台”的业务划分,支撑了业务的快速发展和低成本创新的目标。