电商新系统如何应对峰值

唯品会11.11:峰值系统应对实践:https://www.linuxidc.com/Linux/2015-11/125124.htm

为了保证系统在高并发、大流量访问下工作,并且使系统有较强的扩展性,我们的设计主要从以下几个方面展开:

          • 系统模块有效切分
          • 服务化解耦,集中服务治理
          • 增加异步访问
          • 多阶段缓存,降低后端压力
          • 优化数据库访问
          • 加强系统监控

服务限流

在系统流量达到极限时的情况,有自动熔断机制。熔断器是在服务或者周边环境(如网络)出现了异常后主动断开客户端后续的使用,从而避免服务崩溃无法恢复。但是在后续时间熔断将使用小量请求尝试侦测服务是否已经恢复,如果恢复则将服务再次提供给客户端调用。熔断器的机制即保护了服务也减少了人工干预。相关的阀值都在是在配置中心中配置,并支持动态修改生效。限流一定要谨慎使用,要使用恰当的限流策略,区分正常访问和恶意请求,不能将正常的用户请求抹杀掉。如果无法区分是否是恶意请求,需要将应用分级,确保优先级最高的应用能被访问到,比如所有上线的商品信息。而对于下线的商品信息,可以根据请求容量作适当的限流。

服务降级

对于电商系统,为了保证用户体验,在资源有限的条件下,我们必须保证关键系统的稳定性。通过对不同业务级别定义不同的降级策略,对除核心主流程以外的功能,根据系统压力情况进行有策略的关闭,从而达到服务降级的目的,例如在线商品信息,我们必须保证优先访问,而对于下线的商品信息,我们可以容许在访问容量受限情况下,容许关闭下线商品详情页面的访问等。

增加异步访问

分布式异步消息队列服务器可在宕机后确保消息不丢失,异步系统有重试机制,从而提高系统可用性、健壮性和扩展性。

多阶段缓存,降低后端压力

1、动静分离,静态化

静态化可降低后端压力,一方面通过用户浏览器缓存静态资源,失效时间通过cache-control来控制。另外一方面通过CDN缓存,例如商品详情页面,为了提高缓存效率,可将商品详情页面伪静态化,将URL后缀显示为HTML,商品描述信息等静态信息在有用户访问情况下,缓存到靠近用户的CDN节点,另外为了提高CDN效率,提前将商品图片推送到CDN。其它商品动态数据可动态加载,如商品运营信息、商品库存、尺码表等,从而降低了避免不必要的后台访问。

2、分布式缓存

引入分布式缓存,对缓存数据服务节点做统一集中管理,可支持缓存集群弹性扩展,通过动态增加或减少节点应对变化的数据访问负载,通过冗余机制实现高可用性,无单点失效,不会因服务器故障而导致缓存服务中断或数据丢失。应用端使用统一的API接口访问缓存服务器。

通过分布式缓存,可做应用对象缓存、数据库缓存、会话状态及应用横向扩展时的状态数据缓存。

3、巧用应用服务器本地缓存

分布式缓存虽然有效解决了访问压力,但由于缓存服务器分布在不同网络端、不同数据中心中部署,随着访问量增大将导致I/O和带宽瓶颈。为此可将那些基本不修改的配置数据、全局数据可以在应用服务器本地缓存,减少对后端缓存服务器实例的峰值冲击。本地缓存需要谨慎使用,如果大量使用本地缓存,可能会导致相同的数据被不同的节点存储多份,对内存资源造成较大的浪费。

使用缓存对提高系统性能有很多好处,但是不合理使用缓存非但不能提高系统的性能,反而成为系统的累赘,甚至影响系统运作,产生很大的风险。对于频繁修改的数据、没有热点的访问数据、数据一致性要求非常高的数据,不建议使用缓存。


优化数据库访问

在高并发大数据量的访问情况下,数据库存取瓶颈一直是个令人头疼的问题。如果数据库访问出现性能问题,整个系统将受到影响。

为此需要优化数据库访问,从以下几个方面解决高并发问题:

  • 优化复杂查询,提高数据库查询效率,找出关键模块的数据库慢查询进行优化。例如减少数据库表之间的Join、重构数据库表相关索引、对where子句进行优化等。
  • 保证在实现功能的基础上,尽量减少对数据库的访问次数;通过查询参数,尽量减少对表的访问行数,最小化结果集,从而减轻网络负担;能够分开的操作尽量分开处理,提高每次的响应速度,查询时用到几列就选择几列,降低数据库访问IO负载压力。
  • 基于电商系统读写比很大的特性,采用读写分离技术,通过一主多从,写操作只发生在主表,多操作发生在从表上,可以大大缓解对主数据库的访问压力。
  • 对业务和系统的细分,对数据库表进行垂直拆分。将数据库想象成由很多个"数据块"(表)组成,垂直地将这些"数据块"切开,然后把它们分散到多台数据库主机上面,从而可以分散单位时间内数据库访问压力。垂直切分的依据原则是:将业务紧密,表间关联密切的表划分在一起。
  • 垂直切分后,需要对分区后表的数据量和增速进一步分析,以确定是否需要进行水平切分。对于核心数据如订单,采取水平分区的方式,通过一致性哈希算法,利用用户Id把订单数据均匀的分配在各个数据库分区上,在应用系统查询时,以用户ID调用哈希算法找到对应数据库分区,从而将高峰时期的数据库访问压力分散到不同数据库分区上,从而实现数据库的线性伸缩,极大提升数据库的承载能力。
  • 借助于分布式缓存,缓存提供了远大于数据库访问的性能。当某一应用要读取数据时,会首先从缓存中查找需要的数据,如果找到了则直接执行,找不到的话则从数据库中找。在设计时,需要防止缓存失效带来的缓存穿透压力。
  • 容许一定程度的数据冗余,对于关键模块,为了防止对其它模块的依赖而影响当前模块的性能和可靠性,可适度保存其它模块的关键数据,减少由于访问其它模块服务带来的系统损耗和可靠性压力。
  • 使用NoSQL数据库对海量大数据进行存储和处理。

猜你喜欢

转载自blog.csdn.net/bird73/article/details/79875243