简单聊聊 分布式

发布于:2023-01-17 ⋅ 阅读:(163) ⋅ 点赞:(0)

简单聊聊 分布式


1、CAP 原则

​  CAP原则 指的是在一个 分布式 系统中,一致性(Consistency)、可用性(Availability)、分区容错性(Partition tolerance)这三个要素最多只能同时实现两点,不可能三者兼顾。

  • 一致性(Consistency):所有的节点上的数据时刻保持同步
  • 可用性(Availability):每个请求都能接受到一个相应,无论相应成功或者失败
  • 分区容错性(Partition tolerance):系统应该能够持续提供服务,即使系统内部有消息丢失(分区)

补充:

​  取舍策略:

  • CA without P:不要求 分区,保证 一致性 和 可用性
  • CP without A:不要求 可用,保证 一致性 和 分区容错性(如:传统的数据库分布式事务)
  • AP without C:不要求 一致性,保证 可用性 和 分区容错性(如:NoSQL 分布式事务)



2、高并发

2.1、概述

​  高并发(High Concurrency),通常是指通过设计保证 系统 能够 同时并行 处理很多请求。


补充:

​  常见的高并发场景有:

  • 淘宝的双11
  • 春运时的抢票
  • 微博热搜


2.2、高并发的目标

2.2.1、宏观目标
  • 高性能

    ​  具体体现为 用户请求的响应时间。

  • 高可用

    ​  具体体现为 系统可以正常服务的时间。

  • 高扩展

    ​  具体体现为 系统的扩展能力(是否能够快速扩容)。


2.2.2、微观目标
  • 性能指标

    • 平均响应时间(常用,但对慢请求不敏感)

    • TP90、TP99 等分位值(分值越大,对慢请求越敏感)

      ​  将 响应时间 从小到大排序,TP90 表示排在第 90 分位的响应时间。

    • 吞吐量

      ​  和响应时间成反比,例如:响应时间 1ms,则吞吐量为 每秒 1000 次。

  • 可用性指标

    ​  可用性 = 平均故障时间 / 系统总运行时间。

     常用描述(故障可能性,系统基本要求是 保证 3个9 或者 4个9):

    可能性 年故障时间 日故障时间
    90% 36.5 天 2.4 小时
    99% 3.65 天 14.4 分钟
    99.9% 8 小时 1.44 分钟
    99.99% 53 分钟 8.6 秒
    99.999% 5 分钟 0.86秒
  • 可扩展指标

    ​  扩展性 = 性能提升比例 / 机器增加比例(通常来说,系统的扩展能力要维持在 70% 以上)。

    考虑点:

    • 数据库、缓存、消息队列、服务集群 等中间件
    • 负载均衡
    • 带宽
    • 依赖的第三方

2.3、高并发的实践方案

2.3.1、通用的设计方法
  • 纵向扩展(scale-up,单机方面)

    • 提升单机的硬件性能:增加内存、CPU 核数、磁盘容量
    • 提升单机的软件性能:使用缓存减少 I/O 次数、使用 并发 或 异步 的方式增加吞吐量
  • 横向扩展(scale-out,集群方面)

    • 做好分层架构(横向扩展的前提)

      常见的分层架构:

      在这里插入图片描述

    • 各层进行水平扩展

      ​ 无状态 做 水平扩容,有状态 做 分片路由;主从同步、读写分离。


2.3.2、实践方案

2.3.2.1、高可用(从 计算 和 I/O 两个维度考虑)

  1. 集群部署,通过 负载均衡 减轻单机压力
  2. 多级缓存,包括:静态数据使用 CDN、本地缓存、分布式缓存 等,以及对 缓存场景中的热点 key、缓存穿透、缓存并发、数据一致性 等问题的处理
  3. 分库分表 和 索引优化,以及借助 搜索引擎 解决复杂查询的问题
  4. 考虑 NoSQL 数据库的使用,如:HBase、TiDB 等
  5. 异步化,将次要流程通过 多线程、MQ、延时任务 进行异步处理
  6. 限流,包括:前端限流、Nginx 接入层限流、服务端限流
  7. 对流量进行削峰填谷,使用 MQ 承接流量
  8. 并发处理,通过 多线程 将 串行逻辑 并行化
  9. 预计算,如:抢红包场景,可以提前计算好红包金额缓存起来,发红包时直接使用即可
  10. 缓存预热,通过 异步任务 提前预热数据到本地缓存(或分布式缓存)中
  11. 减少 I/O 次数,如:数据库和缓存的批量读写、RPC 的批量接口支持、使用冗余数据的方式替代 RPC 调用
  12. 减少 I/O 时的数据包大小,包括:采用轻量级的通信协议、合适的数据结构、去掉接口中的多余字段、减少缓存 key 的大小、压缩缓存 value 等
  13. 程序逻辑优化,如:将大概率阻断执行流程的判断逻辑前置、for 循环的计算逻辑优化、采用更高效的算法
  14. 各种池化技术的使用和池大小的设置,包括:HTTP 请求池、线程池、数据库 和 Redis 连接池 等
  15. JVM 优化,尽可能减少 GC 频率和耗时,包括:新生代和老年代的大小、GC 算法的选择 等
  16. 锁选择,读多写少的场景使用乐观锁、通过分段锁减少锁冲突

2.3.2.2、高性能(从 冗余、取舍、系统运维 三个方向考虑)

  1. 对等节点的故障转移:Nginx 和 服务治理框架 均支持一个节点失败后访问另一个节点
  2. 非对等节点的故障转移:通过 心跳检测 并 实施主备切换,如:Redis 的哨兵模式(或集群模式)、MySQL 的主从切换 等
  3. 接口层面:超时设置、重试策略、幂等设计
  4. 降级处理:保证核心服务,牺牲非核心服务,必要时进行熔断;有 备选链路 供核心链路出问题时使用
  5. 限流处理:对超过系统处理能力的请求直接拒绝(或返回错误码)
  6. MQ 场景的消息可靠性保证:producer 端的重试机制、broker 端的持久化、consumer 端的 ack 机制 等
  7. 灰度发布:能支持按机器维度进行小流量部署,观察系统日志和业务指标,等运行平稳后再推全量
  8. 监控报警:全方位的监控体系,包括:CPU、内存、磁盘、网络的监控,web 服务器、JVM、数据库、各类中间件的监控 和 业务指标的监控
  9. 灾备演练:类似当前的 “混沌工程”,对系统进行一些破坏性手段,观察局部故障是否会引起可用性问题

2.3.2.3、高可扩展

  1. 构建合理的分层架构
  2. 对储存层进行拆分
  3. 对业务层进行拆分


3、分布式存储(分布式文件系统)架构

3.1、中间控制节点架构

​  以 HDFS(Hadoop Distribution File System)为代表的架构,在该架构中将 服务器 分为两种类型,一种负责管理 管理数据(元数据),称为 NameNode;另一种负责管理 业务数据(实际数据),称为 DataNode。

​  当 客户端 需要对某个文件进行读写操作时,首先从 NameNode 获取该文件的位置(具体在哪个 DataNode 中),然后在该位置完成相应的读写操作。

在这里插入图片描述


补充:

  • NameNode 通常为主备部署
  • DataNode 通常是由大量的节点构成一个集群
  • 由于 元数据 的访问频度和访问量 相对 数据 都要小得多,因此 NameNode 通常不会称为 性能瓶颈
  • DataNode 可以通过 横向扩展 数量 来增加承载力


3.2、完全无中心架构——计算模式

​  以 Ceph 为代表的架构,在该架构中 客户端 可以直接与存储节点通信(通过一个设备映射关系计算出来其写入数据的位置),从而完全避免中心节点的性能瓶颈。

​  当 客户端 需要对某个文件进行读写操作时,首先从 Mon 服务 拉取存储资源布局信息,然后根据该布局信息和文件的名称等信息计算出期望文件的位置(包括具体的物理服务器信息和磁盘信息),然后在该位置完成相应的读写操作。

在这里插入图片描述


补充:

  • 在 Ceph 存储系统架构中核心组件有 Mon 服务、OSD 服务 和 MDS 服务 等
  • 对于 块存储类型 只需要 Mon 服务、OSD 服务 和 客户端的软件即可
  • Mon 服务 用于维护存储系统的硬件逻辑关系,主要是 服务器 和 磁盘 等在线信息,Mon 服务 通过集群的方式保证其服务的可用性
  • OSD 服务 用于实现对 磁盘 的管理,实现真正的数据读写,通常一个磁盘对应一个 OSD 服务


3.3、完全无中心架构——一致性哈希

​  以 Swift 为代表的架构,该架构与 Ceph 架构的不同之处在于 获取文件位置的方式不同,该架构是通过一致性哈希的方式获得文件位置(即 将设备做成一个哈希环,然后根据文件名称计算出的哈希值映射到哈希环的某个位置,从而实现文件的定位)。

​  为了保证数据分配的均匀性及出现设备故障时数据迁移的均匀性,一致性哈希将 磁盘 划分为比较多的虚拟分区,每个虚拟分区是哈希环上的一个节点。

​  整个环是一个从 0 到 32 位最大值的一个区间,并且首尾相接。当计算出文件(或者文件名称)的哈希值后,必然落到哈希环的某个区间,然后以顺时针,必然能找到一个节点(即 文件存储的位置)。

在这里插入图片描述