热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

服务没有响应控制功能mysql_详解Mysql高可用方案之Failovermha

在分布式系统中,我们往往会考虑系统的高可用,对于无状态程序来讲,高可用实施相对简单一些,纵向、横向扩展起来相对容易ÿ

3e0d6711eff0e569f2a99726c6e4923c.gif

在分布式系统中,我们往往会考虑系统的高可用,对于无状态程序来讲,高可用实施相对简单一些,纵向、横向扩展起来相对容易,然而对于数据密集型应用,像数据库的高可用,就不太好扩展。我们在考虑数据库高可用时,主要考虑发生系统宕机意外中断的时候,尽可能的保持数据库的可用性,保证业务不会被影响;其次是备份库,只读副本节点需要与主节点保持数据实时一致,当数据库切换后,应当保持数据的一致性,不会存在数据缺失或者数据不一致影响业务。很多分布式数据库都把这个问题解决了,也能够通过很灵活的方式去满足业务需求,如同步、半同步方式、数据副本数量、主从切换、failover 等等(下面会提到),然而我们平时使用的社区官方版 mysql5.7及以前的版本 (不包括 Mysql 其他分支像 PhxSQL,Percona XtraDB Cluster,MariaDB Galera Cluster) 都在支持分布式和系统可用性这块处理得不是很完善。针对这个系列问题,下面分析下如何解决这个问题。在这期间发现并提交合并了一个mha在线切换master 而导致master 和slave 数据不一致的bug:https://github.com/yoshinorim/mha4mysql-manager/pull/86何为failover提mha之前,提前普及一下failover。何为failover,即当活动的服务或应用意外终止时,快速启用冗余或备用的服务器、系统、硬件或者网络接替它们工作,故障转移(failover)与交换转移操作基本相同,只是故障转移通常是自动完成的,没有警告提醒手动完成,而交换转移需要手动进行,对于要求高可用和高稳定性的服务器、系统或者网络,系统设计者通常会设计故障转移功能。简单来说就是当系统某块服务不可用了,系统其它服务模块能够自动的继续提供服务,有很多设计良好的开源软件设计都会自动包含failover,像负载均衡nginx,haproxy可以支持后端检测,backup,当检测到后端upstream(endpoints)异常,会自动的无缝进行切换到正常的backup上,然后像分布式的数据密集型应用也会包含failover,包括mongdb副本集,etcd/zookeeper 节点选举,elasticsearch副本集等等,当存在部分数据节点异常,选举数据节点为master/primary/leader,甚至消息队列像rabbitmq镜像队列,kafka replicas都会包含failover。链接:zookeeper leader选举etcd-raftetcd-raft可视化mongdb副本集rabbitmq镜像队列kafka ISR和同步elasticsearch replics数据复制前面提到了failover,那么既然系统支持failover,那必须要保证能有 backup 或者是 replics 来作为新 "master"(这里把leader/master/primary都统称为master )继续提供服务。前面提到了很多开源软件设计过程中就自带了数据同步功能,就是数据所有的插入、删除、更新都在 master 上进行,然后数据会同步到 slave 里,简单来说需要保持 master-slave 数据一致。这里同步的方式可以像 mysql-bin log,mongdb optlog 通过日志的方式实现,将 update(),delete(),insert() 等操作记录到 log 中,然后这些语句都转发给每个从库,每个从库解析并执行该SQL语句,就像从客户端请求收到一样,在从库中重放该数据;也可以通过传输预写式日志(wal)的方式,日志优先写入到磁盘,如SSTables 和 LSM 树实现的引擎,所以日志都是包含所有数据库写入的仅追加字节序列,可以使用完全相同的日志在另一个节点上构建副本,将日志写入磁盘同时,主库可以通过网络将其发送给其它从节点,如etcd状态机同步;还有的方式是通过集群内部的进程直接发送需要同步的数据,如rabbitmq镜像队列。下图就是一个数据复制的应用场景:一个用户有写入操作更新到写库,然后其他用户可能从从库中读取数据,可能数据是最新的,也可能出现从库由于延时不是最新的,复制系统针对这种场景化分为了几种复制方式。9c9396f9f7732749e87f431d6f411466.png示例数据图复制系统的一个重要细节是:复制是同步(synchronously)还是异步(asynchronousl)关于复制方式:同步复制(synchronous):同步复制就是当有数据更新请求到 master 节点,需要保证该更新操作在 slave 节点上执行成功后才返回客户端,从库保证有与主库完全一致的最新数据副本。如果主库突然失效,我们可以确信这些数据仍能在从库上找到,但是该方式也有缺点,如果从库没有响应(比如它已经崩溃,或者出现网络故障,或其它任何原因),主库就无法处理写入操作,主库必须阻止所有写入,并等待同步副本再次可用,这个过程数据库是无法更新插入数据。异步复制(asynchronous):异步复制就是当有更新数据请求到 master 节点,master 操作结束直接返回客户端,不需要 slave 确认,slave 后台从 master 更新数据。该方式的缺点是,如果主库失效且不可恢复,则任何尚未复制给从库的写入都会丢失,这意味着即使已经向客户端确认成功,写入也不能保证持久(Durable)。该方式的优点是:即使所有的从库都落后了,主库也可以继续处理写入操作,服务继续运行。半同步复制(semi-synchronous):半同步复制是一种中间策略,当有更新数据请求到 master 节点,需要保证该操作在某个 slave 上也执行成功才最终返回客户端,如果某个同步的 slave 变得缓慢,则可以使一个异步 slave 变为同步,这样在保证一定数据一致性的前提下也能保证可靠性(这里可能会导致数据不一致,还可能产生数据延时)。mysql的半同步复制(mysql semi-synchronous):master在执行完更新操作后立即向 slave 复制数据,slave 接收到数据并写到 relay log (无需执行)后才向 master 返回成功信息,master 必须在接受到 slave 的成功信息后再向客户端返回响应,仅在数据复制发生异常(slave 节点不可用或者数据复制所用网络发生异常)的情况下,master 才会暂停(mysql 默认约 10 秒左右) 对客户端的响应,将复制方式降级为异步复制。当数据复制恢复正常,复制方式将恢复为半同步复制。mysql 的数据同步和 failovermysql 支持相对严格的 ACID,是一个性能和稳定性都非常不错的关系型数据库,但是对分布式支持不是很友好,虽然它实现了NDB,不过感觉使用不太广泛,国内使用较多的还是基础的主从复制方式。mysql支持前面提到的各种数据复制方式,所以只需要针对各种的场景选取对应的复制方式即可。像对可用性要求较高,数据一致性要求较低的可以选取异步复制;对数据一致性要求很高的场景,金融场景可以选用强同步复制;互联网场景对可用性和一致性可能都有一定要求,但要求不是特别高,可以选择半同步复制。下面简述 mysql 主从同步的逻辑mysql的主从同步逻辑:首先开启mysql master上的 binlog, mysql slave上通过一个 I/O 线程从  mysql master上读取binlog,然后传输到 mysql slave 的中继日志中,接着mysql slave 的 sql  线程从中继日志中读取中继日志,应用到mysql slave的 数据库中,这样就实现了主从数据同步功能。5efc690119e47d9abfa53b8bbfaf8407.pngmysql主从同步逻辑

不过 mysql 自身没有实现 failover,所以当 master 异常的时候,需要制定策略去实现 failover 并处理数据库切换。failover 的逻辑是当 master 异常,slave 自动提升为主库的,然后让其他从库知道新的 master,并继续从新的 master同步数据。在这里我们就要用到 mha了,一个mysql 高可用管理工具。mha 能做到在 0~30 秒之内自动完成数据库的故障切换操作,并且在进行故障切换的过程中,能在最大程度上保证数据的一致性,以达到真正意义上的高可用。关于 mha 的各种细节我这里就不详细展开了,这些内容都在官方wike中(文档真的非常详细,作者考虑很多通用的场景,很多参数可配置化)。

链接:mha安装mha优势mha架构mha配置等等等....这里只分析他实现 failover 的架构与原理,结构如下(官网的图片,略模糊)5f176cfa831c37507048d8f36b583f66.pngmha架构图mha 由两部分组成:mha manager(管理节点):   单独部署在一台独立的机器上管理多个 master-slave 集群(最好和mysql相关服务器管理),也可以部署在一台 slave 节点上,作用是多mysql server服务的管理,master检测,master选举,连接检查,master故障切换等工作。mha node(数据节点):   运行在每台 mysql 服务器上,作用是拷贝 master 二进制日志;然后拥有最新数据的slave上生成差异中继日志,应用差异日志;最后在不停止SQL线程的情况下删除中继日志。原理:(1)从宕机崩溃的master保存二进制日志事件(binlog events);   (2)识别含有最新更新的slave;  (3)应用差异的中继日志(relay log)到其他的slave;  (4)应用从master保存的二进制日志事件(binlog events);  (5)使其他的slave连接新的master进行复制; (6)使其他的slave连接新的master进行复制;mha需要解决的问题:如何确定新的master:由于 mysql 没有像 elasticsearch, etcd 这样分布式的集群决策节点,所以这里的 master 选举节点就是 mha manager节点,mha 主要参考几个因素:1 配置文件中手动配置的候选servers参数 **candidate_master=1**(如: 希望同机房,或则同机架的机器优先为 master), 2 依据各个 slave 中最新的二进制文件,最新的slave节点即可提升为master。82290a1a4c1b7e422b1c56efceaa1509.png选取新的master

如何保证数据一致性:

mha 最大程度的保证数据不丢失,当 mysql master 异常时,但是机器正常提供服务,那么 mha 会去对比 master 节点与将成为 master 节点的 slave 节点的数据差,然后将差值数据拷贝到新的 slave,然后应用这部分数据差去补全数据。301a2d161f54072ea17d319ac9140c84.pngdiff master如果是  mysql  master 异常,机器也异常,那么系统中保存的二进制 binlog 文件也无法访问,这就没法拷贝,那么会略过拷贝流程,直接会从 salve 候选者中选取新的 master。如果使用 mysql 5.5 的半同步复制,可以大大降低数据丢失的风险。95c6c1d8f0ed0bf876afcfc01a8d6991.png拷贝bin-log

节点之间数据如何拷贝:

由于 mysql 内部没有做这样的 bin-log 拷贝功能,所以我们有自定义的需求去实现复制。这里 mha 需要依赖 ssh 协议,就是通过 scp 协议传输文件(搭建 mha 需要保证各个主机间可以 ssh 互通)。292fd355d842e36c5a7c144e2f69c355.png拷贝bin-log

其他 slave 节点如何知道新的 master:

当候选 master 提升为 master 后,mha manager 会用 mysql change replication 的方式更改目前集群的所有 slave的同步源。70349a91a244aa23652b283f17ae06cc.pngslave更新master管理节点如何解决网络分区问题:在上边的网络结构中,我们可以猜到系统可能存在一个很大问题,就是网络分区。网络分区指的是由于网络分离造成系统分裂为两个集群,各自相互不信任。对应无状态的系统,几乎没有影响,正常处理请求,比如nginx;数据系统出现分区问题时,如果系统设计或者配置存在不合理就会导致数据不一致,而这个问题修复起来会非常复杂,所以 elasticsearch , etcd, mongdb 等天生支持分布式的数据系统中,都有机制避免由于网络分区导致的数据不一致问题,解决方式是让集群大多数能正常通信的节点正常服务。比如你的集群是有 5 个节点,分区导致一个分区 2 个节点,一个分区 3 个,那么 2 个节点的分区就会被认为是异常的,不能正常提供服务,这里也会有一些特定的算法可以解决类似的问题,如raft。比如下边这个图,3个节点,那么最少信任集群的节点数应该有2个,所以C节点会被标记为异常,不会正常提供服务32216a43f99493c43af8c05055bd0960.pngmha 的网络分区和上边提到的有点不同,由于集群只有一个 mha management(注意这里只能部署一个management,不允许部署多个,否则会出现异常),所以 mha management 不存在脑裂问题,这里指的网络分区指的 mha management 节点与 mysql master 节点出现分区,如下:b4832011716e89701ed2cb9d4441341c.pngmha management与mysql master发生网络分区当 mha management   和 mysql  master 出现在两个分区,mha 认为 mysql master 异常,但是实际 mysql master 和 mysql slave都正常工作,提供服务,但是这时候  mha  还是会切换 master,可能对应用程序来说(如果前端有负载均衡器),会出现2个master,而导致数据不一致。面对这种情况,mha 提供了一种二次检测的方式,既多条链路检测,1 条链路是 mha management 是通过直接检测 mysql master节点, 2 其他链路是 mha managerment 通过ssh登录到其他 slave 的方式去检测 mysql master 是否正常,这样就能够解决 mha managerment 和 mysql master 的网络分区问题,防止误切换。客户端应用自动恢复一般来说自带 failover 的分布式系统系统都能够自己恢复服务,像elasticsearch , etcd, 他们客户端和集群都能够自动感知集群节点的变化,客户端连接的是一组集群地址,看下边示例,像 etcd 连接的服务端地址 Endpoints []string 是个数组,这就保证了当某个节点 ip 失效,或者机器不能访问,机器异常,机器负载的情况加, 都有其他节点进行处理,etcd连接如下:

cfg := client.Config { Endpoints: []string{"http://127.0.0.1:2379"}, Transport: client.DefaultTransport, // set timeout per request to fail fast when the target endpoint is unavailable HeaderTimeoutPerRequest: time.Second, }然而像 mysql 默认的连接方式,应用 tomcat 或其他 client 连接数据库的默认的方式是mysql 驱动,就没法连接一个数组。所以我们的解决方案是要减少客户端感知,减少逻辑变更,让客户端和原来一样只需要连接一个 ip就好,这里的 ip是 proxy ip, 这里会有多种方式(这里不考虑分片和其他高级的路由,只考虑对应用连接,proxy的高可用方式可以通过keepalived来配合做互备)

  • 七层支持mysql协议的proxy:
    • mycat
    • kingshard
    • Atlas
    • vitess
    • phxsql
    • MaxScale
通过代理的方式对客户端体验最好,原理上是 proxy 解析了mysql协议,然后根据不同的库,表,请求类型路由(读写分离)到后端合适的 mysql 服务器,但是因为加了这样一个 7 层的proxy解析, 所以性能会损失,一般在 20% 左右,上边的各个 proxy 会有各自的优势,和功能,详情可以去看看相关对比,我们需要做的就是在 proxy 后端配置我们的服务应用组,配置读写分离,当 master异常,能够切换。
  • 4层proxy
    • lvs
    • haproxy
4层 proxy 就不会解析出 mysql 7层 协议,只能解析4层,所以保证 mysql 后端端口通就可以了,就是检测到后端master 不可用的时候,切换到 backup master,由于是 4层协议 所以不能配置自动读写分离,只能单独配置 master 端口,slave 端口了(如果配置keepalived可以自定义有脚本可以进行切换,自定义脚本可以配置主从同步延时)
  • 直接使用vip
    • 脚本配置vip
    • keepalived配置vip
最后这个方式逻辑就是:手动配置vip: 在 master 机器上配置虚拟vip,当mysql master异常,mha management 通过配置的 master_ip_online_change_script 的脚本,当  master 异常的时候,利用该脚本在新的 slave 上启动新的 ip,这样对客户端来说也是无影响的,配置vip比较容易关于配置流程[配置流程](https://www.cnblogs.com/gomysql/p/3675429.html),这里说的很清楚了,我就不详细解析了。我们生产环境实际上是使用maxscale,利用它来进行读写分离,他的文档特别全面,我们选用他的原因是他稳定高效,能无缝配合 mha,不需要 mha 配置任何 ip 切换之类的逻辑,当 mha 进行切换后,maxscale 会自动的进行感知系统中 servres 的角色,master切换它能感知到,对应用是完全无影响,如下图:09ffb46d8b688f6b2d27dfef722f9575.png自动识别roke总结:这里解决的是 mysql 原官方社区版的高可用问题,利用 mha + maxscale 的方式,该方案能以最小的代价对现有系统进行变更,提高系统的可用性和稳定性。前面提到以前版本(5.7以前) mysql 对集群化支持相对较弱,但是其实 mysql 也一直在发展,社区也开发出了很多方案,像PhxSQL,Percona XtraDB Cluster,MariaDB Galera Cluster,mysql 官方也开发出了使用 MySQL Group Replication的GA,来使用分布式协议来解决数据一致性问题了,非常期待未来越来越多的解决方案被提出,来更好的解决mysql高可用问题。作者:张志远,百度 · 高级工程师,sre 分布式系统,数据库原文:https://zhuanlan.zhihu.com/p/64383402

--end--

K8S培训推荐

Kubernetes线下实战培训,采用3+1+1新的培训模式(3天线下实战培训,1年内可免费再次参加,每期前10名报名,可免费参加价值3600元的线上直播班;),资深一线讲师,实操环境实践,现场答疑互动,培训内容覆盖:Kubernetes集群搭建、Kubernetes设计、Pod、常用对象操作,Kuberentes调度系统、QoS、Helm、网络、存储、CI/CD、日志监控等。点击查看更多课程信息!成都:8月16-18日

369a4312a168163542b1b52b6869a08a.gif

4402c5b21808c2ec7a81354ab2631934.png

推荐阅读

  • 人均年薪80万以上,Docker 入坑不亏?

  • 超炫酷的Docker终端UI,想看哪里点哪里

  • 使用 kubeadm 安装最新 Kubernetes 1.15 版本

  • 2019年已过半,精选往期 Kubernetes 干货文章

  • 50个你必须了解的Kubernetes面试问题

  • Promethues监控从VM迁移K8S实录

  • 避坑:Kubernetes中pull私有镜像

  • 一份非常完整、详细的MySQL规范

  • Docker stop或者Docker kill为何不能停止容器

  • Docker中Image、Container与Volume的迁

  • 国内拉取google Kubernetes镜像




推荐阅读
  • 篇首语:本文由编程笔记#小编为大家整理,主要介绍了软件测试知识点之数据库压力测试方法小结相关的知识,希望对你有一定的参考价值。 ... [详细]
  • 目录Atlas介绍Atlas部署Atlas基本管理Atlas结合MHA故障恢复读写分离建议Atlas介绍Atlas是由Qihoo360Web平台部基础架构团队开发维护的一个基于My ... [详细]
  • 基于PgpoolII的PostgreSQL集群安装与配置教程
    本文介绍了基于PgpoolII的PostgreSQL集群的安装与配置教程。Pgpool-II是一个位于PostgreSQL服务器和PostgreSQL数据库客户端之间的中间件,提供了连接池、复制、负载均衡、缓存、看门狗、限制链接等功能,可以用于搭建高可用的PostgreSQL集群。文章详细介绍了通过yum安装Pgpool-II的步骤,并提供了相关的官方参考地址。 ... [详细]
  • 本文介绍了Python高级网络编程及TCP/IP协议簇的OSI七层模型。首先简单介绍了七层模型的各层及其封装解封装过程。然后讨论了程序开发中涉及到的网络通信内容,主要包括TCP协议、UDP协议和IPV4协议。最后还介绍了socket编程、聊天socket实现、远程执行命令、上传文件、socketserver及其源码分析等相关内容。 ... [详细]
  • 关于我们EMQ是一家全球领先的开源物联网基础设施软件供应商,服务新产业周期的IoT&5G、边缘计算与云计算市场,交付全球领先的开源物联网消息服务器和流处理数据 ... [详细]
  • ubuntu用sqoop将数据从hive导入mysql时,命令: ... [详细]
  • Oracle优化新常态的五大禁止及其性能隐患
    本文介绍了Oracle优化新常态中的五大禁止措施,包括禁止外键、禁止视图、禁止触发器、禁止存储过程和禁止JOB,并分析了这些禁止措施可能带来的性能隐患。文章还讨论了这些禁止措施在C/S架构和B/S架构中的不同应用情况,并提出了解决方案。 ... [详细]
  • 本文详细介绍了git常用命令及其操作方法,包括查看、添加、提交、删除、找回等操作,以及如何重置修改文件、抛弃工作区修改、将工作文件提交到本地暂存区、从版本库中删除文件等。同时还介绍了如何从暂存区恢复到工作文件、恢复最近一次提交过的状态,以及如何合并多个操作等。 ... [详细]
  • MySQL数据库锁机制及其应用(数据库锁的概念)
    本文介绍了MySQL数据库锁机制及其应用。数据库锁是计算机协调多个进程或线程并发访问某一资源的机制,在数据库中,数据是一种供许多用户共享的资源,如何保证数据并发访问的一致性和有效性是数据库必须解决的问题。MySQL的锁机制相对简单,不同的存储引擎支持不同的锁机制,主要包括表级锁、行级锁和页面锁。本文详细介绍了MySQL表级锁的锁模式和特点,以及行级锁和页面锁的特点和应用场景。同时还讨论了锁冲突对数据库并发访问性能的影响。 ... [详细]
  • 云原生应用最佳开发实践之十二原则(12factor)
    目录简介一、基准代码二、依赖三、配置四、后端配置五、构建、发布、运行六、进程七、端口绑定八、并发九、易处理十、开发与线上环境等价十一、日志十二、进程管理当 ... [详细]
  • Nginx Buffer 机制引发的下载故障
    Nginx ... [详细]
  • ZooKeeper 学习
    前言相信大家对ZooKeeper应该不算陌生。但是你真的了解ZooKeeper是个什么东西吗?如果别人面试官让你给他讲讲ZooKeeper是个什么东西, ... [详细]
  • php网站设计实验报告,php网站开发实训报告
    本文目录一览:1、php动态网站设计的关键技术有哪些软件,及搭建步骤需要哪些页面,分别完成 ... [详细]
  • Nginxgaodaima.comnginx属于七层架构,支持的是http协议,本身对tcp协议没有支持。所以不能代理mysql等实现负载均衡。但是lvs这个东西不熟悉,主要是公司 ... [详细]
  • 什么是网关服务器初学linux服务器开发时,我们的服务器是很简单的,只需要一个程序完成与客户端的连接,接收客户端数据,数据处理,向客户端发送数据。但是在处理量很大的情况下,一 ... [详细]
author-avatar
知知亦不知_710
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有