高并发架构的设计与实践

 高并发通常是指并发访问非常高,具体表现在 QPS、吞吐量、响应时间、PV、UV、带宽等方面。高并发、高性能也是市场上大流量应用最在乎的几个关键点,查阅了很多文章,结合自身项目实践,从多个方面、多层次来理解下高并发和解决措施。

名称解释

  • QPS:每秒钟请求或者查询的数量,在互联网领域,通常指每秒HTTP响应请求数。

  • 吞吐量:单位时间内处理的请求数量(通常由QPS与并发数决定)

  • 响应时间:从请求发出到收到响应花费的时间,例如系统处理一个HTTP请求需要100ms,这个100ms就是系统的响应时间。

  • PV:综合浏览量(Page View),即页面浏览量或者点击量,一个访客在24小时内访问的页面数量,同一个人浏览你的网站同一页面,只记作一次PV。

  • UV:独立访问(UniQue Visitor),即一定时间范围内相同访客多次访问网站,只计算为1个独立访客。

  • 带宽:计算带宽大小需关注两个指标,峰值流量和页面的平均大小。

  • 日网站带宽=PV/统计时间(换算到秒)平均页面大小(单位KB)8

QPS各量级举例解决方案

  • QPS达到50:小型网站量级,一般的服务器就可以应付。

  • QPS达到100:假设关系型数据库的每次请求在0.01秒完成,且单页面只有一个SQL查询,那么100QPS意味这1秒钟完成100次请求,但是此时我们并不能保证数据库查询能完成100次。

    方案:数据库缓存层、数据库的负载均衡

  • QPS达到800:假设我们使用百兆带宽,意味着网站出口的实际带宽是8M左右,且每个页面只有10k,在这个并发条件下,百兆带宽已经占满。

    方案:CDN加速、负载均衡

  • QPS达到1000:假设使用Redis缓存数据库查询数据,每个页面对Redis的请求远大于直接对DB的请求,Redis的悲观并发数在3W左右,但有可能在之前内网带宽已经吃光,表现出不稳定。

    方案:静态HTML缓存

  • QPS达到2000:这个级别下,文件系统访问锁都成为灾难。

    方案:做业务分离,分布式存储

通用解决措施

  • 动态资源和静态资源分离;

  • CDN;

  • 负载均衡;

  • 分布式缓存;

  • 数据库读写分离或数据切分(垂直或水平);

  • 服务分布式部署。

按业务场景划分的解决措施

  • 前端:异步请求、资源静态化、cdn

  • 后端:请求队列、轮询分发、负载均衡、共享缓存

  • 数据层:数据水平分割(分区分表分库)、读写分离、redis缓存、写队列

  • 存储:raid阵列、热备

  • 网络:dns轮询、DDOS攻击防护

前端工程化层面的解决方案

  • 将应用和静态资源分离:静态资源主要包括图片、视频、js、css和一些资源文件,直接存放到响应的服务器使用专门的域名去访问就可以了。

  • 页面缓存:将应用生成的页面缓存起来,可以节省大量的CPU资源,尽可能采用静态页面来实现功能。

  • CDN进行内容分发:CDN 服务器是分布在全国各地的,当接收到用户请求后会将请求分配到最合适的CDN服务器节点获取数据。

后端架构层面解决方案

  • 当单机无法解决时,增加服务器数量(集群),通过反向代理、负载均衡,将请求分发分流。

  • 微服务化,将不同的业务放到不同的服务器中,分布式架构。一个请求可能需要用到多台服务器,这样就可以提高一个请求的处理速度,而且集群和分布式也可以同时使用。

  • 选择有助于高并发的工具,如 Node.js、Nginx、Redis, NoSQL

  • 公共数据缓存,共享缓存服务。

  • 应用服务器配置优化,如连接数的优化,每个请求都是独立的连接线程,所以优化此配置可以提高服务器接收HTTP并发请求的能力。

  • 逻辑代码优化、算法优化

  • 优化架构,加强可伸缩性,流量增大的时候,可以通过增加硬件来分担压力。

  • 关注代码本身,防止出现内存溢出的情况,优化查询语句,避免系统频繁请求数据库,合理使用索引,减少sql语句执行的时间。

  • 镜像技术解决不同网络接入商和地域带来的用户访问速度差异。

数据库层面解决方案(大数据高并发的瓶颈一般在数据库层面)

  • 建立缓存中间件降低对硬盘的读写次数,这是最基本和重要的优化策略。

  • 建立数据库、缓存集群,将读写计算压力分摊到多台机器上。

  • 建立主从备库,读写分离。

  • 数据水平分割,分区、分表、索引优化,良好的查询算法,降低读的次数,解决插入更新缓慢。

  • 分离数据库中活跃的数据、热点数据

  • 使用NoSQL和Hadoop等技术