1.什么是高可用性
高可用性不是绝对的,只有相对更高的可用性。可用性每提高一点,所花费的成本都会远超之前。高可用性实际上是在宕机造成的损失和
降低宕机时间所花费的成本之间取得一个平衡。
有时候人们将可用性定义成服务器正在运行的时间段。我们认为的可用性还应该包括应用是否能足够好的处理请求。
2.导致宕机的原因
1.运行环境 (35%)
2.性能问题 (35%)
3.复制 (20%)
4.各种类似的数据丢失和损坏 (10%)
1.在运行环境中,最普通的问题是磁盘空间耗尽
2.在性能问题中,最普遍宕机的原因是运行很糟糕的 sql
3.糟糕的 schema 和索引设计是第二大影响性能的问题
4.复制问题通常是由于主备数据不一致导致的
5.数据丢失问题通常是由于 drop table的误操作导致的
3.如何实现高可用性
可以通过同时进行以下2步来获得高可用性。首先,可以尝试避免导致宕机的原因来减少宕机时间。许多问题其实很容易避免,例如通过适当的配置,监控,以及规范或
安全保障措施来避免人为错误。第二,尽量保证在发生宕机时能够快速的恢复。最常见的策略是在系统中制造冗余,并且具备故障转移能力。这2个维度的高可用性可以通过
2个相关的度量来确定:平均失效时间(MTBF)和平均恢复时间(MTTR)。
1.提升平均失效时间(MTBF)
1.测试恢复工具和流程,包括从备份中恢复数据
2.遵守最小权限原则
3.保持系统干净,整洁
4.使用好的命名和组织来约定避免产生混乱
5.谨慎安排升级数据库服务器
6.在升级前,使用诸如Percona Toolkit 中的 pt-upgrade 之类的工具仔细检查系统
7.使用InnoDB并进行适当的配置,确保 InnoDB 是默认的存储引擎。如果存储引擎被禁用,服务器就无法启动。
8.确认基本的服务器配置是正确的
9.通过 skip_name_resolve 禁止 DNS
10.除非能证明有效,否则禁用查询缓存
11.避免使用复杂的特性,例如复制过滤和触发器等
12.监控重要组件和功能,特别是像磁盘空间和 RAID 卷这样的关键项目。
13.尽量记录服务器的状态和性能指标,如果可能就尽量永久保存
14.定期检查复制完整性
15.将备库设置为只读,不要让复制自动启动
16.定期进行查询语句的检查
17.归档并清理不需要的数据
18.为文件系统保留一些空间
19.养成习惯,评估和管理系统的改变,状态以及性能信息
2.降低平均恢复时间(MTTR)
通过在系统中建立冗余来避免系统完全失效,并避免单点失效问题。一个能够提供冗余和故障转移能力的系统架构,则是降低恢复时间的关键环节。
团队成员是最重要的可用资产,所以为恢复制定一个好的流程非常重要。拥有熟练技能,应变能力,训练有素的雇员,以及处理紧急事件的详细文档和经过仔细测试的流程,
对从宕机中恢复有巨大的作用。
4.避免单点失效
找到并消除系统中可能失效的单点,并结合切换到备库组件的机制,这是一种通过减少恢复时间(MTTR)来改善可用性的方法。思考并梳理整个应用,尝试去定位任何可能
失效的单点。系统中任何不冗余的部分都可能是一个失效的单点。
单点失效并不总是能够消除。增加冗余或许无法做到,因为有些限制无法避开。尝试去理解每一个影响可用性的部分,采取一种平衡的观点来看待风险,并首先解决其中
影响最大的那一个。可以采用2种方法来为系统增加冗余:增加空余容量和重复组件。一种提升可用性的方法是创建一个集群或服务器池,并使用负载均衡解决方案。
1.共享存储或磁盘复制
共享存储能够为数据库服务器和存储解耦,通常使用的是 SAN。使用共享存储时,服务器能够正常挂在文件系统并进行操作。如果服务器挂了,备用服务器可以挂在相同
的文件系统,执行恢复需要的操作,并在失效服务器的数据上启动MySQL。这个过程在逻辑上跟修复那台故障的服务器没什么区别,不过更快速,因为备用服务器已经启动,
随时可以运行。当开始故障转移时,检查文件系统,恢复InnoDB以及预热是最有可能遇到延迟的地方,但检查失效本身在许多设置中会花费很长时间。
共享存储有2个优点:可以避免除存储以外的任何其他组件失效所引起的数据丢失,并为非存储存储建立冗余提供可能。不过共享存储本身仍然可能是单点。
共享存储本身也有风险,如果mysql崩溃等故障导致数据文件损坏,可能会导致备用服务器无法恢复。我们强烈建议在使用共享存储时选择InnoDB存储引擎或者其他稳定的
ACID存储引擎。一次崩溃几乎肯定会损坏MyISAM表,需要花费很长的时间来修复,并且肯定会丢失数据。我们也强烈建议使用日志型文件系统。
磁盘复制技术是另外一个跟 SAN 类似效果的方法。mysql中最普遍使用的磁盘恢复技术是 DRBD,并结合 Linux-HA 项目中的工具使用。
DRBD是一个以 Linux 内核模块方式实现的秒级别同步复制技术。它通过网卡将主服务器的每个块复制到另外一个服务器的块设备上(备用设备),并在主设备提交块之前
记录下来。由于在备用DRBD设备上的写入必须要在主设备上的写入完成之前,因此备用设备的性能至少要和主设备一样,否则就会限制主设备的写入性能。同样,如果正在
使用 DRBD 磁盘复制技术以保证在主设备失效时有一个随时可以替换的备用设备,备用服务器的硬件应该跟主服务器的相匹配。带电池写缓存的 RAID 控制器对 DRBD 而言
几乎是必须的,因为在没有这样的控制器时性能会很差。
如果主服务器失效,可以把备用设备提升为主设备。因为 DRDB 是在磁盘块层进行复制,而文件系统也可能不一致。这意味着最好是使用日志型文件系统来做快速恢复。
一旦设备恢复完成,mysql 还需要运行自身的恢复。原故障服务器恢复后,会与新的主设备进行同步,并假定自身角色为备用设备。
从如何实际的实现故障转移的角度看,DRBD 和 SAN 很相似:有一个热备机器,开始提供服务时会使用和故障机器相同的数据。最大的不同是,DRBD是复制存储---不是
共享存储---所以当使用 DRBD 时,获得的是一份复制的数据,而 SAN 则是使用与故障机器同一物理设备上的相同数据副本。换句话说,磁盘复制技术的数据是冗余的,
所以存储和数据本身都不会存在单点失效问题。这2种情况下,当启动备用机器时,mysql服务器的缓存都是空的。相比之下,备库的缓存至少是部分预热的。
DRDB 有一些很好的特性和功能,可以防止集群软件普遍会遇到的一些问题。一个典型的例子是 '脑裂综合征',在2个节点上同时提升自己为主服务器时会发生这种问题。
可以通过配置 DRDB 来防止这种事件发生。
缺点:
1.DRDB 的故障转移无法做到秒级以内。它通常至少需要几秒钟的时间将备用设备提升为主设备,还不包括任何必要的文件恢复和mysql恢复。
2.它很昂贵。
3.对于MyISAM表来说实际上用处不大,因为MyISAM表崩溃后需要花费很长的时间来检查和修复。
4.DRDB 无法替代备份。
5.对于写操作增加了负担。你需要理解的是写入时,增加的延迟主要是由于网络往返开销和远程服务器存储导致的,特别对于小的写入而言延迟会更大。尽管增加的延迟
可能就 0.3ms,这看起来比在本地磁盘上的IO 4~10ms的延迟小多了,但却是正常的带有写缓存的RAID控制器的延迟的 3~4倍。使用DRDB导致服务器变慢最常见的原因
是mysql使用了InnoDB并采取了完全持久化模式,这会导致很多小的写入和 fsync() 调用,通过 DRDB 同步时会很慢。
我们倾向于只使用 DRBD 复制存放二进制日志的设备。如果主动节点失效,可以在被动节点上开启一个日志服务器,然后对失效主库的所有备库应用这些二进制日志。接下来
可以选择一个备库提升为主库,以替代失效的系统。
说到底,共享存储和磁盘复制的方式与其说是高可用性解决方案,不如说是一种保障数据安全的方法。只要有数据,就可以从故障中恢复,并且比无法恢复的情况的 MTTR更低。
2.MySQL同步复制
当使用同步复制的时候,主库上的事务只有在至少一个备库上提交后才能确认为其执行完成。这实现了2个目标:当服务器崩溃时没有提交的事务会丢失,并且至少有一个备库
拥有实时的数据副本。大多数同步复制架构运行在主动-主动模式。这意味着每个服务器在任何时候都是故障转移的候选者,这使得通过冗余获得高可用性更加容易。
1.MySQL Cluster
MySQL 中的同步复制首先出现在 MySQL Cluster 。它在所有的节点上进行同步的主---主复制,。这意味着在任何节点上写入;这些节点拥有同等的读写能力。每一行
都是冗余存储的,这样即使丢失了一个节点,也不会丢失数据,并且集群仍然能提供服务。
2.Percona XtraDB Cluster
3.基于复制的冗余
复制管理器是使用标准mysql复制来创建冗余的工具。尽管可以通过复制来改善可用性,但也有一些'天花板'会阻止mysql当前版本的异步复制和半同步复制获得和真正的同步
复制相同的结果。复制无法保证实时的故障转移和数据零丢失,也无法将所有节点等同对待。
复制管理器通常监控和管理三件事:应用和mysql间的通信,mysql服务器的健康度,以及mysql服务器间的复制关系。它们既可以修改负载均衡的配置,也可以在必要的时候
转移虚拟ip地址以使应用连接到合适的服务器上,还能够在一个伪集群中操纵复制以选择一个服务器作为写入节点。大体上操作并不复杂:只需要确定写入不会发送到一个还没有
准备好提供些服务的服务器上,并保证党需要提升一台备库为主库时记录下正确的复制坐标。
1.MMM
2.MHA
基于复制的冗余最终来说是好坏参半。只有在可用性的重要性远比一致性或者数据零丢失保证更重要时才推荐使用。
5.故障转移和故障恢复
冗余是很好的技术,但实际上只有在遇到故障需要恢复时才会用到。冗余一点儿也不会增加可用性或者减少宕机。在故障转移的过程中,高可用性是建立在冗余的基础上的。
冗余和故障转移结合可以帮助更快的恢复,MTTR 的减少将降低宕机时间并改善可用性。
如果系统拥有故障恢复能力,故障转移就是一个双向过程:当服务器A失效,服务器B替代它,在修复服务器A后可以再替换回来。
故障转移比仅仅从故障中恢复更好。
故障转移的缘由各不相同,因为负载均衡和故障转移在很多方面很相似,它们之间的界限比较模糊。总的来说,我们认为一个完全的故障转移解决方案至少能够监控并自动
替换组件。它对应用应该是透明的,负载均衡不需要提供这些功能。
Linux-HA 项目。
故障转移最重要的部分就是故障恢复。如果服务器间不能自如切换,故障转移就是一个死胡同,只能延缓宕机时间而已。这也是我们倾向于对称复制布局,例如双主配置,
而不会选择使用三台或者更多的联合主库来进行环形复制的原因。如果配置是对等的,故障转移和故障恢复就是在相反的方向上的相同操作。
1.提升备库或者切换角色
提升一台备库为主库,或者在一个主---主复制结构中调换主动和被动角色,这些都是许多MySQL故障转移策略很重要的一部分。
2.虚拟IP地址或者IP接管
可以为提供特定服务的MySQL实例指定一个逻辑IP。当mysql失效时,可以将ip地址转移到另外一台mysql服务器上。
这种方法的好处是对应用透明。它会中断已有的连接,但不要求修改配置。
不足之处:
1.需要把所有的ip地址定义在同一个网段,或者使用网络桥接
2.改变ip需要root权限
3.有时候还需要更新ARP缓存
4.需要确定网络硬件支持快速ip接管。有些硬件需要克隆MAC地址后才能工作
5.有些服务器即使完全丧失功能也会保持有ip地址,所以可能需要从物理上关闭或者断开网络连接。
等待更新扩展:
经常有这种情况,在某一层定义了一个冗余后,需要等待底层执行一些改变。
3.中间件解决方案
可以使用代理,端口转发,网络地址转换(NAT)或者硬件负载均衡来实现故障转移和故障恢复。它们是控制应用和服务器连接的中枢。但是,它们自身也引入了单点失效,
需要准备冗余来避免这个问题。
使用这样的解决方案,你可以将一个远程数据中心设置为看起来好像和应用在同一个网络里。这样就可以使用诸如浮动ip这样的技术让应用和一个完全不同的数据中心开始
通信。你可以配置每个数据中心的每台应用服务器,通过它自己的中间件连接,将流量路由到活跃数据中心的机器上。如果活跃数据中心的mysql彻底崩溃了,中间件可以路由
流量到另外一个数据中心的服务器池中,应用无需知道这个变化。
这种配置方法的主要缺点是在一个数据中心的apache服务器和另外一个数据中心的mysql服务器之间的延迟比较大。为了缓和这个问题,可以把web服务器设置为重定向模式。
这样的通信都会被重定向到放置活跃mysql服务器的数据中心。还可以使用http代理来实现。
4.在应用中处理故障转移