高并发网站的演变和优化

一,什么是高并发
高并发是互联网分布式系统架构设计中必须考虑的因素之一,通常指:通过设计保证能够同时并行处理很多请求。
高并发指标:
响应时间:系统对请求做出响应时间。例如系统处理一个HTTP请求需要200ms,这个200ms就是系统响应时间。
吞吐量:单位时间内处理的请求数量。
每秒查询量QPS:每秒响应请求数。在互联网这个指标和吞吐量区分的没有这么明显。
并发用户数:同时承载正常使用系统功能的用户数量。例如一个即时通讯系统,同时在线量一定程度代表系统并发用户数。

二,创业初期系统
假如我们现在有一家创业公司,注册用户10万,每天有10%的用户访问系统也就是1万的活跃用户。按照二八原则,每天高峰用户会达到80%,也就是8000人。假如每个人活跃4小时,每个人提交20次表单,也就是说有16万次提交在4小时内,平均每秒10次。
按照互联网通常配置应用服务4核8G,数据库服务16核32G。
比如每次请求对数据库3次请求,也就是说每秒30次。
按照这台数据库配置,支撑是绝对没有问题的。

三,集群部署
在CEO带领下公司得到了高速发展,注册用户达到了500万。此时日活用户50万,高峰时对系统每秒请求是500次。然后对数据库请求1500次,这个时候会怎样?
按照上面业务系统配置,如果业务逻辑比较重,比较消耗CPU,此时的机器CPU可能负载过高。
然后数据库层面,以上述配置,对于1500次每秒请求,基本还是可以接受。
所以此时需要做的一件事情,就是把系统集群化部署。
在前面挂一个负载均衡层,把请求均匀的打到系统层面,比如再加一台应用服务器,这样每台应用服务器请求只有250/s。

img

四,数据库分库分表+读写分离
此时用户注册达到1000万,日活跃用户100万。对系统每秒请求1000次,系统层面可以继续通过集群化方式来扩容,通过负责均衡层把请求均匀分布。
此时对于数据库层面请求3000/s。
通常来说,对于普通的16核32G机器配置,一般的线上经验是:不要让其每秒请求支撑超过2000,一般控制在2000左右。
所以需要对数据库进行分库分表+读写分离。每个主库至少挂一个从库。
假如读写并发3000/s,这其中1000写,2000读。
这样分库后主库写500/s,从库读1000/s。

img

五,数据库进一步拆分
公司业务迅速发展,注册用户达到了2000万!每天活跃用户200万!每天表单新增数据50万条!高峰请求量达到了1万!
同时公司带来了两轮融资,估值达到了几亿美金!一只朝气蓬勃的幼年独角兽诞生的节奏。
经过一段时间的运行现在表中数据已经到了两三千万条数据,勉强还能支撑。
但是,眼看数据库访问性能越来越差,单表数据量越来越大!
然后高峰请求现在是1万,系统可以部署20台机器,平均每台支撑500请求,还能抗的住,没啥大问题。
但数据库层面呢?
首先我们考虑一个问题,如何是数据库支撑每秒上万并发请求?
上面我们说了,单台数据库每秒请求不要超过2000,所以我们可以部署5台机器,
比如订单表,我们拆分到5个库中,db_order_01,db_order_02,db_order_03,db_order_04,db_order_05。
这样每天50万条数据,均分到每个库中10万条。如图

img

但上述数据库架构还有一个问题,那就是单表数据量还是很大,如果订单一年有一亿条,每个表就有2000万,这也是太大了。
比如可以把订单表拆分为1000张表,这样1亿数据量分散到每个表中数据只有10万条,然后这1000张表分散到这5台数据库里。
写入数据库时候,需要路由两次,对订单Id进行hash后取模获取数据库地址,然后再根据表数据量取模,路由到那张表上。
这样1亿数据量每张表一年才10万条,10年才百万级数据量。
当然这5台数据库需要配置从库,毕竟在2000请求中,按照二八原则,有400写,1600读。这样主库的请求只有400/s,从库1600/s。

img

具体的分库分表落地的时候,需要借助数据库中间件来实现分库分表和读写分离,大家可以自己参考 sharding-jdbc 或者 mycat 的官网即可,里面的文档都有详细的使用描述。

六,缓存集群引入
业务不断发展,每秒1万访问已不在是高峰,系统需要支撑每秒几万的访问。但是不能仅仅考虑数据库层面的分库分表了,大家要知道“数据库其实本身不是用来承载高并发请求的”。
这个时候我们要结合业务,一般的业务都是写少读多,80%-90%访问的是热数据。这样我们可以把热数据放在缓存中。
另外缓存单机承载的并发量都在每秒几万,甚至每秒数十万,对高并发的承载能力比数据库系统要高出一到两个数量级。

img

七,引入消息中间件集群
其实在高并发下,有一些请求是允许异步执行等待几十秒,甚至几分钟后落库。
此时完全可以引入消息中间件,然后基于MQ做一个削峰填谷。比如就以平稳的100/s的速度消费出来然后落入数据库中即可,此时就会大幅度降低数据库的写入压力。
消息中间件系统本身也是为高并发而生,所以通常单机都是支撑几万甚至十万级的并发请求的。

img

八,总结

1,整个架构:可采用分布式架构,利用微服务架构拆分服务部署在不同的服务节点,避免单节点宕机引起的服务不可用!

2,负载均衡:使用nginx等对访问量过大的服务采用负载均衡,实现服务集群,提高服务的最大并发数,防止压力过大导致单个服务的崩溃!

3,数据库:采用主从复制,读写分离,甚至是分库分表,表数据根据查询方式的不同采用不同的索引比如b tree,hash,关键字段加索引,sql避免复合函数,避免组合排序等,避免使用非索引字段作为条件分组,排序等!减少交互次数,一定不要用select *!

4,加缓存:使用诸如memcache,redis,ehcache等缓存数据库定义表,结果表等等,数据库的中间数据放缓存,避免多次访问修改表数据!登录信息session等放缓存实现共享!诸如商品分类,省市区,年龄分类等不常改变的数据,放缓存,不要放数据库!同时要避免缓存雪崩和穿透等问题的出现导致缓存崩溃!

5,使用消息中间件:对服务之间的数据传输,使用诸如rabbit mq,kafka等等分布式消息队列异步传输,防止同步传输数据的阻塞和数据丢失!

6,多线程:现在的服务器都是多核心处理模式,如果代码采用单线程,同步方式处理,极大的浪费了CPU使用效率和执行时间

7,CDN加速:如果访问量实在过大,可根据请求来源采用CDN分流技术,避免大流量完成系统崩溃!

8,避免低效代码:不要频繁创建对象,引用,少用同步锁,不要创建大量线程,不要多层for循环!

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值