上一期《互联网架构设计:高性能的前端》讲述了设计互联网高性能前端架构的基本方法,本篇文章将阐述一下如何设计高性能的后端服务。
先简略回顾一下。对于互联网产品的高性能架构设计通常包括以下几个大方面:
1)web浏览器高性能设计
2)app客户端高性能设计
3)高性能的网络和硬件
4)后台服务高性能设计
后端服务一般指用户直接看到的远程服务,涉及到网络硬件、逻辑计算、通信协议和数据存储等部分。下面我们将着重介绍高性能后台服务的设计方法和策略。
1、高性能的网络和硬件
网络硬件是提供实现高性能服务的先决条件,如果网络硬件失败,再优秀的团队也是“巧妇难为无米之炊”。互联网产品在网络硬件方面经常需要使用的高性能方案有如下几种:
1)cdn加速技术。cdn加速将网站的内容缓存在网络边缘(离用户接入网络最近的地方),然后在用户访问网站内容的时候,通过调度系统将用户的请求路由或者引导到离用户接入网络最近或者访问效果最佳的缓存服务器上,由该缓存服务器为用户提供内容服务;相对于直接访问源站,这种方式缩短了用户和内容之间的网络距离,从而达到加速的效果。
2)足够的带宽。带宽应该满足在网站峰值的情况还能足够快速的使用,所以网络带宽应该大于峰值流量 = 峰值qps * 平均请求大小。只有在保证带宽的情况才能实现高性能服务。
3)服务器性能。服务器性能主要从cpu、内存和磁盘三个方面来考虑,cpu核心数量能尽量多点,内存大小最好大一点,利用到磁盘存储的话ssd会优于机械磁盘。
4)硬件负载均衡设备。对于有条件的团队可以采购硬件负载均衡设备,加强后台服务负载均衡的能力,比如f5。
2、后台服务高性能设计
后台服务的高性能设计是互联网产品高性能架构设计中最重要的一环,对服务整体性能起到决定性的作用。我们来看看设计高性能后台服务的方法:
1)分布式缓存。缓存的本质是通过key-value形式的hash表提升读写速度,一般情况是o(1)的读写速度。读写量比较高,变化量不大的数据比较适合使用缓存。业内比较成熟的分布式缓存系统有redis/memcache。
一般的缓存设计架构如下:用户第一次请求应用程序时,通过存储服务直接读取数据,然后将数据存储到缓存系统去,用户第二次请求的时候就直接从缓存系统读取,从而提升读取速度。
对于分布式缓存系统可以set化部署,比如商品数据缓存到set1,用户数据缓存到set2,或者一类用户的数据缓存到set1,另一类的用户缓存到set2,如下图:
此外,也可以按集群化部署,每一个缓存服务存储的数据都是对等的,可以对外提供同等的服务,所以外部请求需要负载均衡到不同有缓存服务器,如下图:
set化部署的目的主要在于将不同类型的数据路由到不同的地方,好处就是可以减少不同业务数据的耦合,可以针对不同业务进行不同的优化,从而提升整体性能。集群式部署的目的在于,提高缓存系统的对外服务能力,上层业务的路由策略简单灵活,扩缩容比较容易。
2)服务分层
在经典的三层(接入层、逻辑层和存储层)后台服务架构中,三层的划分的原则就是同层次的系统专注处理自己的事情。接入层专注于处理前端和后台服务的接入连通、安全认证和数据转发。逻辑层专注于处理不同业务的无状态逻辑服务。存储层专注于处理业务数据的存储。这样分层的好处在于各个层次能够依据业务特点专注于自己的事情,提高系统复用性,降低业务间的耦合性。在中小型网站中三层架构的典型实现是nginx(接入层)、apache web(逻辑层)、mysql/redis(存储层)。
3)操作异步化
目前大型系统中普遍消息队列来将调用异步化,不仅可以提升系统性能还可以提升系统的扩展性。对于大量的数据库写请求,对于数据库的压力很大,同时也会造成数据库响应不及时。可以考虑使用消息队列,数据库的写请求可以直接写入到消息队列,然后通过多线程或多进程从消息队列中读取数据慢慢写入到数据库。消息队列服务器的处理速度会远远快于数据库,所以用户在写入操作时会感觉到很快的写入速度。
此外,消息队列对于请求不均衡的系统,还具有削峰填谷的作用,将短时间内的高峰请求,逐步平摊到更长的时间里去,从而避免短时间内大量请求压跨系统。
4)服务拆分
服务拆分有多种说法,比如大系统小做,分布式拆分,分层结构以及目前很流行的微服务化。不过服务拆分一般来说有以下原则:
a)高内聚、低耦合: 将耦合性低的业务逻辑划分为不同系统,将聚合性高的业务逻辑划分为同一个系统。
b)单一职责原则:对于一个层次或者一个模块应该保持相对单一的职责,专注于自己的服务。
c)故障隔离:不同系统必须相对独立设计和运行,能够独立处理自己的故障,而不至于影响全局。
d)独立运维和持续交互:对于不同的系统可以随时迭代更新,而不至于影响其他服务。
对于服务拆分主要有纵向拆分和水平拆分两种方法。三层架构就是典型的纵向拆分模式,第2)点有所阐述。对于不同的业务模块,针对业务逻辑和存储服务可以按水平拆分的方法将拆分为不同的系统。比如商品系统逻辑层、订单系统逻辑层、商品系统存储层、订单系统存储层。
5)分布式集群化
分布式集群化是指将不同的业务用集群化的方式部署到不同的机器上去,对于每一个业务都具备大规模集群化的能力,从而提升系统的扩展性和高性能。
对于无状态化的被调服务a,在基于负载均衡的技术下,可以通过集群化部署成倍的提升服务性能,比如a1服务的性能是1万请求每秒,那么部署3台a服务机器,那么a服务的性能就是3万请求每秒了。
6)代码优化
对于io操作的请求可以采用基于状态机的异步化编程。如下图的请求需要业务系统调用三个接口才能返回响应数据,当业务系统收到请求时,将给该请求分配一个seqid,该seqid在接口响应中也应该原封返回,然后并发三个io接口的请求包,将该seqid对应的请求上下文保存到timer中,然后去并发处理其他请求,从而极大的提升系统性能。
此外,高性能的编程模型还有多线程模型、多进程模型、多协程模型和事件驱动模型。
对于数据结构的设计可以采用高效的数据结构,比如典型的key-value缓存系统就是基于hash的基本原理来实现的,hash表的查询效率是o(1),效率极快。
转自原文:https://zhuanlan.zhihu/p/28817489