1.在最开始时,使用的架构是这样的:
浏览器向后台服务器发送请求,然后服务器请求数据库,获取数据,在响应给浏览器,这是最早期的架构,服务器和数据库放在一台主机上,
这样的架构带来的问题是:
当访问量逐渐增大时,服务器的负载就会越来越大,负载达到一定限制时,服务器就会宕机,一旦服务器宕机,前端就获取不到任何数据
2.为了解决这个问题,就提出了第二套架构
通过将数据库分离出来成为一个单独的服务器,来减小放web项目的服务器的压力,这样虽然解决了第一种架构的问题,但是新的问题出现了:
当有十万并发请求web服务器时,服务器就会宕机,服务器宕机,浏览器仍然获取不到任何数据,核心功能在web服务器上
3.因此就出现了第三种架构
为了解决上一种架构的问题,于是就提出了使用web服务器集群来部署项目,这样当节点1宕机的话,就会请求节点2处理请求,那么问题也随之而来:
如果访问量非常大,导致节点1宕机的话,那么所有的请求就会被节点2接受,节点1宕机,节点2最后必然也会宕机,
4.负载均衡
针对上面的架构的问题,就有了解决办法:
使用nginx来做负载均衡,使用轮询算法,一条给节点1,一条给节点2,下一个请求还给节点1,这样就解决了上面的问题,但是又迎来了新的问题:
假设节点1的最大负载是8万,那么当节点1上现在已经达到满载8万时,下一条请求就是压死骆驼的最后一根稻草,当下一次请求进入节点1,节点1的负载就到了8万零一条,
这时节点1就会宕机。当节点1宕机后,nginx会继续尝试连接节点1,当尝试几次还是连接不上后,就会放弃连接,并将节点1标记为宕机状态。
节点1宕机后,所有的请求就会压在节点2上,那么最后结果是节点2也必然宕机
5.架构五,将项目拆分
将一个项目于分两个节点来存放,节点1就只存放门户网站,节点2存放登录的项目, 这样就将请求分不同的服务器处理了
假设此时又十万并发过来了,这十万并发中有两万是请求门户网站的,就访问节点1、3,八万是请求登录项目的就访问节点2、4,这样高并发的问题就解决了。可以查看dubbo架构:https://github.com/Zs-xiazhi/dubbo
并发的问题解决了,数据库又出现问题了:想象一下,随着项目的越来越大,用户越来越多,数据库中的用户表中的数据也越来越多,数据的查询就会非常慢,而且服务器集群中所有的服务器都是访问这一个数据库,那么数据库的压力就会很大。随着数据库中的数据越来越多,压力越来越大,数据库就会宕机,而服务器集群访问的只有这一台数据库,一旦数据库宕机,那么所有的项目都获取不到数据了。
6.架构六,设置主从数据库
因为上面已经解决了服务器集群高并发问题,因此就不详细画该部分了:
数据库设置主从关系库,正常运行时web服务器访问主库,所有的数据都存放在DB1上,当DB1宕机时,访问DB2,发现没有数据,因此DB1和DB2之间要做数据同步。
当DB1宕机期间,所有的数据都存放在DB2上,如果DB1修好了,这时发现DB2上有的数据DB1上没有,DB2就会自动向DB1同步数据,速度非常快,为了加快速度,可以将经常使用的且不经常修改的数据放入redis缓存中
这种架构出现的问题是:
1.如果DB1宕机,如何切换从库?
启用监听。项目启动后,web项目连接数据库DB1,当DB1连接超时,启用监听,切换数据库DB2
2.单表数据过大,数据库承受访问压力过大
单表数据量过大:分库分表
数据库承受访问压力过大:独写分离
7.分库分表
如上图所示,假设项目用户越来越多,那么用户表user内的数据就会越来越多,这时查询数据非常慢,使用分库分表,就是将同一张表放入不同的数据库中。
假设user表中有10万条数据,那么就在db1放1-5万条数据, db2中放5-10万条数据
在分库分表中,没有主从概念,所有的数据库都是平等的
问题:如何知道要查询的数据在那儿个数据库中?
假设用户需要查询一条数据, 那么服务器如何知道这条数据存在哪儿个数据库的表中的呢?所以需要在服务器和数据库之间建立一个命名节点,这也是一个数据库,里面存放的数据是每个数据库节点的数据范围。如:DB1---1-5万,DB2--5-10万。这样服务器访问数据库时,先到命名节点中查询要查的数据库是在哪儿个数据库上,然后再到相应的数据库中查询数据。
8.读写分离
分库分表完美解决了大量数据的存储问题,但是单个服务器压力过大的问题还没有解决,读写分离解决但服务器压力过大问题:中间的命名节点仍然存在,这里画漏了
读写分离:
就是把服务器端的select和增删改操作分离开来,对每一个数据库做标识(read-->只做select操作,write-->只做增删改操作)
读写分离是有主从概念的,并不是真的有主库和从库的区分,是有这个概念,读为主,写为从。
上图使用的是独写分离加上分库分表,这两种方式可以同时使用,也可以分开单独使用,并不冲突