前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >小商店从0到1的系统能力构建之路

小商店从0到1的系统能力构建之路

作者头像
腾讯大讲堂
发布2021-02-26 18:10:11
1.3K0
发布2021-02-26 18:10:11
举报

作者:endyxu??腾讯WXG后台开发工程师

|导语 小商店系统设计深度解析,本文将围绕快速上线、系统优化、商家入驻、商家成交四个维度的技术思考进行讲解

小程序交易开放方案包含标准低门槛版方案(小商店)以及自定义开发版方案(交易组件)。小商店是用于帮助商家免开发、0成本快速生成卖货小程序的一款低门槛的开店工具。小商店现提供商品信息发布、商品交易、直播等功能。有兴趣的朋友可以通过小程序搜索“小商店助手” 或者?https://shop.weixin.qq.com/了解更多。

小商店自立项以来,除了产品形态上在不断迭代,开发上的核心目标也在跟随着产品战略而有不同的侧重,本文主要围绕以下几个产品战略阶段展开讨论。

01

快速上线

这个时间点的开发上的核心挑战是2个月时间搭建一套电商系统雏形。

这是一个比较考验开发个人积累的阶段,因为除了“怎么快怎么来”以外,选型的时候更需要考虑以下两点:“业界怎么做”,“后面怎么升级”。

这里我们以商品及订单系统为例:

商品体系

商品体系核心主要是解决各类关系型数据,这里数据结构设计各友商们也基本大同小异。1:N的关系型,基本就是SQL表每一行存储关系树上的一条边(id, father_id),有兴趣的同学可以翻看下面文章。

参考:电商项目数据库设计 | 第二篇:商品相关表结构

订单体系

订单的设计,我们可以围绕以下的几个点来展开讨论:

1. 多维度查询问题

(1)用户维度查询

这是我们设计上的第一考虑要点,C端用户体验,这里TDSQL自带了水平分片的能力,分片路由上我们选用了useruin,一是保证C端用户查询快,二是确保数据存储均衡。

(2)订单号维度查询

由于我们选择了useruin作为shardkey,在以订单号查询时,有两个方法来避免扫所有分片,一个是在与前端的协议上,要求所有请求都带上useruin(因为一个订单号只对应一个订单),另一个方法,也是业界常用的“基因法”,既是将useruin的部分路由信息,融合到订单号的几个固定位置上。

(3)商户维度查询

在订单量过亿(目前在百万级)之前,扫描所有分片所用耗时均在50ms以内,属于可接受级别,在当前阶段没必要过度设计。后续数据量暴涨时,我们可以使用双集群相互复制模式,既多一套以商户维度分片的存储集群,将所有商户维度的请求都走该集群,不过该方案会带来两个衍生问题:1,单表数据过大问题,需要做水平切分,后面会讲;2,集群同步延迟带来的不一致问题,我们从业务角度上考虑,是属于可接受级别的,比如商家端发货,商家端可以马上看到订单状态更新,而用户端看到需要少许延时。

(4)搜索、筛选、排序

这类请求的特点是,性能消耗大,因此,业界通用做法是使用ES作为附加索引在解决。

2. 数据切分问题

(1)垂直切分

当存储空间不足时,就需要对存储做垂直切分了,这里可以订单表与ES只保留最核心的索引数据,冗余部分最常用的数据(金额)。

(2)水平切分

目前的设计主要是使用TDSQL自带的水平分片能力,以useruin作shardkey避免单表过大问题。假如后面需要优化商户维度的查询性能,则需对商户维度的存储做定制水平切分处理。

(3)数据冷热

订单的特点是时间越久被访问的频次越低,可以按照时间维度划分冷人数据,冷数据归档到便宜的存储上,既可以让数据库瘦身保持性能,同时也能降低存储成本。

参考:

大规模订单系统解读-架构篇

微信支付核心订单系统的架构是怎样实现的?

02

系统优化

由于接入场景变多,部分场景存在抢购行为(如视频号直播)或者海量导入行为(交易组件),这些场景会给系统带来一定的冲击,因此这个阶段我们核心目标就是系统稳定性建设。

系统解耦

这是常用的降低故障影响面的套路,主要分为以下几点:

(1)主次分离:将核心业务重点隔离出来,将影响到交易,且不可降级的业务为核心业务,DB层/逻辑层均独立部署

(2)读写分离:C端读 B端写的数据可做读写分离(如商品,优惠券),降低写操作对高频读的影响,并可讲读数据简化提升读性能

(3)前后端分离:前端(展示+效果)与后端(数据+业务逻辑)解耦,方便紧急情况下后端做一些降级策略

读优化

之前由于需要快速上线,整个系统基本处于裸奔无任何cache状态,这一阶段我们对整个系统的所有读调用做了梳理,说到加缓存,其实就是以下这几个套路:

电商场景下,我们可以总结出以下几类数据:

(1)商家/商品相关:核心考虑点是保护商家上架时,用户突然间一波峰的抢购冲击,这里需要在上货时主动set cache。

(2)类目/品牌相关:属于少量数据,且变动不频繁,可做全量cache

(3)用户相关:这类数据,需要考虑点是如何做到访问DB的时机与交易时机错开,这个需要因地制宜,例如直播场景下,我们需要在用户进入直播间时预热这些数据

(4)库存相关:在售时属于动态数据,无需cache,但售罄时,需要第一时间cache住售罄状态,并将多余的流量做剪枝。

(5)商品降级数据:触发降级条件时生效,数据是正常请求时随机1%的结果去set cache,后面会详细讲。

关于如何防止缓存同时大量穿透的问题,其实有很多,如做本地+分布式的两级cache,或者stable cache等。

这一块重点想讨论的是,“如何排查出系统里面有哪些地方没加缓存”,发现未知的隐患,不然某一天一波突发流量进来了,他就是一颗定时炸弹。有人说压测/测试可以吗?可以,但前提是测试case要覆盖全逻辑链路,在一套庞大的系统面前几乎不可能。

这里我们提出了一个的监控方法:

怎么理解呢?我们假设理想情况下,DB里面所有数据有加了完美缓存,那么理论上DB的GET次数为GETuv(多少个key就访问多少次,同一个key第二次访问会被cache挡住)+SETpv(数据更新时,我们会删除缓存,所以需要额外访问一次DB),而实际的DB GET次数为GETpv次。因此我们可以根据该公式,对每一个DB的表做监控,如:

当曲线值远大于1(1为理想情况),且抖动明显时,可通过告警发现系统处理无缓存无优化状态。

写优化

说到写,在整个电商场景里面,最难的应该就是秒杀了,这也是经典的面试题。

秒杀场景的瓶颈在于热点库存的吞吐量,这里由于我们之前使用的是TDSQL的事务来做,基本上限是在100QPS左右。这道面试题标准的解法就是使用Redis集群代理模式来解决,这里我们主要围绕CAP理论展开讨论下实际使用中的一些注意点(面试干货)。

(1)租借式:同一条库存在某个时间节点只有一个DB可用(避免信息同步不及时带来的一致性问题),以DB为准,缓存只做代理租借,借出与归还都要写凭证,成交流水凭证也要同步给DB。

(2)平滑租借:从tdsql借出,到入账redis的过程,如何规避这个短暂不可交易状态?可以从业务上来考虑,在上架前完成租借,或者使用类似两阶段提交的模式,一次只租借部分的库存,保证任何时刻至少有一方有库存。

(3)redis可靠性:lua脚本保证操作的原子性;部署方案使用集群,双机热备,保证5个9的可用性;未知极端选择少卖,这里有一个技巧,所有扣库存的操作,都是先扣库存再写凭证,所有还库存的操作,都是先写凭证再还库存,确保库存当前值<=库存实际值。

(4)最终一致性:以写凭证成功为准,并在系统低峰基于凭证修复库存数。

(5)扩展性:动态扩容分桶模式,一个桶代理不够了,可以使用两个桶代理,这里我们可以对每个库存桶做一个令牌桶告警,当令牌桶水位超过50%时,自动将该库存桶的库存一分为二。由于库存分散在多个桶,可能会有碎片问题,但结合业务实际思考,能触发到扩容(至少2w/s以上的单key并发请求),其实货物马上就售罄了,所以碎片问题不会暴露。

柔性可用

如何做用户无感知的降级?在电商场景下,有一个核心思想很重要:调用峰值=min(库存数,同时购买人数),因为在商品售罄后,我们可以直接从一个复杂case变成简单case。

在突发大流量进来时,我们没必要去硬抗,确保有少部分用户(超过库存数)能正常交易就行,其他用户看到的其实都是静态页面。

这里我们在商详页的读请求做了简单的频率限制,超过3w/s(普遍抢购场景库存数都不超过1k)的请求自动加载降级页面。由于降级页面属于静态页面,因此我们可以直接做在CGI层的local cache,通过正常请求随机1%的流量去更新cache,这样即使有百万级以上的抢购流量进来时,我们只需简单扩容CGI层的机器即可,轻量的水平拓展。

03

商家入驻

当系统趋于稳定后,我们的部分精力会去思考如何辅助产品做好这个项目。

电商场景下,商家入驻影响因素:拉力与门槛。而我们是否可以从技术的角度去辅助产品降低门槛呢?

(1)OCR自动填表:优化用户多余的无必要操作

(2)自动识物:拍照即可为商家自动填充所需商品信息,“自动识图”的底层是“扫一扫—识物”的基础能力。基于识物的召回结果,首先对多个相关商品标题进行信息整合,通过Pointer-Generator-Network得到包含品牌、商品名和基础属性的精简标题;其次,采用基于AL-BERT的多标题的文本分类,提取精确的商品三级类目;此外,对召回的商品图集,通过DBSCAN的同款聚类、PHash的相似图去重、CNN的图像质量分排序,为商家挑选高质精美的商品主图。

(3)爬虫代替API模式:电商场景中,部分商家是基于API导入商品的,这个过程本质就是字段的copy。而其实该商品有对应的小程序页面,我们正在规划一种接入模式,商家只需告诉我们path,我们可以自己爬取。

04

商家成交

继上面的命题,商家入驻了之后,我们如何用技术的手段辅助商家促成交易呢?

(1)智能海报:转化率最高的传播方式,这里我们正在做一套类似阿里“鹿班”的系统,结合设计的模版与u2net像素级抠图算法智能生成花样百出的海报

(2)智能文案:多用于微商场景群聊传播,转化率高,但创作门槛也高,这里我们通过对抗网络生成离线生成营销文案库,在线场景通过倒排检索相关营销文案,辅助商家0成本创作

(3)智能视频:用户短视频消费时间越来越长,微商已经把广告投放到短视频生态中,这里我们结合设计的模板(PAG)与智能选图,智能魔性配乐,降低商品视频的制作成本,辅助促成交易

05

小结

本文主要围绕工程算法在不同的时期,不同产品方向目标下,所面临的问题,以及如何做好对应的技术决策的思考小结,很多细节本文没有展开。项目能够在短时间能上线,并取得不错的业务结果,背后有很多人的付出,感谢整个项目团队的共同努力。

近期热文

基于云原生基础设施的后台架构设计思考

云时代,我们需要怎样的数据库?

大数据AI时代的产品修炼之路:A/B测试

让我知道你在看

本文参与?腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-02-25,如有侵权请联系?cloudcommunity@tencent.com 删除

本文分享自 腾讯大讲堂 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与?腾讯云自媒体分享计划? ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 01
  • 02
  • 03
  • 04
  • 05
    • 基于云原生基础设施的后台架构设计思考
      • 云时代,我们需要怎样的数据库?
        • 大数据AI时代的产品修炼之路:A/B测试
        相关产品与服务
        云直播
        云直播(Cloud Streaming Services,CSS)为您提供极速、稳定、专业的云端直播处理服务,根据业务的不同直播场景需求,云直播提供了标准直播、快直播、云导播台三种服务,分别针对大规模实时观看、超低延时直播、便捷云端导播的场景,配合腾讯云视立方·直播 SDK,为您提供一站式的音视频直播解决方案。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
        http://www.vxiaotou.com