系统设计:如何让系统高可用?
系统设计:如何让系统高可用?
系统的高可用性是指系统具备较高的无故障运行的能力。
很多开源组件中可以看到 HA 方案就是提升组件的可用性,让系统免于宕机无法服务的方案。
举个例子, Hadoop 1.0 中 NameNode 是单点的,一旦发生故障则整个集群不可用,Hadoop 2.0 时 ,采用的是两个 NameNode. 一个状态是Active,一个状态是 Standy 状态,两者共享存储。一旦 Active NameNode 发生故障,Standy NameNode 切换成 Active 状态继续提供服务。
一个高并发大流量的系统,系统出现故障比系统性能低更影响用户体验。一个日活百万的网站,如果出现一分钟故障,可能就影响了上千用户。
如何度量一个高可用系统?
系统可用性计算:
MTBF
Mean Time Between Failure 是瓶颈故障间隔的意思,代表两次故障的间隔时间,也就是系统正常运转的平均时间。这个时间越长,系统稳定性越高。
MTTR
Mean Time To Repair 表示故障的恢复时间,也可以理解为瓶颈故障时,这个值越小,故障对于用户的影响越小。
Availablity = MTBF/(MTBF+MTTR)
这个比例表示的是系统的可用性:
一般来说,核心系统的稳定性需要达到 4个9 ,非核心系统的可用性最多容忍 3个9 。
高可用系统设计思路
看MTBF 系统故障间隔时间 ,MTTR 系统故障恢复时间。因此高可用的设计思路主要两个方面:
- 系统设计,让系统更稳定
- 运维角度,让系统恢复更快。" Design for failture ",主要方法有:failover(故障转移),超时控制,限流,降级。
系统设计
故障转移 failover
- 同级别的 failover
完全对等节点之间做 failover。这类系统所有节点都承担读写流利,并且节点中不保存状态,每个节点都可以作为另外的一个节点的镜像。
举个例子:
Nginx 可以配置当某一个 Tomcat 出现 500 的请求时候,重试请求另外一个 Tomcat 节点。
2. 不同级别的 failover
主要指的是一个主从节点,可以在客户端上定期向主节点发送心跳包,也可以从备份节点上定期发送心跳包。选主的结果需要在多备份节点上达成一致。一般采用分布式一致性算法 paxos 或者 Raft.
超时控制
比如RPC框架,默认超时是30秒,平时运行可能比较稳定,但是一旦遇到比较大的流量,RPC 会出现一定数量的慢请求时 ,RPC 调用就可能超过30s ,造成 RPC 客户用尽调用线程而宕机。如歌设置了超时,就可以在出现慢请求是,触发超时,不会导致系统雪崩。
如何确定超时时间?
超时时间,一般通过收集系统之间的调用日志来确定,比如统计 99% 的响应时间是怎样的,然后根据这个时间来指定超时时间。
超时控制,其实是不让请求一直保持,经过一段时间后,释放资源给其他请求,避免消耗系统资源,导致雪崩。
服务降级
降级是为了保证核心服务的稳定从而牺牲非核心服务的做法。
在日常流量下,采用反垃圾邮件系统,对流量进行检查,虽然比较耗时但是依然能正常响应,但是在高并发情况下,这样反垃圾邮件系统的就可能成为瓶颈,这个时候就需要关闭掉反垃圾邮件系统,让主流量更加稳定。
服务限流
限流是对并发的请求进行限速来保护系统。
限制单机只能处理每秒 1000 次请求,超过的部分直接返回错误给客户端,限流一般是短暂行为。
系统运维
保证系统的可用性从运维角度,可以从灰度发布,故障演练两个方面考虑如何提升系统的可用性。
灰度发布
会不发布是指系统变更不是一次性推到生产上,按照一定比例推进, 一般情况下,灰度发布是以机器维度进行的。灰度发布是在系统正常运行条件下,保证系统高可用的运维手段。以便于在出现问题时快速回滚恢复。
故障演练
故障演练是指在发生故障时,如何快速恢复。
故障演练是指在系统进行一些破坏,观察出现局部问题时,整体的系统表现,从而发现系统潜在的问题。建议在线下搭建和线上部署结构一样的系统,这样可以在这套系统上故障演练,避免对生产系统影响。
欢迎关注公众号:程序员开发者这社区
- AtCoder Beginner Contest 069【A,水,B,水,C,数学,D,暴力】
- 2017"百度之星"程序设计大赛 - 资格赛【1001 Floyd求最小环 1002 歪解(并查集),1003 完全背包 1004 01背包 1005 打表找规律+卡特兰数】
- 洛谷 2634&&BZOJ 2152: 聪聪可可【点分治学习+超详细注释】
- 【经验总结】Java在ACM算法竞赛编程中易错点
- 【Java学习笔记之六】java三种循环(for,while,do......while)的使用方法及区别
- 类A是公共的,应在名为A.java的文件中声明错误
- 逆天通用水印支持Winform,WPF,Web,WP,Win10。支持位置选择(9个位置 ==》[X])
- 【Java学习笔记之七】java函数的语法规则总结
- BZOJ 3038: 上帝造题的七分钟2【线段树区间开方问题】
- BZOJ 3211: 花神游历各国【线段树区间开方问题】
- WP、Win10开发或者WPF开发时绘制自定义窗体~例如:一个手机
- 【Java学习笔记之八】JavaBean中布尔类型使用注意事项
- BZOJ 1597: [Usaco2008 Mar]土地购买【斜率优化+凸包维护】
- BZOJ 1046: [HAOI2007]上升序列【贪心+二分状态+dp+递归】
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Angular list列表绑定的一个例子
- Angular双向绑定的一个例子
- mysqlbinlog命令详解 Part 3 - 查看十六进制格式内容
- MySQL information_schema详解 CHARACTER_SETS 表
- 彻底弄懂 Unicode 编码
- 两种使用代码获得SAP CRM product sales status的办法
- C#: "$"作用和用法
- SAP ABAP字符和字符串变量隐式转换的一些规则
- MySQL information_schema详解 COLLATION_CHARACTER_SET_APPLICABILITY
- 如何处理Angular项目在Visual Studio Code打开报关于@Decorators的警告信息
- QT 中普通数值与字符串之间的转换
- C# 时间与时间戳互转 13位
- 在C#中ref和out具体怎么使用?在什么情况下使用?
- Vs code 创建vue模版
- [892]python中re.split()方法