Friday, December 11, 2015

大型网站技术架构



http://blog.me115.com/2014/04/514

1.初始架构

一台服务器,应用、DB、文件都在一块,使用经典的LAMP模式构建整个站点;
优点很明显,开发部署都简单,船小好掉头,做不起来也亏不了多少;

2.应用服务与数据分离

随着访问量的增长,出现问题了:web性能变差,数据存储空间不够
这时候需要更多的服务器,首要任务是将数据库分离出来,单独占用一台服务器,如果文件读写多,需要增加文件服务器;不同的服务器对硬件的要求也不尽相同:
应用服务器需要处理大量业务逻辑,这需要更强的CPU;
数据库服务器需要快速磁盘检索和数据缓存,这需要更快的硬盘和更大的内存;
文件服务器需要存储用户上传的文件,需要更大的硬盘;

3.使用缓存改善网站性能

访问量持续增长,web性能再次变差;
考虑使用缓存改善网站性能;web的访问规律:80%业务访问集中在20%的数据上;使用缓存,数据库压力得到有效缓解;
缓存可通过以下方式增加:
增加应用服务器本地缓存,这个最直接,也最简单;
增加远程分布式缓存集群;当本地的内存不足以放下需要缓存的数据时,就只有通过分布式;
使用类似Memcached之类的开源缓存产品,缓存更多的数据;

4.应用服务器集群化

随着网站的成长,单一应用服务器成为网站瓶颈;
解决方案:应用服务器集群化提高网站并发处理能力;
做成集群的关键是增加负载均衡服务器来调度应用集群

5.数据库读写分离

问题:当增加缓存之后,随着访问量的持续增长,数据库再次出现问题:数据库负载压力过高
解决方案:数据库读写分离
利用数据库主从热备功能,实现读写分离;读写分离的细节这篇文章讲的很清楚了,就不多说,有需要的请参考:http://www.cnblogs.com/qlee/archive/2011/04/08/2009738.html

6.使用反向代理和CDN

问题:网站做大,全国甚至全球各区域的访问量都来了,但是各区域的访问速度差别巨大;
解决方案:使用反向代理和CDN
CDN和反向代理基本原理都是缓存,CDN部署在网络提供商的机房,用户请求最近的节点访问;而反向代理则部署在网站的中心机房;

7.使用分布式FS和分布式DBS

问题:应用集群如果将session管理做好,或做成无状态的应用集群,可达到线性伸缩;而数据库的压力却不是很好解决;
解决方案:使用分布式数据库拆分,可使用的方法有:
单表拆分:将不同的表放到不同的库中,从而降低单个数据库的结点的负载;这样带来的问题就是不同库中的表无法做join操作;
另一种方法就是按业务拆分,将属于同一业务的表划分到一个库中,从而有效降低数据库负载,同时在业务逻辑实现上不至于过于复杂;

8.使用NoSQL和搜索引擎

问题:出现海量数据存储和检索的需求
解决方案:使用NoSQl产品分布式部署来支持海量数据的查询和存储;

9.业务拆分

按照业务来划分子系统,按产品线划分系统,通过分布式服务来协同工作;
http://blog.me115.com/2014/04/534

分层

随着应用框架的普及,分层的概念已经深入人心;从我们学习写web代码开始,框架就要求我们通过分层开发来适应框架的结构;只是到后来,才逐渐体会到分层带来的好处;
最基本的分层一般分为以下三层:
应用层:面向终端用户的应用;
服务层:为应用层提供服务的通用服务;
数据层:数据存储层;
分层架构是逻辑上的,但物理上也可部署在不同的机器上。

分割

网站大了,通过分割网站的功能和业务,大而化小,将不同的模块分布式部署,从而提高并发处理能力和功能扩展能力;

分布式集群

当单机负载无法满足我们的需求时,就会考虑分布式:

分布式静态资源 (动静分离)

这是最为简单的分布式,将网站中的静态资源分离出去,部署到别的机器上, 减轻应用服务器压力;这种分离最为简单,而且性能提升明显;同时,采用独立域名,加大浏览器的并发加载量,让网站更快的呈现在用户面前;web优化中有这么一个优化顺序,先前端后后台,前端优化是需要时间最少而见效最快的方式,关于具体的优化步骤和效果,可以参考大CC之前写的这篇文章:WEB站点性能优化实践(加载速度提升2s)

分布式应用和服务

分层和分割后的应用分布式部署,提升性能、增加网站的伸缩性和扩展性;

分布式数据和存储

包括关系数据库的分布式和NoSQL的分布式;关系数据库的分布式,可以细分为分表和数据分片;数据库的分布式不是那么简单,阿里的OceanBase项目貌似是做到了关系数据库的分布式;
Nosql的分布式相对简单许多,例如新浪的redis使用场景,就是分布式存储微博内容;关于新浪redis的分布式应用,请移步这篇文章:Redis 在新浪微博中的应用

分布式计算

以Hadoop和MapReduce为代表的分布式计算,主要应用场景为日志分析、索引建立,数据挖掘等,实时处理的分布式计算还是见得少;

分布式要注意的问题

任何事务都有其两面性,分布式并不一定就是好的,在网络访问量小的时候,没必要分布式,单机处理能大大节省运维成本;
分布式需要注意以下问题:
  • 分布式服务器见通信的网络开销
  • 服务器多了,服务器宕机概率增大
  • 如何保持分布式存储的数据的一致性,一台机器宕机后故障恢复,如何保证一致性;
  • 分布式事务难以保证
  • 分布式部署后,结构会复杂很多,这带来了维护的困难

缓存

最简单的缓存是本地缓存:有页面缓存、前端页面静态化、前端页面的片段化缓存、以及数据缓存;大CC之前介绍过一篇关于Yii的缓存配置,有兴趣可以参考:Yii 的缓存(页面缓存配置实例)
需要缓存的内容多了,单机装不下,就得考虑分布式缓存;
反向代理也是缓存的一种,反向代理将缓存放到了应用层的前面,用户请求还未接入到应用层,反向代理就将之前被访问过的内容返回给用户;
CDN也是缓存,一般由第三方服务商提供;相比反向代理,CDN这个缓存与用户又近了一步;
下图展示了用户的WEB请求中会遇到的缓存;
image
CDN提供最基础的缓存(静态化的页面和静态资源(css、js等);
反向代理提供与CDN类似的数据;
WEB服务器的缓存提供片段化的缓存和警惕资源缓存;页面中变化的部分则需要通过web服务器生成,其中涉及到调用应用服务器;
应用服务器中的缓存为计算结果的缓存;主要是内容缓存;基础数据缓存;

异步

使用SEDA(分段消息驱动)设计,异步非阻塞技术,可提高系统可用性,加快网站响应速度;
异步还有个好处,就是消除并发访问高峰;发到后台的请求通过消息队列存起来,起到缓冲作用,后台按照其处理能力依次处理;
在实现上,单一服务器上使用多线程共享内存队列来实现异步,在集群中,通常使用分布式消息队列来实现,比如我们用到的MQ、ZeroQ等;

冗余

考虑到数据安全,备份必不可少;冷备份没有什么好说的,主要是热备,架构的设计中需要考虑数据的热备;

自动化

自动化应该是程序员最应该掌握的基础技能;一般而言,自动化要求的技术含量不是很高,但却是长期实践的经验结晶;自动化能有效的降低公司运营成本,提升程序员的生活质量,想想就欢乐,重复的工作都交给机器来做,创造性的工作才需要人来参与嘛;自动化主题广泛,大致包含以下方面:
发布过程自动化
自动化代码管理
自动化测试
自动化部署
自动化监控
自动化失效转移和恢复
自动化降级
自动化分配资源
架构设计中要考虑的核心五要素;
性能、可用性、扩展性、伸缩性、安全性
http://blog.me115.com/2014/04/554

性能

性能的测试指标

  • 响应时间
    应用执行一个操作需要的时间,包括从发出请求开始到收到最后响应数据所需要的时间。响应时间是系统最重要的性能指标,直观地反映了系统的“快慢”。下表列出了一些常用的系统操作需要的响应时间。
    image
  • 并发数
    系统能够同时处理请求的数目
  • 吞吐量 
    单位时间内系统处理的请求数量; 
    如:TPS、QPS(每秒查询数)
随着并发数的增大,吞吐量随着增大;
超过阈值后,并发数继续增大,吞吐量下降,直到吞吐量降为0,网站宕机;
理解上述3个指标:类比高速公路行车
吞吐量就是每天通过的车辆数
并发数是正在行驶的车辆
响应时间是车速

性能测试方法

  • 性能测试 
    以预期设定的性能值为目标,测试是否能满足预期
  • 负载测试 
    不断加压到安全临界值
  • 压力测试 
    超过安全负载直到崩溃下的最大负载
下图中的横坐标表示消耗的系统资源,纵坐标表示系统处理能力(吞吐量)。在开始阶段,随着并发请求数目的增加,系统使用较少的资源就达到较好的处理能力(a~b段),这一段是网站的日常运行区间,网站的绝大部分访问负载压力都集中在这一段区间,被称作性能测试,测试目标是评估系统性能是否符合需求及设计目标;随着压力的持续增加,系统处理能力增加变缓,直到达到一个最大值(c点),这是系统的最大负载点,这一段被称作负载测试。测试目标是评估当系统因为突发事件超出日常访问压力的情况下,保证系统正常运行情况下能够承受的最大访问负载压力;超过这个点后,再增加压力,系统的处理能力反而下降,而资源消耗却更多,直到资源消耗达到极限(d点),这个点可以看作是系统的崩溃点,超过这个点继续加大并发请求数目,系统不能再处理任何请求,这一段被称作压力测试,测试目标是评估可能导致系统崩溃的最大访问负载压力。
image
性能测试反应的是系统在实际生产环境中使用时,随着用户并发访问数量的增加,系统的处理能力。与性能曲线相对应的是用户访问的等待时间(系统响应时间),如图所示。
image
在日常运行区间,可以获得最好的用户响应时间,随着并发用户数的增加,响应延迟越来越大,直到系统崩溃,用户失去响应。

性能测试报告

测试结果报告应能够反映上述性能测试曲线的规律,阅读者可以得到系统性能是否满足设计目标和业务要求、系统最大负载能力、系统最大压力承受能力等重要信息,下表是一个简单示例。
image


可用性

高可用的应用服务器

构建高可用的应用服务器关键是session的处理,如果能使得每天机器上处理的请求都无状态,即可实现应用服务器的线性伸缩;服务器宕机后也可随时将请求放到其它机器上再次处理;
而对于需要处理状态信息的应用,解决方案是让每台机器使用共享的Session服务器,本地上还是无状态特征;

高可用的服务

设计要点
  • 分级管理 
    区别核心应用和一般应用;在流量增加到超过网站的处理能力时,为了保证核心应用的可用性,可以将一般应用的服务停止,将资源让位给核心服务; 
    比如博客中的博文显示和博客的评论功能;
  • 超时设置
  • 异步调用
  • 服务降级 
    eg:twitter:随机拒绝部分请求
  • 幂等性设计 
    保证多次调用结果一致

高可用的数据

CAP原理
一个提高服务的存储系统无法同时满足以下三个条件
一致性(Consistency)
数据可用性(Avalibility)
分区耐受性(Patition Tolerance,系统具有跨网络分区的伸缩性)
WEB架构设计中,通常为了保证高可用性,会牺牲一致性;
数据一致性分为:强一致、用户一致、最终一致;
大型WEB站点一般只保证数据的最终一致性;

扩展性

在网站新增业务产品时,实现对现有产品无影响,透明上线新产品。
主要手段
  • 事件驱动 
    利用消息队列实现
  • 分布式服务 
    将业务和可复用服务分离开

伸缩性

通过不断向集群中加入服务器的手段来缓解不断上升的用户并发访问压力。
可能加入的服务器有以下4类,其伸缩性能各不相同;

应用服务器

通过设计实现集群内服务器对等,使用合适的负载均衡可保证良好的伸缩性;

缓存服务器

缓存服务器伸缩性良好,但新加入服务器后可能导致缓存路由失效;
通过改进缓存路由算法,比如Memcached的一致性Hash,可实现加入新的缓存服务器后对原有缓存的影响尽量减少;

数据库服务器

很难做到大规模集群的可伸缩性
实现方式有:读写分离、数据表分库
(单表拆分:Cobar)
也可考虑伸缩性方案在数据库之外实现(通过路由分区)

NoSql产品

Nosql数据库就是为海量数据而生,可轻松实现集群规模的线性伸缩;
(Hbase使用Zookeeper选举master)

安全性

99.99%的设计标准:无单点、在线更新、自动切换

Labels

Review (572) System Design (334) System Design - Review (198) Java (189) Coding (75) Interview-System Design (65) Interview (63) Book Notes (59) Coding - Review (59) to-do (45) Linux (43) Knowledge (39) Interview-Java (35) Knowledge - Review (32) Database (31) Design Patterns (31) Big Data (29) Product Architecture (28) MultiThread (27) Soft Skills (27) Concurrency (26) Cracking Code Interview (26) Miscs (25) Distributed (24) OOD Design (24) Google (23) Career (22) Interview - Review (21) Java - Code (21) Operating System (21) Interview Q&A (20) System Design - Practice (20) Tips (19) Algorithm (17) Company - Facebook (17) Security (17) How to Ace Interview (16) Brain Teaser (14) Linux - Shell (14) Redis (14) Testing (14) Tools (14) Code Quality (13) Search (13) Spark (13) Spring (13) Company - LinkedIn (12) How to (12) Interview-Database (12) Interview-Operating System (12) Solr (12) Architecture Principles (11) Resource (10) Amazon (9) Cache (9) Git (9) Interview - MultiThread (9) Scalability (9) Trouble Shooting (9) Web Dev (9) Architecture Model (8) Better Programmer (8) Cassandra (8) Company - Uber (8) Java67 (8) Math (8) OO Design principles (8) SOLID (8) Design (7) Interview Corner (7) JVM (7) Java Basics (7) Kafka (7) Mac (7) Machine Learning (7) NoSQL (7) C++ (6) Chrome (6) File System (6) Highscalability (6) How to Better (6) Network (6) Restful (6) CareerCup (5) Code Review (5) Hash (5) How to Interview (5) JDK Source Code (5) JavaScript (5) Leetcode (5) Must Known (5) Python (5)

Popular Posts