聊聊关于生产扩容

130 阅读5分钟

背景

最近马上双十一了,各种问题接踵而至,出了几次线上问题,做了几次线上应急,因此对于线上扩容这个需要额外注意,不仅仅简单扩容,可能错误的扩容反而会造成更大的问题。

什么是扩容?

扩容是什么?

可能第一想法就是服务器,比如linux的物理机ECS或者目前使用最广的docker容器(底层也是物理机)。

但是扩容不仅仅只是这一个场景,一个复杂的系统涉及各个方面的底层组件,这些组件都是扩容的对象。

扩容的对象:

  • 网络:带宽
  • CDN:容量
  • 服务器:服务器数量
  • 服务器规格:内存、CPU核数
  • 缓存:Redis内存
  • 消息队列:RocketMQ的TPS、queue数量扩容、Broker扩容
  • 数据库:内存、CPU
  • 应用:中间件的线程数 -Page-19.jpg

为什么扩容?

为什么扩容?这个问题估计都可以立即回答,因为应用支撑不了当前的流量,需要通过扩容解决流量过大服务宕机的问题。

这是最简单的扩容原因,当面对线上各种问题时会发现有时扩容不是解决流量过大,而是为了解决生产问题。

扩容原因:

  • 【流量超出服务承受的预期】:一个服务上线我们都会评估QPS,QPS作为流量的大小,QPS越大说明业务量越大,服务要求也越高,如果前期评估QPS小于真实业务流量,此时服务可能无法满足业务要求,该情况下就需要扩容。
  • 【数据库问题】:异常场景下如果业务代码出现了bug造成了数据库CPU被打满,此时最快捷的方式一方面修改代码,另外一方面评估升级数据库的规格,升级CPU核数
  • 【异常流量】:比如一些大报文请求,可能并不频繁,但是当来了异常流量会导致应用出现异常,比如FGC,这种问题一般通过限流异常流量或者升级内存规格或者扩容服务器数量

怎么扩容?

怎么扩容这个问题是很谨慎的问题,刚开始工作时没有什么思考,如果出现需要扩容就无脑扩,也不知道扩容数量是多少?有没有影响?

现在来看这个问题需要额外谨慎,扩容不能随便,扩容也要当作生产问题来处理,扩容的前提是你要知道扩容产生的影响,虽然扩容会解决当前问题,但是会不会产生其它问题,这是要深思的问题(紧急情况下更要谨慎,亲身经历!)

扩容流程

服务器扩容

  • 观察系统水位,CPU、load数、内存使用率、FGC频率。CPU一般80%,load需要区分load1、load5、load15,每个值越小越好,一般不要超过核心数**2,内存使用率一般80%为水位阈值,FGC优化好的应用一般一天一次,如果十几分钟一次并且每次FGC的时间都要几秒,那么需要特别关注

  • 以上几个水位超过阈值都要扩容,扩容数量如何确定?

    • 一般阶梯扩容,比如原数量10,可以先扩容3、再不够再基于评估扩容5。如果特殊情况比如所有内存和CPU都打满了,这种情况下直接扩一倍是最快速的。
  • 服务器扩容额外注意数据库,因为应用扩容会导致数据库连接数也增大,如果数据库规格不足,那么扩容应用可能会直接将数据库打爆,造成更大的问题。因此扩容应用一定要和数据库一起考虑扩容,避免扩容之后服务RT无法降低(亲身经历本人扩容服务器扩容了一倍,数据库被打爆,导致数据库连接数打满,数据库CPU打满,出现大量慢SQL,导致服务RT升高,服务基本不可用!)

数据库扩容

  • 观察数据库连接数、CPU、内存,如果连接数打满,并且出现大量慢SQL这种一般都是连接数被打满导致连接等待,CPU、内存一般超过80即不稳定状态需要考虑扩容

缓存扩容

  • 这里说的缓存扩容指Redis,Redis是基于内存的数据库,完全依赖内存,这个水位要根据redis的缓存增量计算,比如你的缓存过期时间很散列,因此可以设置80%的阈值,如果缓存过期时间不可控,那么需要将阈值降低。

  • 缓存的扩容一般原因有以下几点:

    • 过期时间设置不合理
    • 存在大key
    • 流量过大

MQ扩容

  • MQ的扩容主要是升级TPS,TPS是同一时刻同步响应的请求量,比如TPS设置的数量为1w(发送和消费的综合),如果超过1w阈值mq会将消息打回重新执行。
  • 如果出现消息堆积,并且消息的消费者速率无法提升,那么大概率就是TPS受限导致消费能力无法提升,此时需要升级TPS的数量
  • MQ扩容的需要特别考虑应用和数据库是否会受影响,TPS升高会导致应用消费能力上升,服务压力也会同步上升,相应的也会对数据库造成一定压力,因此升级TPS一定考虑底层服务的支撑能力

带宽扩容

  • 带宽扩容一般是面临公网请求量过大导致带宽打满无法正常接收请求,这种情况下正常提升带宽即可解决

总结

针对自己的扩容经历梳理扩容对象、扩容原因、扩容流量。

以上只是自己的日常工作的见解,如有异常欢迎指正