大型网站技术架构 读书笔记

    1. 架构演化

    • 单机托管:应用程序 / 数据库 / 文件资源等
    • 应用服务与数据服务分离
    • 数据库缓存:解决数据库访问压力,包括本地缓存及远程分布式缓存集群
    • 集群部署:使用应用服务器集群解决高并发,负载均衡服务器负责分发访问请求
    • 读写分离:主库写入数据,从库读取数据
    • CDN / 反向代理:缓存静态资源及部分动态请求
    • 分布式数据库:解决数据容量瓶颈
    • 业务拆分:通过消息队列进行通信
    • 分布式服务调用

    2. 架构模式

    每一个模式描述了一个不断重复发生的问题及解决方案的核心,这样解决方案可以重复使用

    • 分层:将系统横向切分成几个单一职责的部分,通过上层对下层的依赖或调用组成一个完整系统。只要维持接口不变,各层根据业务具体问题独立演化发展
    • 分割:对软件系统进行纵向分割,不同的功能和服务分割包装成高内聚低耦合的模块单元,由独立的团队负责
    • 分布式 / 集群
    • 异步:降低系统间耦合性,即业务之间的消息传递不是通过同步调用,而是将一个业务操作分成多个阶段、各阶段之间异步执行
      • 提高可用性:即使消费者服务器故障,数据会在消息队列中堆积、生产者可以继续处理业务请求,系统整体表现无故障
      • 加快响应速度:前端的生产者服务器在写入消息队列后,不需等待消费者服务器处理即可返回响应
      • 削峰:将短时间内高并发产生的事务消息存储在消息队列
    • 冗余备份 / 失效转移:即数据通过定期备份(冷备)或实时同步(热备),以确保单台服务器宕机时、服务及数据访问转移到集群其他机器

    3. 架构要素(性能)

    指标:响应时间 / 并发数 / 吞吐量(TPS / QPS)/ 系统指标(System Load / Memory / IO)

    a. 使用缓存

    数据访问通常遵循二八原则,即80%访问落在20%数据;将数据存储在高速访问的存储介质,减少访问时间,避免重复计算。

    合理使用缓存:

    • 频繁修改的数据:即写入缓存后、应用来不及读取就已失效;多读少写(读写比 2:1 以上)
    • 数据不一致或脏读:即应用需要容忍一定时间的数据不一致
    • 缓存可用性:缓存服务崩溃时,数据库承受不起如此大的访问压力而宕机(缓存雪崩,故障发生时甚至不能简单地重启缓存服务器和数据服务器来恢复 / 缓存预热)
    • 缓存穿透:因为不恰当的业务或恶意攻击导致高并发请求某不存在的数据,会穿透到数据库

    分布式缓存架构 ( Memcached / NoSQL )

    • 通信协议 ( HTTP / TCP / UDP )
    • 通信序列化协议(JSON 等文本系列化协议 / PB 等二进制序列化协议)
    • 内存管理:避免内存碎片
    • 互不通信的服务器集群架构:应用程序通过一致性 Hash 等路由算法选择缓存服务器,缓存服务器间不通信;缓存集群的规模可以很容易实现扩容,具有良好的可伸缩性

    b. 代码优化

    • 多线程,解决线程安全:
      • 无状态对象(贫血模型)
      • 使用局部对象
      • 并发访问资源时加锁
    • 资源复用,如数据库连接、网络通信连接、线程、复杂对象等:
      • 单例模式
      • 对象池

    c. 存储优化

    • 机械硬盘具有快顺序读写、慢随机读写的访问特性,使用 SSD 作为存储介质
    • B+ 树 vs. LSM 树:文件系统或数据库系统通常对数据排序后存储,需要确保数据在更新/插入/删除后依旧有序

    4. 架构要素(高可用)

    大型网站的分层架构及物理服务器的分布式部署,使得位于不同层次的服务器具有不同的可用性特点

    • 应用层:通过负载均衡设备将一组服务器组成集群共同对外提供服务,通过心跳检测等监控单台服务器可用
    • 服务层:服务层的服务器会被应用层通过分布式服务调用框架访问,框架在应用层客户端实现软负载均衡,并通过服务注册中心对提供服务的服务器进行心跳检测
    • 数据层:多实例主从同步

    高可用服务策略

    • 分级管理:核心应用和服务使用更好的硬件及运维策略,且服务部署上做必要的隔离,避免故障连锁反应
    • 超时设置:设定服务调用的超时时间,一旦超时、通信框架抛出异常,应用程序根据服务调度策略重试或将请求路由到其他机器
    • 异步调用:避免一个服务失败导致整个应用请求失败
    • 服务降级:低优先级的服务(随机)拒绝服务,减少并发数并节约资源
    • 幂等设计:确保重复调用和一次调用具有相同的结果

    CAP 理论:一个提供数据服务的存储系统无法同时满足

    1. 数据一致性 Consistency : 所有应用程序访问得到相同的数据
    2. 数据可用性 Availibility : 任何时候、任何应用程序都可以读写访问
    3. 分区耐受性 Patition Tolerance : 系统可以跨网络分区线性伸缩

    大型网站一般选择强化分布式存储系统的可用性 A 和伸缩性 P, 放弃强一致性(即各副本的物理存储完全一致),采用用户数据一致策略(用户访问时、通过纠错和校验机制确保返回一致的数据),或最终一致(即经过一段时间修正,数据达到一致)

    发布策略

    • 代码版本控制、自动化回归测试
    • 预发布验证:预发连接生产数据及配置,部署在相同的物理环境,但不配置在负载均衡服务器、不暴露给外部用户,通过使用 IP 地址直接访问并做验证
    • 灰度发布:进行用户测试或确保集群渐进发布及快速回滚

    5. 架构要素(可伸缩)

    负载均衡

    • HTTP 重定向 302 负载均衡
    • DNS 负载均衡:配置多个A地址,根据负载均衡算法返回 IP 地址;缺点在于 DNS 多级解析带来的缓存失效问题。一般将 DNS 作为第一级负载均衡手段
    • 反向代理负载均衡:用户请求达到反向代理服务器后,转发 HTTP 请求及响应
    • IP 负载均衡(网关服务器):用户请求数据包达到后,修改 IP 包目的地址并转发,即在内核进程即完成转发
    • 链路层负载均衡 ( LVS ) 负载均衡分发过程中仅修改 MAC 地址,应用服务器和负载均衡服务器使用相同的虚拟 IP. 响应数据包不经负载均衡服务器、直接返回用户,避免负载均衡服务器带宽成为瓶颈

    负载均衡算法

    • 轮询:请求依次分发到每台服务器
    • 加权轮询:按权重分发
    • 随机
    • 最少连接 Least Connections:记录每个应用服务器正在处理的连接数,将新到请求分发到最小连接的服务器上
    • 源地址散列 Source Hashing:同一个 IP 的请求仅分发到同一个服务器,便于实现会话粘滞