1 前言
最近因为公司的事情比较多,任务比较重,所以很长时间没有更新文章了。最近因为工作上的内容突击学习了很多的内容,比如今天我要讲的。
随着互联网行业的快速发展,高并发可以说是很多发展不错的公司都可能或者最终都可能面对的场景。高并发分布式技术体系也可以说是现在很多的互联网公司招聘所必备的技术体系了。高并发分布式开发技术体系已然非常的庞大,从国内互联网企业使用情况,可发现RPC、Dubbo、ZK则是最基础的技能要求。
高并发分布式这块有很多需要学习的地方,所以自己准备好好的学习并总结一下自己学习过程中的问题和心得。所以我和大部分人一样是一名学习者,文章中更多的是自己的学习总结和自己的理解,可能也会有理解不透彻的地方,所以如果有任何的问题欢迎大家指出并交流讨论,在此也希望大家共同进步。
这篇文章作为这个系列的第一篇文章,将介绍一下什么是高并发和分布式架构。
2 什么是高并发
我们都会遇到这样一个场景,在双11的购物狂欢节的时候当我们进入某家店铺或者付款的时候可能会遇到进不去的情况,还有一些明星离婚、结婚导致微博爆了,这些都是高并发的场景。所以高并发比较形象点的必须就好比春节的时候,高速收费站的车辆,就一个路口,结果数万辆车同时请求经过,导致高速公路上排满了车辆,这就是现实生活中的高并发。在互联网中高并发会导致站点服务器资源被沾满崩溃,数据的存储和更新结果和理想设计中的结果不一样,比如会出现重复的数据,双十一的时候会有多次成功支付的情况,同一件商品添加了多次,等等。这些是服务端的情况。对于用户的体验肯定是很差的,这样用户就会减少,每次进去一个网站都要搞半天,那还有谁用你家网站。
在做我们公司的产品网站的时候,经常会搞一些活动,比如抽奖,签到,秒杀等等,如果没有考虑到高并发下的数据处理,那么就很容易导致抽奖被多抽走,签到的时候会发现一个用户有多条记录,签到一次获得了获得了多积分,等等这些超出正常逻辑的现象,因为这些都是面向大量用户的,而不是像做ERP管理系统,OA系统那样,只是面向员工。
所以高并发是在开发中必须解决的问题,尤其是一些大型的、用户数量比较多的互联网公司。
解决高并发,那么首先需要清楚什么是高并发?
高并发(High ConCurrency)是互联网分布式系统架构中必须考虑的因素之一,它通常指的是通过设计保证系统能够同时并行处理很多请求。
不能说一个网站每次请求都有数十万个那才叫高并发,而请求只有几千、几万的就不叫高并发。高并发有一些相关的指标,比如响应时间(Response Time)、吞吐量(Throughput),每秒查询率(Query Per Second,QPS),并发用户数等。
响应时间:指的是系统对请求作出响应的时间,比如系统处理一个HTTP请求需要200ms,那么200ms就是这个系统的响应时间。
吞吐量:单位时间内处理的请求数量。
QPS:这个平时应该听到的比较多。指的是每秒响应的请求数,QPS和吞吐量的区别并不是很明显。
并发用户数:同时承载正常使用系统功能的用户数量。比如有些游戏,同时只能保证多少人在线,人多了就会有一些性能上的影响。
3 高并发的分布式解决方案
前面介绍到了什么是高并发以及高并发的几个重要的因素。那么在进行系统开发的时候如何提高系统的并发能力有效的解决高并发带来的问题呢?结合前面提到的一个比较好的互联网应用的特点是高并发和海量的数据。海量的数据包括数据的存储和处理能力,而高并发则指该互联网系统在单位时间内的请求数量,而越好的应用其用户的数量是没有上限的(取决于其开发性),所以高并发的处理能力则是评判一个系统优良的一个很重要的指标。那么在互联网架构的设计中通过使用分布式的架构能够解决上述的问题。
互联网分布式架构设计的方法主要有两种:
第一种是垂直扩展的方式(Scale Up);垂直拓展主要是提升单机处理能力,垂直扩展的方式又可以分为两种:
1、增强单机的硬件性能,比如:增加CPU核数,升级宽带或网卡,采用更好的硬盘等等,通俗点就类似于我们自己的电脑玩游戏感觉很卡,我们自己加内存条也是一种方式,这就是增强单击的硬件性能。
2、第二种就是提升单机的架构性能,比如:可以多使用缓存从而减少IO次数,提升系统性能;或者采用异步的方式来增加单服务的吞吐量,等等。
分布式架构设计的第二种是采用水平扩展的方式(Scale Out)。水平拓展通常指的是通过增加服务器数量,线性地扩充系统性能。比如最近发洪水需要泄洪一样,单个的泄洪口只能泄特定数量的洪水,如果洪水很多,那么可以在不改变泄洪口大小的情况下,通过多设计几个泄洪口也能够增加泄洪量。如何实现请求的平均分配便是负载均衡了。
垂直拓展的方式虽然也能够提高系统的性能,但是成本较高,而且单机性能总是存在极限的。所以在互联网架构中通常采用的是水平拓展的方式进行系统架构设计,但是水平扩展对系统架构设计也是要求的,本文将讨论如何在架构各层进行可水平扩展的设计,以及互联网公司架构各层常见的水平扩展实践。
图源网络,侵删
通过上图我们可以发现,常见互联网分布式架构可以分为:
(1)客户端层:常见的比如浏览器、软件或者手机软件等等。
(2)反向代理层:系统入口,反向代理。
(3)站点应用层:实现核心应用逻辑,返回html或者json。
(4)服务层:这一层并不是都有的,如果系统实现了服务化,那么就有这一层。
(5)数据-缓存层:使用缓存可以加速数据的访问。
(6)数据-数据库层:进行数据的存储。
除了分布式系统进行水平拓展,上面提到的各层次也可以进行更细致的水平拓展。
反向代理层主要通过通过DNS轮询实现水平扩展:dns-server对于一个域名配置了多个解析ip,每次DNS解析请求来访问dns-server,会轮询返回这些ip。
所以当nginx的性能受限的时候,只要增加服务器数量,新增Nginx服务的部署,增加一个外网ip,就能扩展反向代理层的性能,可以做到理论上的无限高并发。
再下一层的web应用层的水平拓展,则是通过nginx实现的。通过修改nginx.conf,可以设置多个web应用。那么当web后端性能受限了的时候,只需要增加服务器的数量,并且增加web服务的部署,并且在nginx的配置中配置新的web后端,那么就能拓展web应用层的性能,提高高并发的性能。
在web应用层的再下一层的服务层则是通过服务连接池可以进行水平拓展。web应用层通过RPC-Client来调用服务层的RPC-server的时候,RPC-client中的连接池就会与服务建立多个链接。同理当服务的性能达到瓶颈的时候,只需要增加服务器的数量,新增服务器的部署,并且在rpc-client建立新的服务链接,从而拓展服务层的性能。
缓存层的水平拆分和数据库层的水平拓展类似,主要有范围水平拆分和哈希水平拆分的方式。以数据库为例,每一个数据服务存储一定范围的数据,比如:
库1存储id为1-100万的数据;
库2存储id为100万到200万的数据;
.............
而哈希水平拆分则指的是先对某个key值进行hash,然后存储其hash后的部分数据,比如:
库1存储id为偶数的数据;
库2存储id为奇数的数据;
................
上面两种拆分方式都有一定的优点和缺点,通过其原理,可以发现:
范围水平拆分的优点是:
1、规则和原理比较简单,只需要根据id的范围就可以找到对应的存储服务;
2、因为原理简单,所以拓展性好,方便进行拓展,根据范围可以追加跟多的数据服务‘
3、数据的均衡性比较好,每个库的数据量基本差不多。
但是也有缺点,那就是请求的负载不一定均衡,因为较大范围内的服务请求的压力会更大。
而哈希水平拓展的好处则是请求的均衡性比较好,但是拓展性不好,这个根据哈希算法的原理有关,当拓展一个数据服务的时候,如果哈希算法改变,那么可能需要进行数据的迁移,比较麻烦。
水平扩展和垂直拆分是分布式架构的两种思路,但并不是一个二选一的问题,更多的是兼并合用。比如 我们公司的系统很庞大并且是分布式系统,所以为了方便组织管理,公司将整个技术部按业务和平台拆分为部门,订单的,会员的,商家的等等,每个部门有自己的web服务器集群,数据库服务器集群,通过同一个网站访问的链接可能来自于不同的服务器和数据库,对网站及底层对数据库的访问被分配到了不同的服务器集群,这个就是按业务做的垂直拆分,而当每个部门的服务器的压力比较大的时候,就会有弹性的扩展,这便是水平扩展。
在数据库层,有些表非常大,数据量在亿级,如果只是纯粹的水平的扩展并不一定最好,如果对表进行拆分,比如可以按用户id进行水平拆表,通过对id取模的方式,将用户划分到多张表中,同时这些表也可以处在不同的服务器。按业务的垂直拆库和按用户水平拆表是分布式数据库中通用的解决方案。
4 如何实现负载均衡
上面的内容主要讲的是如何采用分布式架构来解决性能问题,那么如何进行数据的分布,即实现负载均衡也是需要考虑的问题。我们已经知道分布式系统中有很多的服务器,那么当客户端进行请求时,如何让它合理的请求分布式系统中哪一台服务器,这就是需要考虑的问题。这里比较常见的做法就是采用一台中间服务器来给客服端分配目标服务器。
分布式文件系统FastDFS的一次文件下载请求过程是这样的:
1、client询问tracker可以下载指定文件的storage;
2、tracker返回一台可用的storage;
3、client直接和storage通信完成文件下载。
这里的tracker便是负载均衡服务器,而storage就是存储文件和处理上传下载请求的服务器。
分布式的RPC中间件的处理过程也是类似的:
1、client询问zookeeper哪台server可以执行请求;
2、zookeeper返回一台可用server;
3、client直接与service完成一次RPC。
这里zookeeper就是分布式系统中一个负载均衡框架,它是一个分布式服务框架,是Apache Hadoop 的一个子项目,它主要是用来解决分布式应用中经常遇到的一些数据管理问题,如:统一命名服务、状态同步服务、集群管理、分布式应用配置项的管理等。
常听说的nginx也是一个负载均衡服务器,它面向的是分布式web服务器。
分布式系统中,另外一个比较重要的问题就是如何保证数据的一致性,这个就需要通过同步来保障。根据不同的场景和需求,同步的方式也是有选择的。但这块内容我自己理解的也不够深,所以先不进行讨论,自己还要学习学习,后面再写,如果有同学对这块比较了解或者有兴趣可以进行讨论。
5 总结
因为工作上的需要所以对高并发和分布式这块进行了一些简单和仓促的学习,这里就算是对这块内容进行一个简单的入门和介绍,如果有不对的地方欢迎指出大家可以一起交流讨论。另外不管是在工作还是学习中,大家都需要保持一个不断学习的热情,这样才能在工作中保证一颗从容的心,不然就会像我一样,啥都不会,只能临时抱佛脚,慌慌张张,还耽误工作进度。大家一起加油。
另外我的github上也正在整理一些笔面试题的内容,欢迎大家star,一起编写整理帮助更多的人,一个人有些时候比较忙, 所以更新速度有点慢。