技术博客-分布式

Posted by xiezg247 on January 1, 2016

分布式设计

扩展性设计

稳定性 & 高可用

  • 《系统设计:关于高可用系统的一些技术方案》
    • 可扩展:水平扩展、垂直扩展。 通过冗余部署,避免单点故障。
    • 隔离:避免单一业务占用全部资源。避免业务之间的相互影响 2. 机房隔离避免单点故障。
    • 解耦:降低维护成本,降低耦合风险。减少依赖,减少相互间的影响。
    • 限流:滑动窗口计数法、漏桶算法、令牌桶算法等算法。遇到突发流量时,保证系统稳定。
    • 降级:紧急情况下释放非核心功能的资源。牺牲非核心业务,保证核心业务的高可用。
    • 熔断:异常情况超出阈值进入熔断状态,快速失败。减少不稳定的外部依赖对核心服务的影响。
    • 自动化测试:通过完善的测试,减少发布引起的故障。
    • 灰度发布:灰度发布是速度与安全性作为妥协,能够有效减少发布故障。
  • 《关于高可用的系统》
    • 设计原则:数据不丢(持久化);服务高可用(服务副本);绝对的100%高可用很难,目标是做到尽可能多的9,如99.999%(全年累计只有5分钟)。

硬件负载均衡

软件负载均衡

限流

  • 《谈谈高并发系统的限流》
    • 计数器:通过滑动窗口计数器,控制单位时间内的请求次数,简单粗暴。
    • 漏桶算法:固定容量的漏桶,漏桶满了就丢弃请求,比较常用。
    • 令牌桶算法:固定容量的令牌桶,按照一定速率添加令牌,处理请求前需要拿到令牌,拿不到令牌则丢弃请求,或进入丢队列,可以通过控制添加令牌的速率,来控制整体速度。Guava 中的 RateLimiter 是令牌桶的实现。
    • Nginx 限流:通过 limit_req 等模块限制并发连接数。

应用层容灾

  • 《防雪崩利器:熔断器 Hystrix 的原理与使用》
    • 雪崩效应原因:硬件故障、硬件故障、程序Bug、重试加大流量、用户大量请求。
    • 雪崩的对策:限流、改进缓存模式(缓存预加载、同步调用改异步)、自动扩容、降级。
    • Hystrix设计原则:
      • 资源隔离:Hystrix通过将每个依赖服务分配独立的线程池进行资源隔离, 从而避免服务雪崩。
      • 熔断开关:服务的健康状况 = 请求失败数 / 请求总数,通过阈值设定和滑动窗口控制开关。
      • 命令模式:通过继承 HystrixCommand 来包装服务调用逻辑。
  • 《缓存穿透,缓存击穿,缓存雪崩解决方案分析》
  • 《缓存击穿、失效以及热点key问题》
    • 主要策略:失效瞬间:单机使用锁;使用分布式锁;不过期;
    • 热点数据:热点数据单独存储;使用本地缓存;分成多个子key;

跨机房容灾

  • 《“异地多活”多机房部署经验谈》
    • 通过自研中间件进行数据同步。
  • 《异地多活(异地双活)实践经验》
    • 注意延迟问题,多次跨机房调用会将延时放大数倍。
    • 建房间专线很大概率会出现问题,做好运维和程序层面的容错。
    • 不能依赖于程序端数据双写,要有自动同步方案。
    • 数据永不在高延迟和较差网络质量下,考虑同步质量问题。
    • 核心业务和次要业务分而治之,甚至只考虑核心业务。
    • 异地多活监控部署、测试也要跟上。
    • 业务允许的情况下考虑用户分区,尤其是游戏、邮箱业务。
    • 控制跨机房消息体大小,越小越好。
    • 考虑使用docker容器虚拟化技术,提高动态调度能力。
  • 容灾技术及建设经验介绍

容灾演练流程

平滑启动

数据库扩展

读写分离模式

分片模式

  • 《分库分表需要考虑的问题及方案》
    • 中间件: 轻量级:sharding-jdbc、TSharding;重量级:Atlas、MyCAT、Vitess等。
    • 问题:事务、Join、迁移、扩容、ID、分页等。
    • 事务补偿:对数据进行对帐检查;基于日志进行比对;定期同标准数据来源进行同步等。
    • 分库策略:数值范围;取模;日期等。
    • 分库数量:通常 MySQL 单库 5千万条、Oracle 单库一亿条需要分库。
  • 《MySql分表和表分区详解》
    • 分区:是MySQL内部机制,对客户端透明,数据存储在不同文件中,表面上看是同一个表。
    • 分表:物理上创建不同的表、客户端需要管理分表路由。

服务治理

服务注册与发现

服务路由控制

  • 《分布式服务框架学习笔记4 服务路由》
    • 原则:透明化路由
    • 负载均衡策略:随机、轮询、服务调用延迟、一致性哈希、粘滞连接
    • 本地路由有限策略:injvm(优先调用jvm内部的服务),innative(优先使用相同物理机的服务),原则上找距离最近的服务。
    • 配置方式:统一注册表;本地配置;动态下发。

分布式一致

CAP 与 BASE 理论

  • 《从分布式一致性谈到CAP理论、BASE理论》
    • 一致性分类:强一致(立即一致);弱一致(可在单位时间内实现一致,比如秒级);最终一致(弱一致的一种,一定时间内最终一致)
    • CAP:一致性、可用性、分区容错性(网络故障引起)
    • BASE:Basically Available(基本可用)、Soft state(软状态)和Eventually consistent(最终一致性)
    • BASE理论的核心思想是:即使无法做到强一致性,但每个应用都可以根据自身业务特点,采用适当的方式来使系统达到最终一致性。

分布式锁

  • 《分布式锁的几种实现方式》
    • 基于数据库的分布式锁:优点:操作简单、容易理解。缺点:存在单点问题、数据库性能够开销较大、不可重入;
    • 基于缓存的分布式锁:优点:非阻塞、性能好。缺点:操作不好容易造成锁无法释放的情况。
    • Zookeeper 分布式锁:通过有序临时节点实现锁机制,自己对应的节点需要最小,则被认为是获得了锁。优点:集群可以透明解决单点问题,避免锁不被释放问题,同时锁可以重入。缺点:性能不如缓存方式,吞吐量会随着zk集群规模变大而下降。
  • 《基于Zookeeper的分布式锁》
    • 清楚的原理描述 + Java 代码示例。
  • 《jedisLock—redis分布式锁实现》
    • 基于 setnx(set if ont exists),有则返回false,否则返回true。并支持过期时间。
  • 《Memcached 和 Redis 分布式锁方案》
    • 利用 memcached 的 add(有别于set)操作,当key存在时,返回false。

分布式一致性算法

PAXOS

Zab

Raft

Gossip

两阶段提交、多阶段提交

幂等

  • 《分布式系统—幂等性设计》
    • 幂等特性的作用:该资源具备幂等性,请求方无需担心重复调用会产生错误。
    • 常见保证幂等的手段:MVCC(类似于乐观锁)、去重表(唯一索引)、悲观锁、一次性token、序列号方式。

分布式一致方案

分布式 Leader 节点选举

TCC(Try/Confirm/Cancel) 柔性事务

  • 《传统事务与柔性事务》
    • 基于BASE理论:基本可用、柔性状态、最终一致。
    • 解决方案:记录日志+补偿(正向补充或者回滚)、消息重试(要求程序要幂等);“无锁设计”、采用乐观锁机制。

分布式文件系统

唯一ID 生成

全局唯一ID

  • 《高并发分布式系统中生成全局唯一Id汇总》
    • Twitter 方案(Snowflake 算法):41位时间戳+10位机器标识(比如IP,服务器名称等)+12位序列号(本地计数器)
    • Flicker 方案:MySQL自增ID + “REPLACE INTO XXX:SELECT LAST_INSERT_ID();”
    • UUID:缺点,无序,字符串过长,占用空间,影响检索性能。
    • MongoDB 方案:利用 ObjectId。缺点:不能自增。
  • 《TDDL 在分布式下的SEQUENCE原理》
    • 在数据库中创建 sequence 表,用于记录,当前已被占用的id最大值。
    • 每台客户端主机取一个id区间(比如 1000~2000)缓存在本地,并更新 sequence 表中的id最大值记录。
    • 客户端主机之间取不同的id区间,用完再取,使用乐观锁机制控制并发。

一致性Hash算法