6、使用反向代理和CDN加速网站响应

    为了进一步加快网站的访问速度,可以考虑使用CDN和反向代理。CDN部署在网络提供商的机房,当用户访问时,可以从距离用户最近的网络提供商机房获取数据。反向代理部署在网站自己的中心机房,当用户请求到达机房时,优先访问的服务器是反向代理服务器,如果反向代理中缓存了用户请求的资源,那么就直接返回给用户,加快了响应的速度,也减轻了后端负载的压力。CDN与反向代理的基本原理都是缓存。

这一阶段涉及到的知识体系:需要了解CDN和反向代理相关的知识

 

| 7、数据库的分库分表(垂直/水平拆分)及分布式文件系统

    我们的网站演进到现在,用户、商品、交易的数据都还在同一个数据库中。尽管采取了增加缓存,读写分离的方式,但随着数据库的压力继续增加,数据库的瓶颈越来越突出,此时,我们可以采用分库分表两种方法进行解决。

    分库:又叫垂直拆分,就是把数据库中不同的业务数据拆分到不同的数据库中,结合现在的例子,就是把用户、商品、交易的数据分开。优点:解决了原来把所有业务放在一个数据库中的压力问题,可以根据业务的特点进行更多的优化。缺点:需要维护多个数据库。

    分库所遇到的问题:1)需要考虑原来跨业务的事务;2)跨数据库的join

    解决方案:在应用层尽量避免跨数据库的事物,如果非要跨数据库,尽量在代码中控制。我们可以通过第三方应用来解决,如上面提到的mycat,mycat提供了丰富的跨库join方案,详情可参考mycat官方文档。

    分表:又叫水平拆分,就是把同一个表中的数据拆分到两个甚至多个数据库中。产生数据水平拆分的原因是某个业务表的数据量或者更新量到达了单个数据库的瓶颈,这时就可以把这个表拆分到两个或更多个数据库中。优点:如果我们能克服单个表过大的问题,那么我们将能够很好的应对数据量快速增长的情况。

    分表所遇到的问题:

    1)访问用户信息的应用系统需要解决SQL路由的问题,因为现在用户信息分在了两个数据库中,需要在进行数据操作时了解需要操作的数据在哪里。

    2)主键的处理也变得不同,例如原来自增字段,现在不能简单地继续使用了。 

    3)如果需要分页,处理起来比较麻烦。

    解决方案:我们还是可以通过第三方中间件来解决,如mycat。mycat可以通过SQL解析模块对我们的SQL进行解析,再根据我们的配置,把请求转发到具体的某个数据库。我们可以通过UUID保证唯一或自定义ID方案来解决主键问题。mycat也提供了丰富的分页查询方案,比如先从每个数据库做分页查询,再合并数据做一次分页查询等等。

    分表是系统数据库拆分的最后方法,只有在单表数据规模非常庞大的时候才使用,更常用的数据库拆分手段是业务分库,将不同的业务数据库部署在不同的物理服务器上。截止到目前,我们的数据库已经改成了分布式数据库,这时我们还可以采用分布式文件系统,用来应对数据量的大幅度增长。

 

这一阶段涉及到的知识体系:了解第三方中间件比如mycat,在分库分表中的应用。

 

| 8、使用NoSQL和搜索引擎

    随着网站业务越来越复杂,对数据存储和检索的需求也越来越复杂,网站需要采用一些非关系型数据库(NoSQL)和非数据库查询(搜索引擎)技术,这时我们可以引入NoSQL数据库及搜索引擎。应用服务器通过统一数据访问模块访问各种数据,减轻应用程序管理诸多数据源的麻烦。

    数据库做读库的话,常常对模糊查找力不从心,即使做了读写分离,这个问题还未能解决。以我们所举的交易网站为例,发布的商品存储在数据库中,用户最常使用的功能就是查找商品,尤其是根据商品的标题来查找对应的商品。对于这种需求,一般我们都是通过like功能来实现的,但是这种方式的代价非常大。此时我们可以使用搜索引擎的倒排索引来完成。 

    搜索引擎的优点:它能够大大提高查询速度。

    引入搜索引擎后也会带来以下的开销:

    1)带来大量的维护工作,我们需要自己实现索引的构建过程,设计全量/增量的构建方式来应对非实时与实时的查询需求。

    2)需要维护搜索引擎集群

    搜索引擎并不能替代数据库,他解决了某些场景下的“读”的问题,是否引入搜索引擎,需要综合考虑整个系统的需求。引入NoSQL和搜索引擎后的系统结构如下:

这一阶段涉及到的知识体系:

    搜索引擎:例如Elasticsearch、Solr、Sphinx等

    NoSQL:例如MongoDB、Hbase、Cassandra等

 

| 9、按业务模块拆分

    当业务模块越来越多,同时用户达到一定的级别后,需要通过分而治之的手段将系统分成多个模块,不同模块划分不同业务团队负责。具体到技术上,也会根据不同模块进行拆分,每个模块独立开发维护和部署。

这一阶段涉及到的知识体系:业务模块拆分,工作量比较大,需要对各业务非常熟悉,且非常认真负责。

 

| 10、服务化及中间件

    随着业务的拆分越来越小,系统的复杂度呈指数级上升,部署维护越来越困难。这时会面临以下问题:

    1)业务拆分后,可能会有一些相同的代码,如用户相关的代码,商品和交易都需要用户信息,所以在这两个系统中都保留差不多的操作用户信息的代码,这些代码如何可复用?

    2)由于所有的应用都需要跟数据库进行连接,导致数据库的连接资源不足,拒绝服务

    为了解决这些问题,我们需要将公用的功能进行独立提取,独立部署,向外提供可复用的统一分布式服务,这种方式又叫SOA。服务化之后,相同的代码不会散落在不同的应用中了,这些实现放在了各个服务中心,使代码得到更好的维护,同时我们把对数据库的交互放在了各个服务中心,让前端的web应用更注重与浏览器的交互工作,而新增业务也只需要调用这些分布式服务。但是同时,我们又遇到以下问题:

    1)如何进行远程的服务调用

    2)随着网站的继续发展,我们的系统中可能出现不同语言开发的子模块和部署在不同平台的子系统。此时我们需要一个平台来传递可靠的,与平台和语言无关的数据,并且能够把负载均衡透明化,能在调用过程中收集调用数据并分析之,推测出网站的访问增长率等等一系列需求,对于网站应该如何成长做出预测。

    这时我们可以通过引入消息中间件的方式来解决,例如阿里的dubbo,可以搭配Google开源的分布式程序协调服务zookeeper实现服务器的注册与发现。这一步的架构图如下:

    这一阶段涉及到的知识体系:需要识别可复用的业务,设计服务接口,规范服务依赖关系;要求对通信、远程调用、消息机制等有深入的理解和掌握,要求的都是从理论、硬件级、操作系统级以及所采用的语言的实现都有清楚的理解;运维这块涉及的知识体系也非常的多,多数情况下需要掌握分布式并行计算、报表、监控技术以及规则策略等等。

通常,演进到这一阶段需要耗费相当长的时间,也会碰到很多挑战:

    1)拆成分布式后需要提供一个高性能、稳定的通信框架,并且需要支持多种不同的通信和远程调用方式;

    2)将一个庞大的应用拆分需要耗费很长的时间,需要进行业务的整理和系统依赖关系的控制等;

    3)如何运维(依赖管理、运行状况管理、错误追踪、调优、监控和报警等)好这个庞大的分布式应用。

    经过这一步,差不多系统的架构进入相对稳定的阶段,同时也能开始采用大量的机器来支撑着巨大的访问量和数据量,结合这套架构以及这么多次演变过程吸取的经验来采用其他各种各样的方法来支撑着越来越高的访问量。

 

| 总结

    设计网站架构时一定要从小开始,架构随业务演变而演变,切记不要在业务还是0的时候去追求1的架构设计,那样的架构只会舍本逐末,得不偿失。整个网站架构的经典演变过程都和上面比较的类似,当然,每步采取的方案,演变的步骤有可能会不同,另外,由于网站的业务不同,会有不同的专业技术的需求,这篇文章更多的是从架构的角度来讲解演变的过程,当然,其中还有很多的技术也未在此提及,像数据挖掘、实时数据统计等,并且在真实的演变过程中还会借助像提升硬件配置、网络环境、改造操作系统等来支撑更大的流量,因此在真实的发展过程中还会有很多的不同。一个大型网站要做到的远远不仅仅上面这些,还有像安全、运维、运营、服务、存储等,要做好一个大型的网站真的很不容易。

posted on 2019-11-26 10:07  李留广  阅读(427)  评论(0编辑  收藏  举报