MySQL--整合Keepalived进行双机热备自动切换(升级版)

news2024/11/15 14:05:40

原文网址:MySQL--整合Keepalived进行双机热备自动切换(升级版)_IT利刃出鞘的博客-CSDN博客

简介

        本文介绍MySQL整合Keepalived进行双机热备自动切换(升级版)。

        服务器要考虑高可用问题。nginx、tomcat、缓存、队列、数据库,每个环节高可用的最基本要求是避免单点故障,能够自动failover。

我的目的:数据库主库挂了,一定要能自动切换,否则公司停摆。。。

我的要求:简单实用、可靠、主从不要轻易切、尽最大可能不脑裂、不丢事务。

网上常见的一个简单的方案是:mysql双主+Keepalived。猛一看很完美:mysql两个库可写、keepalived任意切换,像管理无状态服务一样自在……,其实这种方案有很明显的缺点:主从同步有延迟时,如果发生切换,发生数据错乱的概率太高(对于很多系统来说,宁可宕机几分钟,也不要产生大量脏数据)

如果不差钱,可以直接使用阿里云的RDB,支持容灾、备份、恢复、监控、迁移等全套解决方案。阿里云RDS基础版110元/月。

方案概述

我的方案是对mysql双主+keepalived的方案的改进:mysql主从半同步复制+keepalived+第三方程序和数据辅助切换判断

主要特点:

1、从库只读,切换为主时才可写

2、keepalived不配置virtual_ipaddress,由notify脚本实现IP漂移

3、把主从切换置于“重量级”的等级,不要轻易切换:

keepalived监控连续失败2分钟再切换(如mysqld宕机后能被mysqld_safe重启,则不切换);

切换脚本要判断很多逻辑,确保不会人为失误导致切换,也确保从库不满足切换条件时不会切换。

4、切换是单向的,从切为主后,需要重建部署主从环境

5、说到MHA,很多人会担心脑裂问题,keepalived网络环境比mha简单,在确保主从两节点在一个二层网络时,即便keepalived发生了脑裂(即双节点都有VIP),ARP广播可以确保只有一个节点的VIP是可以对外服务的,因此脑裂导致脏数据的可能性接近为零。

项目名称:mkf (mysql keepalived failover)

脚本地址:https://github.com/meishd/mkf

架构图:

方案说明

心跳表

所有的数据库有一个心跳表dbadmin.heartbeat(id,create_time),JOB每秒更新create_time,该表是我们用来监控从库同步延迟的;这里用这个表判断从库是否满足切主条件。

python数据抽取与dbfailover

dbfailover位于独立的实例,包括两张表:主库配置表master_info,切换仲裁信息表master_arbit_info

master_info自动:

  • db_name  primary key  唯一标识一套主从的数据库名称
  • ip  主IP,切换后要改之
  • port 端口
  • user_name 用户名
  • status 状态,0:启用,1:禁用
  • update_time DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,根据该字段判断是否需要reset连接池

master_arbit_info字段:

  • id auto_increment
  • db_name 数据库名称
  • semi_status 半同步状态,1:同步,0:异步
  • heartbeat_time 心跳表记录的时间
  • create_time 当前时间

python程序读取master_info表初始化每个主库的连接池,定期(10秒)检测连接池、失效重连,定期(每秒)抽取信息到master_arbit_info。

主节点控制

主连续宕机120秒(interval 10,fall 13)才切换,自动重启不切换,避免轻易切换;

主节点通过notify_backup控制VIP删除,降低运维操作的风险、避免对主库正常使用的影响

  1. 便于线上无缝实施,初始配置时不会影响现有VIP正常访问;
  2. 主节点只有notify_backup,确保切换单向,进入master无额外操作;
  3. 刚启动keepalived时主节点会先短暂进入backup状态,再进入master状态,脚本可以根据启动时间判断退出VIP删除操作;
  4. 正确的启动顺序:先启动主keepalived、再启动从keepalived,如误操作先启动从,则主keepalived进入backup状态,此时通过判断mysql端口退出VIP删除操作。

从节点控制

从节点通过notify_master控制从升为主,目的是尽最大可能确保从库不丢事务才能升为主,否则宁可不切换。

以下是必须按顺序满足的条件,否则终止操作:

  1. 主服务器3306端口不通
  2. master_arbit_info无120秒内的数据
  3. master_arbit_info有180秒内的数据
  4. master_arbit_info最后一条semi_status=1
  5. master_arbit_info最后一条heartbeat正常更新
  6. 从库回放所有relay log,如未完成,每3秒检测1次,超时时间10分钟
  7. 0<=(从库心跳 - master_arbit_info最后心跳)<=1秒

满足上述条件后,从库正式执行切换操作:

  1. 记录slave状态show slave status\G,用于主恢复后确认是否丢事务
  2. set read_only=0
  3. set event_scheduler=1
  4. ip addr add ${VIP}/24 dev ${DEV}
  5. arping -I ${DEV} -c 1 ${VIP}
  6. arping -I ${DEV} -c 1 -s ${VIP} ${GATEWAY}

从库正常切为主后的日志:

# tail -20 notify_master.log
20200318 14:42:48 notify master begin...
20200318 14:42:48 1. master is offline
20200318 14:42:48 2. master_arbit_info records within 120 seconds: 0
20200318 14:42:48 3. master_arbit_info records within 180 seconds: 52
20200318 14:42:48 4. master_arbit_info last semi status: 1
20200318 14:42:48 5. master_arbit_info last heartbeat_time after create_time: 0
20200318 14:42:48 6. slave exec log lag behind read log: 0
20200318 14:42:48 7. heartbeat lag between master and slave: 1
20200318 14:42:49 switch to master
Warning: Using a password on the command line interface can be insecure.
20200318 14:42:49 add vip
ARPING 10.40.12.104 from 10.40.12.104 eth1
Sent 1 probes (1 broadcast(s))
Received 0 response(s)
ARPING 10.40.12.254 from 10.40.12.104 eth1
Unicast reply from 10.40.12.254 [84:D9:31:9F:29:75] 1.416ms
Sent 1 probes (1 broadcast(s))
Received 1 response(s)
20200318 14:42:51 notify master end
# more slave_status.log.20200318_144248
Warning: Using a password on the command line interface can be insecure.
*************************** 1. row ***************************
Slave_IO_State: Reconnecting after a failed master event read
Master_Host: 10.40.12.101
Master_User: lbadmin
Master_Port: 3366
Connect_Retry: 60
Master_Log_File: mysql-bin.000004
Read_Master_Log_Pos: 74770
Relay_Log_File: relay-bin.000005
Relay_Log_Pos: 74980
Relay_Master_Log_File: mysql-bin.000004
Slave_IO_Running: Connecting
Slave_SQL_Running: Yes
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 74770
Relay_Log_Space: 137461
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Seconds_Behind_Master: NULL
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 2003
Last_IO_Error: error reconnecting to master 'lbadmin@10.40.12.101:3306' - retry-time: 60 retries: 3
Last_SQL_Errno: 0

测试用例

测试对象判断条件异常条件模拟
主库
notify_backup.sh
1.keepalived启动时间超过60秒每次新启动keepalived时会短暂进入backup状态,再进入master状态,触发异常
2.mysql端口不通主节点keepalived.conf将notify_backup误写为notify_master,启动后触发异常
从库
notify_master.sh
1.主服务器mysql端口不通先起从节点keepalive,导致从进入master状态,触发异常
2.master_arbit_info无120秒内的数据keepalived监测脚本判断时间不足120秒,如interval 10,fall 5
3.master_arbit_info有180秒内的数据python数据抽取程序挂了
4.master_arbit_info最后一条semi_status=1做大数据量的DML,或者从库stop slave一段时间后再起,确保半同步降级2分钟以上,关主库
5.master_arbit_info最后一条heartbeat正常更新主库关闭heartbeat job
6.从库回放所有日志,如未完成循环等10分钟主库DDL大表,DDL完成后关主库
7.0<=(从库心跳-master_arbit_info最后心跳)<=1不好用实际场景模拟,关主库后删除master_arbit_info表2条最新的数据

运维操作

python程序部署

  1. 创建第三方mysql库dbfailover,执行脚本install_dbfailover.sql,将需要维护的主库信息初始化至master_info
  2. 在被管理的主库执行install_dbtarget.sql
  3. 部署python数据抽取程序(可以和dbfailover同服务器):安装python3环境,requirement: PyMySQL==0.9.3 DBUtils==1.3 APScheduler==3.6.3,设置mkf.py中的dbmanager连接池信息: managerdb_pool = PooledDB(host='dbmanater_ip',user='user1',passwd='password1')
  4. 启动脚本: python mkf.py

主从库环境部署

主从服务器上安装部署keepalived
主节点配置文件:keepalived_master.conf,脚本文件:notify_backup.sh
从节点配置文件:keepalived_slave.conf,脚本文件:notify_master.sh
其中keepalived_master/slave.conf修改IP信息,notify_backup/master.sh修改文件头的变量

启停keepalived顺序

启动时先起主节点keepalived,再起从节点keepalived;

如果先起从后起主,不会对线上业务有影响,但是要重启从节点的keepalived,确保主进入master状态。

failover后的操作

停止两节点的keepalived;

如果老主服务器可修复,查看Executed_Gtid_Set信息,与从节点切换为主时记录的slave status比较,确认是否有事务丢失;

如有事务丢失则解析binlog,与研发一起处理数据问题,无则搭建新的主从,调整keepalived配置;

更新master_info中的IP信息,python程序会在10秒内自动更新连接池配置。

其他网址

mysql高可用自动切换方案(半同步复制+keepalived+第三方数据逻辑判断)_sdmei的博客-CSDN博客_mysql自动切换方案

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/133329.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Java开发的古董拍卖系统竞标系统拍卖网

简介 古董展品拍卖网站 用户可以注册成为买家也可以申请开店成为卖家&#xff0c;发布古董展品&#xff0c;设置拍卖起止时间进行展品的拍卖。如果早于拍卖开始时间或者晚于拍卖结束时间&#xff0c;则不可以竞拍。多人竞拍&#xff0c;买家可以根据最高价设置谁中标&#xff…

系分 - 结构化方法【概念】

个人总结&#xff0c;仅供参考&#xff0c;欢迎加好友一起讨论 系分 - &#xff08;概念&#xff09;结构化方法 结构化方法贯穿整个软件工程全部&#xff0c;可以单独细分出来作为某个软件工程环节的技术指引 结构化方法&#xff0c;由结构化分析&#xff08;SA&#xff0c;St…

【C语言进阶】速学,不会用数据库可不能再错过文本与二进制文件操作

目录 ✨前言✨&#xff1a; &#x1f388;一、文本文件与二进制文件&#x1f388;&#xff1a; &#x1f381;二、文件读取结束的判定&#x1f381;&#xff1a; 1.错误使用 feof 函数&#xff1a; 2.判断文件读取结束&#xff1a; &#x1f38a;三、文件缓冲区&#x1f38…

Ubuntu虚拟机图文安装详细教程

Hello, 小伙伴们&#xff0c;大家好&#xff01;今天教大家一步一步进行ubuntu虚拟机的安装。俗话说的好&#xff1a;“工欲善其事必先利其器”&#xff0c;作为一名嵌入式软件开发人员&#xff0c;我们必须熟悉Linux系统的操作及使用&#xff0c;熟练掌握Linux系统下的开发&am…

java 接口的私有方法

其实java8就已经做下伏笔了 在拥有静态和默认 两种拥有方法体的方法之后 接口出现私有方法也是一种必然 然后我们来创建一个包 包下创建一个接口 subInterface 参考代码如下 public interface subInterface {private void show2() {System.out.println("我是一个私有方…

头条权重在线查询,头条号增加权重的4个妙招

头条号权重可以简单理解为头条号指数&#xff0c;刚开通头条号的时候&#xff0c;会根据头条号的领域、介绍等等给予相应的权重。后期会根据账号使用情况进行调整权重&#xff0c;提高或者降低。 头条权重在线查询方法 打开“站长工具”之后&#xff0c;输入网站网址。…

LeetCodeday04

24. 两两交换链表中的节点 给你一个链表&#xff0c;两两交换其中相邻的节点&#xff0c;并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题&#xff08;即&#xff0c;只能进行节点交换&#xff09;。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3…

JavaScript篇.day08-DOM,节点,事件,定时器,位置及坐标

目录 1.DOM 2.DOM相关操作 (1)获取元素 (2)操作元素 (3)操作元素属性 (4)操作元素类名 (5)操作元素样式 3.节点操作 4.事件 5.事件传播 6.定时器 7.位置及坐标 1.DOM Document Object Model 文档对象模型一整套操作文档流相关内容的属性和方法可以做的操作: 修改样…

前端框架搭建(六)搭建页面框架【vite】

1.安装所需依赖 需要安装 vue-routernaive视图框架 npm npm install vue-router4 yarn yarn add vue-router4npm i -D naive-ui2.搭建naive适配框架 创建文件夹——存放通用组件 在components下创建文件夹common 全局配置常用组件 在之前创建的global.d.ts中添加Window…

枚举的应用

枚举&#xff1a; 在数学和计算机科学理论中&#xff0c;一个集的枚举是列出某些有穷序列集的所有成员的程序&#xff0c;或者是一种特定类型对象的计数。这两种类型经常&#xff08;但不总是&#xff09;重叠。 [1] 是一个被命名的整型常数的集合&#xff0c;枚举在日常生活…

基于CAS操作的atomic原子类型

原子操作 C A S (compare And Swap&#xff09;也叫比较交换&#xff0c;是一种无锁原子算法&#xff0c;映射到操作系统就是一条cmpxchg硬件汇编指令&#xff08;保证原子性)&#xff0c;其作用是让CPU将内存值更新为新值&#xff0c;但是有个条件&#xff0c;内存值必须与期望…

站长权重在线查询,怎么查询网站权重是多少?

什么是网站权重 当站长们辛辛苦苦建立起来一个网站&#xff0c;怎么才能知道自己的网站在搜索引擎中的权重情况呢&#xff1f; 对于很多人而言&#xff0c;权重这个词可能听到最多的场景就是淘宝京东店铺权重。淘宝或京东会根据商家网店的浏览量、好评率、转化率、是否…

4A(统一安全管控平台)解析

4A是指帐号&#xff08;Account&#xff09;、认证&#xff08;Authentication&#xff09;、授权&#xff08;Authorization&#xff09;和审计&#xff08;Audit&#xff09;&#xff0c;4A统一安全管控平台是以身份为中心&#xff0c;实现帐号、认证、授权和审计统一管控的安…

Spark注意事项

一、Spark理解 数据的操作只有两种 大数据领域中对数据的操作只有两种:聚合 & 处理 无论是多华丽算法,最终都是这两个平平无奇的操作组合而成的 action理解 在spark中,一个action操作为一个jobId(在源码中可以看到runjob 是只有在action操作后才会调用) , 所以一个…

Mac内存空间不足导致无法安装Ventura?可用这些方法释放储存空间

安装Macos新版系统Ventura需要非常多的内存空间&#xff0c;本身我们的Mac磁盘空间就掣襟肘见&#xff0c;我们又该如何释放Mac磁盘空间来安装Ventura呢&#xff1f;今日&#xff0c;小编将分享一些能够释放大量Mac内存空间的方法&#xff0c;以便大家能够优化Mac的运行速度外还…

摄影基础笔记

https://www.icourse163.org/learn/UESTC-1001958013?tid1450439527#/learn/content 这里写目录标题景深 焦距 光圈视角快门测光 感光度构图井字曝光色温白平衡光光的强度光的方向色彩色相明度饱和度色相环反差影调手机瞬间后期处理景深 焦距 光圈 当我们把镜头对着一个景物聚…

Annoconda常见用法

打开conda命令行窗口 点击开始&#xff0c;选择A-选择Anaconda里面的prompt 查看环境 conda env list #查看虚拟环境 创建环境 conda create -n 虚拟环境名字 python3.8 #创建虚拟环境 python3.8 指定python版本 激活环境 conda activate 虚拟环境名字 #进入虚拟环境 …

Linux磁盘情况常用查看指令

Linux磁盘情况 磁盘查询 df -h&#xff1a;(disk free)查询磁盘的整体情况。 du -h&#xff1a;(disk usage)查询指定目录的磁盘占用情况&#xff0c;默认为当前目录 -s 指定目录占用大小汇总-h 带计量单位-a 含文件–max-depth1 子目录深度-c 列出明细的同时&#xff0c;增…

【LDF】线性判别函数(二)

感知准则函数 线性可分性 现有 nnn 个 样本: y1,y2,…,yn\mathbf{y}_1, \mathbf{y}_2, \ldots, \mathbf{y}_ny1​,y2​,…,yn​, 这些样本来自于两个类别 ω1\omega_1ω1​ 或 ω2\omega_2ω2​ 。任务: 寻找一个线性判别函数 g(x)aTyg(\mathbf{x})\mathbf{a}^T \mathbf{y}g(…

SpringMVC 入门案例

1.1 添加依赖 在pom文件中添加 javax.servlet-api 和 spring-webmvc 依赖&#xff1b; javax.servlet-api&#xff1a;主要用于 JAVA Web 开发&#xff1b; spring-webmvc&#xff1a;SpringMVC 依赖&#xff1b; <dependencies><dependency><groupId>javax.…