本文属于专栏《构建工业级QPS百万级服务》系列简介-CSDN博客
继续上篇。如图1,我们的qps百万级的无状态服务架构基本成型。
图1
这个架构能让我们的服务接受百万QPS的请求。并能够有序完成开发迭代,和日常运维。既然大部分业务是为了挣钱,那降低成本就十分重要。降本是一个复杂而系统的事,这里,我们先基于图1的架构,看看目前的架构可能会遇到哪些成本问题,一般是如何解决的。
首先考虑如何提升单机QPS。提升单机QPS时,我们要确认我们目前的应用瓶颈在哪里,比如当前我们的瓶颈在计算相差日期的逻辑消耗的CPU资源。那我们有几个角度来做优化:
- 算法角度:计算日期差值时,考虑目前的算法是否足够简单,是否有更快的三方库提供的算法
- 工程角度:通过缓存,减少冗余计算。比如我们发现80%的请求,开始结束时间都在当前时间前后1年内。那我们提前算好,前后1年以内的用户时间差,共计约(365*2)*(365*2)= 5,204,900种请求。我们的key用64位的int,高32位是开始时间,低32位是结束时间,value用32位int,这样我们的内存大小为60M。这样我们用存储换了CPU。这里也是有代价了,有了缓存,就有了状态,系统复杂度也会增加。复杂度的增加是否划算,取决于机器成本和人力成本的比较结果
- 产品角度:为了用少量的成本,服务大量的用户,我们抛弃一些查询时间太长的用户,限制用户一段时间最多查询次数等
然后我们看看从集群的角度如何降低成本。我们在实际生产中,大概率不是恰好每台机器分到的请求数都一致,这种情况我们需要调整负载均衡服务器的分发函数尽量平均。另外如果我们使用足够多的物理机,物理机之间可能有性能差异,甚至芯片版本不一样,比如有的机器能接受1500请求/秒,有的只能500请求/秒,这个时候我们要以性能最差的机器来算,那需要的核数是2000核。为了节省成本,我们应该尽量使用机器性能一致的物理机。这个是运维层面的责任,作为研发,我们也要确认每台机器性能差异不大,确认的办法很简单,压测,也就是与线上请求隔离的情况下,验证出性能最差的那台机器达到性能瓶颈时,集群整体处理能力。
另外一个问题就是不同时段用户请求不一样,比如白天峰值是100万/秒,凌晨是1万/秒,那晚上我们使用10个核就够了,但是一般来说流量不是断崖下跌的,以图2为例,14:00请求人数最多,00:00最少,只有高峰的1/10
图2
很明显,凌晨如果我们依然保留着1000核,就有些浪费了。节约成本的方式,由计费规则决定,举些例子:
- 如果使用的是云厂商,且机器以小时粒度计费。那我们使用动态扩缩容的方式,如在每次CPU达到70%时增加机器,在CPU每次达到30%时减少机器,让机器的CPU保持在30%到70%之间,这样减少了机器浪费,也不至于服务无法承担请求
- 如果是自己买的物理机器。我们就把离线任务放到夜间去做,这样既不影响用户体验,也不再需要额外购买物理机做离线计算
以上是无状态服务的通用架构和工程经验。对于有状态的服务,复杂度就显著增加了,我会在后续的《QPS百万级的有状态服务实践》中,分享我的经验。