分布式
[toc]
分布式
1. 概述
**分布式(distributed)**为了解决单个物理服务器容量和性能瓶颈问题而采用的优化手段, 将一个业务拆分成不同的子业务, 分布在不同的机器上执行, 服务之间通过远程调用协调工作, 堆外提供服务.
实现方式:
水平扩展: 增加机器的方式, 将流量平分到所有服务器, 所有机器都可以提供相同服务.
垂直拆分: 不同业务需求分发到不同机器上.
1.1 集群
集群(cluster): 多台不同的服务器部署相同应用或者模块, 构成一个集群, 通过负载均衡设备对外提供服务.
特点:
可扩展性: 集群中的服务节点, 可动态添加机器, 从而增加集群处理能力
高可用性: 如果集群某个节点发生故障, 这台节点上运行的服务可以被其他服务节点接管, 从而增强集群的高可用性
能力:
负载均衡: 能把任务比较均衡地分布到集群环境下的计算和网络资源
集群容错: 各种原因允许部分失败
1.2 分布式设计理念
目标: 提升系统整体性能和吞吐量另外尽量保证分布式系统的容错性.
实现两大思路:
中心化设计
- 两个角色: master, 和slave
- 角色职责: master监督slave, 分派任务, 如果slave挂掉. 将其任务分配给其他slave.
- 问题: 1. 最大问题master存在单点问题; master挂掉,真个集群崩溃. 2. master性能问题, 如果系统设计和实现不好, 问题会卡在master上.
- 单点问题解决办法: 主备2个master或者可以热备或者冷备, 也可以自动或者手动切换master, 还可以实现自动选举切换master, 提升系统可用性
去中心化
- 地位平等: 所有服务器角色一致
- "去中心化"不是不要中心, 而是由节点自由选择中心: 集群自发举行会议选举新的领导.
- 问题: 脑裂问题(由于网络故障, 被分为至少两个彼此无法通信的单独集群, 如果两个集群各自工作, 可能会产生严重的数据冲突和错误). 如果集群发生脑裂问题, 规模较小的集群就自杀或者拒绝服务
1.3 集群分布式区别
- 分布式: 一个业务拆分为多个子业务, 部署在不同的服务器上.
- 集群: 同一业务部署在多个服务器.
2. CAP定理
选项 | 描述 |
---|---|
Consistency(一致性) | 数据在多个副本之间能够保持一致的特性(严格的一致性) |
Availability(可用性) | 系统提供的服务一直处于可用状态, 每次请求都能获取到非错的响应(不保证获取数据为最新数据) |
Partition tolerance(分区容错性) | 遇到任何网络分区错误, 仍能够对外提供满足一致性和可用性的服务, 除非网络环境都发生故障 |
CAP仅使用于原子读写的NOSQL场景, 并不适合数据库系统. 现在的分布式系统具有更多的特性如扩展性,可用性等等.
当发生网络分区时, 如果要继续服务, 那么强一致性和可用性只能2选1. 也就是网络分区后P是前提, P之后才有C和A的选择. 也就是说分区容错性必须要实现.
3. BASE理论
BASE是由 Basically Available(基本可用), Soft-state(软状态), **Eventually Consistent(最终一致性)**三个短语缩写. 对CAP中一致性和可用性权衡的结果, 来源于对大规模互联网系统分布式实践的总结, 基于CAP定理逐步演化而来. 大大降低了我们对系统的要求.
3.1 核心思想
即使无法做到强一致性, 但每个应用都可根据自身业务特点, 采用适合的方式来使系统达到最终一致性, 也就是牺牲数据的一致性来满足系统的高可用性. 系统中一部分数据不可用或者不一致时, 仍需要保持系统整体"主要可用"
正对数据库领域, 主要实现是对业务数据拆分, 让不同数据分布在不同机器上, 以提升系统可用性, 主要2种做法: 按功能划分数据库, 分片(Mycat等)
3.2 基本可用
分布式系统在出现不可预知故障的时候, 允许损失部分可用性. 但绝不等价于系统不可用, 比如:
- 增加时间上损失: 正常0.5秒返回响应结果, 出现故障查询结果响应时间增加1-2秒
- 系统功能上缺失: 对于使用高峰, 保障系统稳定性, 部分用户被引导到一个降级页面
3.3 软状态
允许系统中的数据存在中间状态, 并认为中间状态的存在不会影响系统整体可用性, 即允许系统在不同节点的数据副本之间进行数据同步的过程存在延迟
3.4 最终一致性
系统所有的数据副本, 经过一段时间的同步后, 最终能够达到一个一致的状态. 本质是需要系统保障最终数据能够达到一致, 而不需要实时保证系统数据的强一致性.
4. 高可用
4.1 组件方法提高可用性及并发量
- 提高硬件能, 增加服务器(当服务器增加到某个程度, 系统提供的并发访问量几乎不变, 不能解决根本问题)
- 使用缓存(本地缓存, 分布式缓存)
- 消息队列(解耦, 削峰, 异步)
- 采用分布式开发(不同服务器部署在不同机器节点. 一个服务部署到多台机器上. 利用nginx负载均衡.)
- 数据库分库(读写分离), 分表(水平分布, 垂直分表)
- 采用集群(多台机器提供相同服务)
- CDN加速(静态资源缓存到离用户最近的网络节点)
- 浏览器缓存
- 合适连接池(数据库连接池, 线程池等)
- 适当使用多线程开发
4.2 设计高可用常用手段
- 降级: 服务器压力剧增情况下, 根据业务情况对一些服务和页面有策略的降级. 是否服务器资源保障核心任务允许. 不同异常等级执行不同的处理, 根据服务方式: 拒接服务, 延迟服务, 随机服务. 根据服务范围: 砍掉某个功能. 砍掉某个模块.
- 限流: 防止恶意请求, 恶意攻击, 或者方式流量超出系统峰值
- 缓存: 避免大量请求之间落到数据库, 将数据库击垮
- 超时和重试机制: 避免请求堆积造成雪崩
- 回滚机制: 快速修复错误版本
4.3 性能测试
自动化测试工具模拟多种正常, 峰值, 异常负载条件来对系统各项性能指标进行测试. 细分为:
- 基准测试: 系统施加较低压力时, 查看系统允许状况并记录相关数据作为基础参考
- 负载测试: 不断加压或者增加一定压力下持续时间. 直到系统某项或者多项性能指标达到安全临界值.此时继续加压. 系统处理能力会下降
- 压力测试: 超过安全负载情况下, 不断施加压力(增加并发请求), 直到系统崩溃或无法处理任何请求, 依此获得系统最大压力承受能力
- 稳定性测试: 测试系统在特点硬件, 软件, 网络下, 加载一定业务压力(模拟生产环境不同时间点, 不均匀请求, 呈波浪特性)运行一段较长时间, 以此检测系统是否稳定
常用工具为JMeter
4.3 大表优化
- 限定数据范围查询: 禁止不带任何限制数据范围条件的查询语句
- 读写分离
- 垂直分区: 数据库表相关性进行拆分. 数据表列的拆分, 列比较多的表拆分为多张表. 优点: 行数据变小, 减少读取block数, 减少IO次数. 简化表结构,易于维护. 缺点: 主键出现冗余, 需要管理冗余列, 引起join操作(可通过应用层join解决). 事务更复杂
- 水平分区: 保持表结构不变, 通过某种策略存储数据分片, 每一片数据分散到不同的表或者库中, 达到分布式目的, 可以支持非常大的数据量. 水平拆分最好分库. 优点: 支持非常大的数据量存储, 应用端改造也少. 缺点: 分片事务难以解决, 跨界点Join性能差, 逻辑负载. 尽量不要对数据进行分片, 如果实在要分片, 尽量选择客户端分片架构, 减少和中间件网络IO.
数据库分片方案: 1. 客户端分片: 分片逻辑在客户端, 通过修改和封装JDBC层来实现. 2.中间件代理: 应用和数据中间加一个代理词, 分片逻辑统一维护在中间件服务中.