数据库作为IT系统中最关键的服务之一,其可用性一直是系统设计中的重点考虑因素。同时,由于数据库有数据有状态的天性,数据库高可用有其天然的复杂性和难点,云原生架构下尤其如此,是一个值得深入探讨的课题。本系列文章将基于网易杭州研究院的研究与实践,解析数据库高可用技术要点,梳理主流数据库方案,为数据库技术建设规划提供参考。
本文由作者授权网易云发布,未经许可,请勿转载!
作者:倪山三,网易杭州研究院运维工程师
Catalog
- 0. Prologue
- 1. 数据库高可用技术要点
- 1.1. 冗余设计 — 数据冗余方案
- 1.2. 冗余设计 — 冗余数据间的一致性
- 1.3. 冗余设计 — 实例冗余
- 1.4. 故障切换 — 服务角色
- 1.5. 故障切换 — 故障感知与应对
- 1.6. 故障切换 — 业务连接切换
- 2. 主流数据库方案概览
- 2.1. 主流数据库高可用功能概览
- 2.2. MySQL数据库高可用功能概览
接上文:
网易杭研总结:数据库高可用技术之道(1)
网易杭研总结:数据库高可用技术之道(2)
网易杭研总结:数据库高可用技术之道(3)
1.4. 故障切换 — — 服务角色
1.1~1.3章节属于高可用技术两个核心点中的第一个议题, 实例和数据如何冗余的范畴, 也是一般意义上高可用方案的表皮, 大家都很关注的内容, 其技术实现相信大家多少有所了解. 而从1.4开始的3个技术要点属于极容易被大家忽视的另一个核心议题, 假设服务和数据都有了冗余, 故障的时候要如何切换. 好比最开始的例子, 飞机有三条油路, 还得有自动切换功能, 不但如此, 万一自动切换功能不能用了, 还得提供机长手动切换功能.
那么先来看第一个要点, 冗余实例间是否需要区分在集群中的角色.
1.4.1. 有集群角色
多个数据库节点互相关联组成一个集群, 集群对外提供内部高可用冗余和一定的性能扩展能力, 对内需要协调治理每个节点的功能分工, 也就是形成角色. 角色大致有几类:
- 主库角色, 数据主题, 允许读写.
- 从库角色, 从当前主库同步数据, 通常最多允许只读, 不允许写入, 避免数据一致性风险.
- 根据整体架构差异, 部分数据库会有没有数据但是作为中间人监督参与其他节点角色选举的角色, 例如MongoDB的arbiter, 在其高可用架构中也是非常重要的角色.
当然最常见的还是主从角色. 而且对于大部分数据库来说, 就是一个集群允许有一个主, 然后多个从. Oracle (dataguard), redis (sentinel或cluster), MongoDB... 基本上所有shard nothing的架构都会对一个集群中的不同实例来区分主从, 主要是来定义当前哪个实例允许数据写入. 而Oracle RAC, TiDB, HBase等shard data的方案中由于数据要么允许多实例共同读写, 要么数据被分片了避免了写冲突, 因此通常不需要区分角色.
对于运用最普遍的shard nothing架构中, 数据库高可用场景下, 数据一致性风险主要来自于故障或切换过程中, 业务对多个节点的同时修改数据造成的数据冲突和丢失. 角色正是起到了防止这一风险的目的, 集群应当只有主角色可写.
![c8522e94738ab76d514facb87c4fe07a.png](https://img-blog.csdnimg.cn/img_convert/c8522e94738ab76d514facb87c4fe07a.png)
角色相当重要, 有角色就意味着集群内部有治理机制, 会做选举. 这是避免数据库集群脑裂的重要前提条件之一, 设置为不可写角色(从)相当于实现了IO fencing, 这部分在1.5章节中会继续展开.
![7274f738d6ac9ba42d2de109421a210a.png](https://img-blog.csdnimg.cn/img_convert/7274f738d6ac9ba42d2de109421a210a.png)
那作为线上运用最广泛的MySQL的情况? 这里的角色指的是集群通过内部节点间协商得到的合理的主从身份分配. 而传统意义上的MySQL就是真的没有这个机制. 虽然大家都知道MySQL有主有从, 但是传统MySQL是没有集群概念的, 主从是一个松散的配置概念, 是运维人员外部赋予的, 并非集群属性. 除了日志传输外MySQL主从间几乎没有其他任何关联, 对数据一致性缺乏保障. 你可以对MySQL复制链路的任何节点开启写, 并修改数据, 直到数据冗余因为冲突彻底瘫痪. 传统MySQL不组集群, 不通信, 不选举, 不区分角色, 一切都交给外部框架或中间件完成, 这方面来看, 其功能设计对高可用和数据一致性需求的支持可以说非常简陋.
但是现状也在改变, MySQL在5.7以及8.0中引入的MGR(mysql group replication)架构, 实现了集群内部通信, 协调选举, 区分角色的功能, MGR可以说是对MySQL高可用机制可靠性上的一次重要飞跃.
![687746cbc61e4e2e21ae498c0a7658b6.png](https://img-blog.csdnimg.cn/img_convert/687746cbc61e4e2e21ae498c0a7658b6.png)
MGR实际上也允许不区分角色做multi master多活, 利用乐观锁和冲突检测防止事务冲突, 但是真正有价值的我认为还是single master模式, 从角色强制不可写. 现在的主要问题是, MGR推广进度不算快, 作为线上存储数据最多, 功能最重要的数据库MySQL, 我认为MGR技术推广落地是非常重要的, 是接下来需要重点推动的关键工作.
1.4.2. 无集群角色
除了shard data架构的那批不需要区分可写节点的服务外, 还有什么主流数据库是没有角色的? 传统MySQL和postgreSQL是这样的, 只能通过引入外部中间件, MHA, clustercontrol等, 来松散定义集群, 集群内的节点并不严格区分角色, 稍有不慎就出现主从数据不一致, 高可用切换后服务脑裂等问题, 是非常不健康的架构.
未完待续
推荐阅读:
- 网易杭研总结:数据库高可用技术之道(1)
- 网易杭研总结:数据库高可用技术之道(2)
- 网易杭研总结:数据库高可用技术之道(3)
- MySQL Group Replication在网易使用和优化实践
- MySQL/InnoDB数据克隆插件(clone plugin)实现剖析
- 如何建设中台?中台建设的组织、支撑技术和方法论