京东到家商品系统架构演进:从1.0到2.0版本的高可用高性能优化之路

2025-01-03
来源:网络整理

前言

产品系统是电商系统最基本、最核心的系统之一。产品数据分布在所有企业中。首页、店铺页、购物车、订单、结算、售后、库存、价格等都离不开产品。产品信息要稳定地提供给家居供应链的各个节点,因此必须有稳定、高性能的产品服务体系作为支撑。

随着京东到家商品业务的快速发展,业务从单一向多元化转变,系统功能设计也从最初的大而全的功能支持向微功能、领域化发展。

商业系统也在高可用、高并发的持续冲击下经历了多个架构版本的演进。最初的1.0版本采用了合适、简洁的设计思想,满足业务的快速迭代上线;随着业务规模的快速增长,2.0版本不断演进,以提高高可用性和性能。随后,业务复杂度的增加导致系统复杂度的增加。为了解决系统复杂性带来的问题,3.0产品系统领域的建设诞生了。

到家产品架构初始模型1.0 合适、简单的原理设计思路

商品系统原型

到家商品系统刚创建时,为了适应业务的快速发展,设计并上线了到家商品1.0系统。商品系统服务是基于大而全的思想,用一套服务来提供上游业务方聚合的商品数据。无论是B端业务还是C端业务,都耦合在一起,应对业务的快速迭代上线,节省开发成本。充分体现了简单性的优点。

随着业务量的增加,原有设计的弊端也凸显出来,主要体现在以下几点:

·线上B/C端业务耦合在一起,导致线上读/写业务相互影响。尤其是在重大促销期间,大量的产品修改导致C端服务不稳定。只能通过不断的横向扩展来提高稳定性,进而导致资源的严重浪费;

·服务器性能波动较大;

·简单的缓存架构,解决高并发下的缓存崩溃问题;

·监控不完善,无法及时预警;

针对以上问题,商品系统从高​​可用、高性能的出发点,演进到架构2.0;

到家商品架构-2.0高可用高性能架构模型演进

产品体系经历了1.0的快速迭代阶段后,线上流量随着业务的增长而成倍增长。 B/C端服务的高耦合导致产品服务波动较大,监控不完善也导致无法及时发现。系统异常。

为了提高商品系统服务的高可用性,商品系统制定了如下迭代计划。

·AP原则+最终一致性思想

·B/C业务分离

·远程多活动,双机架构

·限流

·监控平台

高可用演进

(1) AP原则+最终一致性思想

为了提高商品C端读服务的高可用性,采用AP原则+最终一致性的设计思想,引入分布式缓存集群来提高读服务可用性,以及数据的最终一致性通过异步消息来保证。

AP原理契合产品系统C端服务的业务场景。例如,由于网络延迟等问题,数据库没有及时将数据同步到缓存,导致当前读取的商品数据与数据库中的数据不一致。这种短期的不一致不会在业务中使用。是可以接受的。

引入分布式集群后,商用的C端读服务能力不仅提高了可用性,而且在性能方面也表现得非常好。

(2)B/C服务分离

商家通过连接开放平台接口定期修改商品信息、图片等属性。例如:在一次大促销中,我们遇到商家密集修改商品信息。导致写服务占用大量系统资源,导致读服务可用性下降。

为了提高产品服务B/C端的可用性,B/C端服务独立部署,分别对外提供服务。 B/C服务分离后,商品系统在后续的各种促销活动中表现稳定,大大提高了商品服务的可用性。在商户后续的写入操作中,产品系统从未出现过对读取服务的损坏。

(3) 远程多活动、双机架构

异地多活动——到家商品和服务所在的物理机房部署在异地多活动中。机房分布在多个不同区域,遵循“鸡蛋不要放在一个篮子里”的原则。当其中一个机房出现问题时,另外两个机房将提供服务,大大提高了商业系统应对黑天鹅事件的可扩展性。

双机架构——作为产品核心阅读服务的支撑中间件集群,采用主从模式,主分片和从分片属于不同机房。当主分片异常时,主分片自动切换。

数据备份方式为1主2备。如果主数据库出现异常,可以通过域名快速切换主备节点。整个切换过程流畅且难以察觉。

(4) 限流

产品阅读服务引入了流控组件,可以根据调用源实时配置不同的流控策略。出现极端流量后,可以对非核心调用源进行限流、熔断,为线上扩容争取足够的时间。避免突发流量异常导致整体产品服务不可用,提高产品阅读服务的可用性。

产品服务通过配置方法名称和调用源,对边缘业务调用和方法进行针对性限流。极端情况下,通过牺牲边缘服务的可用性来保证核心方法的高可用性。

(5)监控平台

产品服务采用京东监控报警平台。产品接口API可以通过UMP监控不同时间段的性能分布,实时统计TP99、AVG、MAX等维度指标。可以监控服务器的系统、网络、磁盘、容器等指标,并通过设置报警阈值实时通知指定负责人。

高性能进化

京东到家商家入驻_入驻到家京东商家怎么操作_入驻到家京东商家怎么样

商品系统服务通过高可用性的演变为我们赢得了提高商品服务性能的时间。由于1.0版本产品C端服务出现查询降级、缓存击穿等问题,导致产品系统性能受到较大影响。

例如:促销期间,高并发场景往往会导致查询性能下降->响应线程等待->线程池等待队列已满->拒绝策略,进而导致产品整体服务性能变慢。

为了提高商品系统服务的性能,商品系统制定了如下迭代计划。

·C端查询去除依赖

·持久化缓存

·数据异步处理服务

·内存缓存

(1) C端依赖

在产品1.0版本中,如果C端请求错过缓存,查询数据库将会降级,数据会回写到其中。单个请求在产品系统内经历了多次交互,并且有些逻辑与用户行为无关,例如逆写。同时,还存在严重的缓存渗透风险。产品服务器的API性能波动较大,风险也比较高。

产品C端读服务去掉了降级查询操作,B端处理对缓存的写操作。去除依赖后,产品C端读服务的性能得到了大幅提升。

(2)持久化缓存

商品系统经过C端查询降级改造后,集群中存储的KV由之前的1个月过期时间转为持久化KV存储。

去掉KV过期时间后,关键问题是如何保证数据库和集群之间的数据一致性。通过异步任务修改B端商品信息,并将数据持久化并刷新到缓存中。没有命中C端请求的KV被视为不存在。这不仅减少了产品系统内部的交互次数,还有效防止了缓存损坏。它解决了问题并最终减少了服务器响应时间。

(3)数据异步处理服务

产品最初的B/C/异步任务是耦合在一起的。 B/C服务拆分后,异步任务相互耦合。产品在修改信息、图片、属性、状态服务时,会异步回写缓存,保证 KV数据最终一致性,但大量异步任务会占用服务资源,从而拖慢B/C服务表现。

因此,产品系统构建了一套独立的数据异步处理服务,包括异步任务和消息队列,承载了产品B/C端服务的所有异步写入、回写等数据操作。

分离的异步任务平台,既保证了异步任务功能的完整性,又消除了大量异步任务写入带来的B/C服务性能波动。

(4)内存缓存

商品和服务有大量的字典数据,例如类别字典和商家分类字典。这些词典通常是商家维度的重要关键。而且,从商户维度到分片的关键哈希值相对集中。在大流量的情况下,容易出现热键问题,导致某些分片的输入输出缓冲区溢出,影响整个集群。

商品系统引入内存缓存,通过客户端服务器内存存储此类数据,不仅解决了大key和热key的问题,而且减少了与中间件的网络请求交互,大大提高了请求响应速度。

概括:

产品系统演化为高性能、高可用系统后,产品系统稳定、高可用,并在后续大推广流量的验证下表现良好。

随着商品业务的迭代和系统复杂度的增加,出现了业务耦合度高、系统扩展困难、维护成本高等问题。

到家产品架构-3.0产品体系域构建

大宗商品业务最初是线性的。随着业务复杂度的增加,商品业务逐渐从线性转变为非线性。

例如,商家打造产品后,由于操作不当,维护了错误的产品信息,导致品类产品数据异常。他需要找到一种实时监控和处理数据的方法。

再比如:商家加入到家平台,想要快速将自己的产品同步到到家。如何才能提供快速、全面的产品体系供商家使用。

随着需求复杂度的增加,产品系统的复杂度也随之增加,我们的业务开发、扩展、维护的成本也随之增加。

而且,系统复杂度的增加还带来了以下问题:

·系统错误隔离性差,可用性差。任何一个模块出现错误都可能导致整个系统崩溃;

·扩展性差。扩容只能扩展整个应用的容量,而不能扩展整个功能点的容量;

·所有服务共享同一个系统,某种方式的流量渗透会导致所有服务不可用;

为了提高系统可扩展性、缩短业务开发周期、节省维护成本、降低系统风险,在保证商品系统服务稳定性和高可用性的前提下,推出了商品系统3.0版本架构演进:商品体系领域建设。

(一)商品体系建设

首先我们需要明确商品业务的需求点,然后根据不同业务的需求点从聚合的业务中进行区域划分,根据业务区域对系统进行垂直拆分,采用分而治之的理念攻克构建商品系统,然后拆分合并独立部署以下业务域系统。

·标准图书馆系统

到家独有的UPC模板系统,为商户提供一键搭建产品的产品模板,规范商户标准产品,更好地赋能商户搭建产品。

·扩展系统

通过大数据分析,我们可以根据商户类型、经营范围等,为商户补充提供缺失产品清单,协助商户拓展产品。

·治理体系

根据到家产品的规则,管理产品的基本信息,规范准确的数据,制定产品规格。

·限购制度

京东到家商家入驻_入驻到家京东商家怎么样_入驻到家京东商家怎么操作

针对产品用户端和移动端,支持产品数量限购活动,协助商户维护单品限购。

·属性系统

拆分产品的品类属性、特殊属性等边缘属性体系。

划分完商品系统区域后,接下来我们需要考虑如何在原有系统的基础上进行系统的拆分。

商品体系拆分主要面临以下问题: 从哪里开始拆分?数据按照什么维度进行分割?服务按照哪些维度进行划分?如何保证分裂过程中系统的稳定性?

针对上述问题,我们进行了以下操作:

·自上而下的逻辑分层

·自下而上的分解方法

·业务领域划分

·缓存分割

(1)自上而下的逻辑分层

首先,选择逻辑分层,其目的是隔离关注点——每一层中的组件只处理本层的逻辑。业务层只需要处理业务逻辑,这样当我们扩展某一层时,其他层不会受到影响。这样我们就可以在某一层支持系统的快速扩展。

其次,在原有层面进行拆分,会给产品原有的逻辑功能带来很多不确定性。新增的业务聚合层可以起到上层聚合入口、下层分裂方式的作用。自上而下的结构化分解,保证了系统升级迭代的风险在很大程度上可控,同时为后续的业务拆分保持了更好的节奏;

(2)自下而上的方法分解

方法细目:

自上而下的逻辑分层后,将所有业务方法抽取到各层进行聚合,然后将自下而上的方法逻辑拆解。保持原始方法的逻辑不变,并行化一组新的级别,并确保方法遵循单一责任原则。这个过程会消耗大量的时间和精力,所以尽量根据业务聚合层来确定拆分方向的优先级(优先考虑次要业务),避免与正常的业务需求发展发生冲突。解耦本身就是一个小步慢跑的过程。一步完成这一切是不可能的。拆分方法必须经过充分的测试和验证,确保前后业务逻辑没有发生变化。

方法切换开关:

在聚合层添加一个开关,用于在新旧方法调用之间进行切换。如果新方法出现问题,随时切换到旧方法,保证在线稳定性。完全稳定上线一段时间后,可以在后续上线中移除方法切换和废弃的旧方法。

(三)业务领域划分

在逻辑分层的基础上,按照产品业务进行垂直拆分,分离品牌、属性、分类、信息、图片等业务模块,实现业务模块之间的理解和耦合。此时业务和代码层次结构已经非常清晰,可以按照模块优先级进行系统微服务区域的划分。

(4) 缓存分割

商品系统数据存储在集群中。在持续高并发请求下,输入输出缓冲流量会达到峰值,导致服务器和客户端连接中断,从而影响读服务的稳定性。虽然可以通过分片的水平扩展来解决燃眉之急,但随着数据规模的不断增长,单个集群的风险也越来越大。

根据集群中不同的数据KV,将产品拆分为主信息KV、明细KV、属性KV等独立集群,并通过异步任务增量更新集群数据。

(5)微服务架构演进——面向服务

将独立缓存集群按照业务领域进行拆分后,将服务按照业务领域进行拆分,分离出主要的信息系统服务、图片系统服务、图文系统服务、属性系统服务等。

分离的业务服务独立部署,根据各自的业务功能点合理分配机器资源。服务系统之间的垂直隔离,提高了整体服务的可用性和可扩展性,解决了因某个模块导致的整体服务不可用的问题。

前景

商品体系体系化建设不断完善。展望未来,到家商品体系的智能化、自动化、服务化建设,以及与算法、大数据领域的交互,还有很多拓展的方向。

例如:

·如何打造商品标签库智能数据采集、筛选、审核、录入系统;

·产品管理如何利用算法领域实现产品智能纠错、敏感图片、敏感文字快速识别;

对于上面的例子,我们有以下想法:

·扩充标准库中的产品数据,创建产品样品室。目的是打造国产产品的核心竞争力——快速打造产品的能力。以智能采集、筛选、审核、录入为目的,制定如下设计流程框架。通过多种渠道获取原始产品数据。首先,经过系统过滤,清理垃圾数据。然后,根据送货上门规则对数据进行过滤和排序。然后,将数据异构、符合要求的数据进行拼接组合,进入到家配送预审核。通过大数据、数据比对、算法评分等运算对数据进行评分加权,最终达到自动、智能快速审核录入的目的。

·产品治理的强弱决定了一个平台产品的质量,所以如何用系统和算法来解决人力成本是我们设计考虑的。主要设计思想是利用算法领域,通过算法和分数加权来达到管理商品的最终目标。

总结

京东到家产品系统架构的每一次演进都是与业务发展相契合的,旨在解决因业务系统复杂性带来的各种问题。 1.0阶段处理业务系统的快速迭代,2.0阶段处理业务系统的稳定性和高可用性,3.0阶段处理业务系统的体系建设。每个阶段尽量采用适当、简单的设计,防止过度设计造成更多复杂问题。

基于架构是顶层设计、贴合业务的理念,在系统优化设计的道路上,我们保持适度、简单的原则,以及持续演进的方向,不断迭代优化到家商品系统。未来的日子,我们将会遇到更多的挑战、更多的业务场景、更多未被发现的隐患。我相信没有最好的设计,只有最适合业务的设计!

分享