这个一个月没有更新的公众号的作者,他在支撑双十一

2020-06-01 00:00:00 数据 缓存 时间 调用 主机

上一篇更新的公众号文章是在10月11,距离双十一一个月的时间,各大电商平台的技术人员就都已经开始摩拳擦掌,厉兵秣马,迎接这一年一度的电商盛会,从朋友圈看出,大家都卖的很成功,我们也实现了28分钟就卖出了去年整个双十一的量,办公室里面顿时敲锣打鼓,红旗招展。


能够平稳支撑过双十一着实不容易,如果前期没有容量的评估和全链路的压测,谁也心里没底。所以随着双十一的逼近,压测的频率越来越频繁,从一周一次,到一周两次,三次,四次。


模拟的环境总是不能真实的模拟线上环境,所以线上压测往往是必须的,当然需要从历史数据中推测出压测模型,在数据库中建立影子表,在整个链路区分压测流量,但是对于带宽的占用也是非常大的,因而不可能使得线上真实用户的使用不受影响。所以半夜的压测就不可避免了,所以很长时间黑白颠倒,晚上压测,白天要开总结会,就几乎没有时间写公众号了。


我这么其实还在总结一个Kubernetes的知识点的脑图,画了一半,觉得老是不更新不合适,于是在10月21日,和31日各发出一版来,还都是残图,这个会后面逐渐丰富起来,进入了十一月,就实在没有时间了。


正式的架构层面的总结后续会慢慢的写,东西实在是太多了。


我必须更新一篇文章了,所以简单谈一下感受。


从基础设施层面,也即容器,云主机,云网络,云硬盘层面来说,由于我们的容器是部署在云主机里面的,用的也是云主机的CPU,对于需要高性能的核心模块所在的云主机,尽量不要超售,如果超售就会存在资源竞争的问题,一个核让跑多个虚拟机,而虚拟机上下文切换的代价实在太大,因而会造成性能的大幅度下降,竞争不激烈感觉不出来,竞争一激烈各种steal,相应时间和网络吞吐量就下去了。


除了设置不超售,其实还不够,因为虚拟CPU还是会随机的分配到不同的物理CPU上,这个时候CPU绑定非常的重要。CPU是重要的资源,除了业务需要CPU,物理机的中断需要CPU,虚拟机的中断需要CPU,OVS解析流表需要CPU,网络队列和存储队列的处理都要CPU,所以CPU还是好绑定,各用个的,互不干扰,仔仔细细的当宝贝一样的规划。


云网络也是重中之重,当然网络包的处理能力是严重依赖CPU的。一般我们测试网络的时候,总是在测带宽,其实在电商场景下,横向流量很多,而且小包很多,所以PPS也很重要,PPS上不去,仅仅带宽开的大,流量就是压不上去。所以DPDK和SR-IOV是必须的选择了。


二层的广播包是很讨厌的,非常影响一个集群下的云主机的数量,随着同一租户云主机的数目越来越大,原来使用ARP做发现的方法实在撑不住了,所以就需要采取通过管理平面加速用户平面的做法,实现真正的SDN。


云存储还是好和云网络的流量完全分离,不然写云存储还会占用网络的队列,本来就不够用。当然应用层好做成无状态的,少向云盘里面写入数据,都通过远程写入数据库,消息队列,大数据平台。


优化这些,统一的日志中心和统一的监控,统一的告警是必须的,如果只有几台机器,人可以去盯着,如果机器数目非常大,谁知道哪里出了问题,等现场已过去,就很难定位了。


传统的厂商使用云平台,总喜欢基于云平台实现高可用,而在应用层不考虑高可用,希望依赖于虚拟机的FT,HA的技术。但是当虚拟机规模比较大的时候,算算心里都发慌。按亚马逊的数据,云主机的SLA一般定在99.95%,有人说为什么不能更高,X86基本就这德行,而且云主机这东西又不像存储,可以三份备份之类的,咱们学计算机的时候其实都学了,CPU的时间维度,和CPU的几层Cache,和内存,和硬盘,和网络,完全不在一个层次上,这也是为什么FT会带来大幅度性能下降的原因。


如果挂的概率是0.05%,那么2000台虚拟机概率就是1,也即单租户如何有两千台机器的时候,很可能就有一台要挂了,如果是两万台呢?我们应用层就要假设挂是一定的,不挂是幸运的。所以应用层的高可用就非常的重要。应用应该是无状态的,是可以随便重启的,所谓的无状态,就是把数据放在统一的外部存储上,但是这解决不了一个问题,就是内存中也是有状态的,这就需要前序应用有错误重试的能力,同样需要一个接口设计的时候,有幂等的特性,保证重试的时候,不会相同的操作做多次。


应用拆成了多个,很多人会担心调用链过长,导致一个请求变慢,其实应用的拆分,不代表应用分层的增多,好三层就能搞定,不然维护起来也非常麻烦,故障概率也大大提高了,相当于多个条件概率乘起来。


应用之间的发现我们还在使用Dubbo,当然开发了自己的版本,叫做Dubbok。CSDN有专门的文章写这里面做的优化。对服务之间的调用需要有一个统一的治理平台,查看线程数,调用数,接口调用时间,调用链分析等,往往能够帮助找到性能瓶颈,甚至逻辑错误,例如有个接口调用次数过多,是不是在一个循环里面,每次循环都调用一次,能不能本地的空间换时间等等。


缓存非常重要,客户的点击就像射过来的剑雨,缓存就像一层层的盾牌,将请求拦在外面,只有少数的剑能到数据库这一层,虽然使用了DDB,分库分表,流量太大了也受不了。记得很早年间听新浪微博的负责人分享的时候,说了这样一句话,就是尽量用内存,现在感受越来越深了。静态资源需要CDN,不需要非常实时的数据可以在外层就有缓存。进程内部可以使用本地缓存,比分布式缓存性能好一些,然后才是分布式缓存Redis或者Memcache。熔断的时候,可以选择使用默认结果返回,或者缓存中结果,防止因为一个服务的响应慢,带来连锁反应。


主要关键的下单或者支付的流程越短越好,能够异步做的尽量异步做,不要纠结一城一地的得失,保证关键的步骤。使用终一致性即可,不一定非要强一致性,带来太多的锁,性能就下去了。只要将下单或者支付的动作记录下来,不丢了,允许整个过程存在中间状态,对于暂时失败的重试,能解决绝大部分问题。


该降级的都降级掉,想象大促状态下,紧张的顶多一个多小时,在这个时间内,抢购的女孩子们是不会关心哪些边边角角的功能的,下单支付成功了,就洗洗睡了,或者发朋友圈。


当压力测试测到运营估计到的量,今年的业绩目标按照这个量走,基本上就能完成,谢天谢地拜神灵,心就不要这么贪,超出这个预估量的咱就缓缓伺候,所以一般都会限流,对外层就有个统一的限流层,内部应用之间也有客户端限流和服务端限流,保证服务本身不会挂掉。技术人员相信,没测到的,一定会出问题,所以超过能抗的量,就算了。被限流的应用的这次调用可能返回错误码,甚至超时,看能不能返回缓存中的数据或者默认数据,或者没有这部分数据能不能降级返回,直到外层被限制的用户,只好求人家等等之类的。当然和网页不同的是,手机APP由于是自己开发的客户端,里面也可以有缓存,有异步调用,有重试,很可能被限流了客户感知不到,闪了一下又正常了,还以为是WIFI的问题呢,不过我也区分不出来到底是哪里慢了,要知道从你的手机到应用服务器,细算起来不下几十个步骤(包括网络的),详细亲们都理解。


反正大家都买到了心仪的商品,我也可以喘口气了。


“还有双十二那。。。。。。。。。。”



相关文章