小网站发展成大型网站的过程,就像游戏中的升级打怪一样,不同的阶段需要不同的技能。网上有很多架构演进的文章,不过他们更多的讲的是每次演进的结果,并没有很详细的讲为什么需要这样的演变。
本文将通过一个包含用户模块、商品模块和交易模块的时尚电商网站来阐述一个小网站发展成大型网站的过程中所遇到的问题、解决方案和所需要掌握的知识体系。这个发展过程是一种较为典型的架构演变历程,不管您的公司目前处于哪个阶段,总能找到适合您公司下一个阶段的框架及所需要了解的知识。
分布式架构的演进过程如下:
1、单机网站架构
2、应用与数据分离
3、使用缓存改善网站性能
页面缓存、页面片段缓存、数据缓存
4、应用服务器集群
5、数据库读写分离
6、使用反向代理和CDN加速网站响应
7、数据库的分库分表(垂直/水平拆分)及分布式文件系统
8、使用NoSQL和搜索引擎
9、按业务模块拆分
10、服务化及中间件
1、单机网站架构假如我们要做一个时尚电商网站,网站最开始的时候只有一些朋友圈的好友访问,这时只需要一台服务器就够了。应用程序、数据库、文件等所有的资源都放到这台服务器上,可以采用LAMP(linux+apache+mysql+php)架构或linux+tomcat+maven+springboot+mybatis+mysql架构,这些都是开源软件,可以在网上很方便的找到并安装。
单机网站架构
这一阶段涉及到的知识体系:LAMP(linux+apache+mysql+php)或linux+tomcat+maven+springboot+mybatis+mysql
2、应用与数据分离随着用户量的增加,服务器的负载慢慢提高,导致性能越来越差,数据量越来越多也导致存储空间不足。假如我们代码层面已难以优化,在不提高单台机器性能的情况下,可以通过增加机器的方式将应用和数据分离,分离后系统分为三台服务器:应用服务器、文件服务器和数据库服务器。
应用与数据分离
这三台服务器对硬件资源的要求各不相同:应用服务器需要处理大量的业务逻辑,因此需要更快更强大的CPU;数据库服务器需要快速磁盘检索和数据缓存,因此需要更快的磁盘和更大的内存;文件服务器需要存储大量用户上传的文件,因此需要更大的磁盘。
优点:应用服务器跟数据服务器分离后,不同特性服务器承担不同的服务角色,系统并发能力和存储能力都得到了很大加强,并且不会因为数据库和应用形成互相的影响。
这一阶段涉及到的知识体系:这一步架构演变对技术上的知识体系基本没有要求。
3、使用缓存改善网站性能好景不长,随着访问的人越来越多,响应速度又开始变慢了,查找原因,发现是访问数据库的操作太多,导致数据连接竞争激烈,所以响应变慢,因此考虑采用缓存机制来减少数据库连接资源的竞争和对数据库读的压力。
从缓存的对象来分类,后端缓存可以分为:页面缓存、页面片段缓存和数据缓存。页面缓存:我们可以把系统中相对静态的页面(例如一两天才会有更新的页面)进行缓存,可以采用squid等类似的机制,也可以采用将页面静态化的方案。页面片段缓存:我们可以把动态页面里相对静态的部分也缓存起来,可以采用类似ESI之类的页面片段缓存策略。数据缓存:大家都知道80%的业务访问集中在20%的数据上,我们可以考虑把这部分热数据放到缓存中,以降低数据库的压力。
从缓存的存储来分类,后端缓存可以分为:本地缓存和远程缓存。本地缓存:基于内存,访问速度更快,但是受限于硬件资源大小。远程缓存:可以使用Redis或Memcache等内存数据库,采用集群部署,理论上不限容量。
使用缓存改善网站性能
优点:对于一些页面和热数据采用缓存后,可以极大的降低数据库服务器的压力,提高网站性能。
这一阶段涉及到的知识体系:页面缓存技术,例如squid等类似的机制;页面静态化;页面片段缓存技术,例如ESI等;一致性Hash算法;Redis或Memcache等内存数据库的相关知识;
4、应用服务器集群随着系统访问量的再度增加,应用服务器的压力越来越大,遇到访问高峰时,甚至会成为系统的短板,同时单台应用服务器如果down机的话,系统就无法访问了。为了解决性能和可用性的问题,我们跟公司申请,增加了两台应用服务器。应用服务器实现集群化是一种成熟的可伸缩架构。
这时我们会遇到以下问题:
1)用户的请求如何转发到某台具体的应用服务器?
2)用户如果每次访问到的应用服务器不一样,如何维护session的一致性?
3)如何保持数据缓存信息的同步,例如之前缓存的用户数据等?
4)如何让上传文件等类似的功能继续正常?
第一个问题即是负载均衡的问题,一般有5种解决方案:http重定向、DNS域名解析负载均衡、反向代理服务器、IP层负载均衡和数据链路层负载均衡,每种解决方案都各有优劣。解决负载均衡问题的软件一般有:Apache自带的负载均衡方案、LVS这类的软件负载均衡方案、keepalived+ipvsadm、nginx等,目前很多公司采用nginx来实现负载均衡。
第二个问题是session问题,一般有四种解决方案:SessionSticky、SessionReplication、Session数据集中存储和CookieBase,下面简单介绍下这四种解决方案:
SessionSticky:sessionsticky就是把同一个用户在某一个会话中的请求,都分配到固定的某一台服务器中,这样我们就不需要解决跨服务器的session问题了,常见的算法有ip_hash法。优点:实现简单。缺点:应用服务器重启则session消失。
SessionReplication:sessionreplication就是在集群中复制session,使得每个服务器都保存有全部用户的session数据。优点:减轻负载均衡服务器的压力,不需要要实现ip_hasp算法来转发请求。缺点:复制时宽带开销大,访问量大的话session占用内存大且浪费。
Session数据集中存储:session数据集中存储就是利用数据库来存储session数据,实现了session和应用服务器的解耦。优点:相比sessionreplication的方案,集群间对于宽带和内存的压力减少了很多。缺点:需要维护存储session的数据库。
CookieBase:cookiebase就是把session存在cookie中,有浏览器来告诉应用服务器我的session是什么,同样实现了session和应用服务器的解耦。优点:实现简单,基本免维护。缺点:cookie长度限制,安全性低,宽带消耗。
第三个问题可以采用缓存同步或分布式缓存方法解决。
第四个问题通常使用的是共享文件系统或存储等。
应用服务器集群
优点:应用服务器集群化之后,可以支持更大的用户访问量,同时单台服务器down机的话,用户请求可以实时切换到其他服务器上,系统无影响。
这一阶段涉及到的知识体系:
负载均衡技术:包括但不限于硬件负载均衡、软件负载均衡、负载算法、linux转发协议、所选用的技术的实现细节等
主备技术:包括但不限于ARP欺骗、linuxheart-beat等
状态信息或缓存同步技术:包括但不限于Cookie技术、UDP协议、状态信息广播、所选用的缓存同步技术的实现细节等
共享文件技术:包括但不限于NFS等
存储技术:包括但不限于存储设备等
5、数据库读写分离有一天你会发现,由于添加的webserver太多了,导致数据库连接的资源还是不够用,这个时候你开始分析数据库的压力状况,可能会发现数据库的读写比很高,这个时候通常会想到数据库读写分离的方案。
数据库的读写分离是建立在主从热备的基础上的,基本目前大多数主流数据库都支持主从热备,通过配置两台或者多台数据库的主从关系(1主1从,1主多从,多主多从),实现数据的读(从库)写(主库)分离,主库主动将数据同步到从库。分离之后,写到主库,从从库读,但是这样会带来几个问题:
1)主从的数据库之间的数据同步:可以使用mysql自带的master-slave方式实现主从复制
2)对应的数据源的选择:可以采用第三方数据库中间件,例如:mycat,mycat是国内比较好的mysql开源数据库分库分表中间件。
数据库读写分离
优点:一般情况下,读请求量会远高于写请求,读写分离后,当读请求比较大的时候,可以横向扩展从库服务器,从而支持更大的访问量。
这一阶段涉及到的知识体系:数据读写分离要求对数据库的复制、standby等策略有深入的掌握和理解,同时要求具备自行实现的技术。
本篇文章介绍了一下前5个演进过程,下篇文章会介绍接下来的5个演进过程。