docker部署mysql8主从集群(互为主从),keepalived保证高可用

news2024/11/25 16:47:33

一、准备2台物理机器master-1、master-2,目标虚拟VIP。
  VIP:172.50.2.139
  master-1:172.50.2.41
  master-2:172.50.2.42

二、然后分别在2台物理机器master-1、master-2上使用docker-compose安装mysql8,并配置互为主从。
1)配置master-1

cd /
mkdir docker
cd /docker
mkdir mysql8
cd mysql8
mkdir mysql8data
# master_1_init.sql见文件[master-1]
touch master_1_init.sql
# Dockerfile_master_1见文件[master-1]
touch Dockerfile_master_1
# docker-compose.yml见文件[master-1]
touch docker-compose.yml

[master-1]文件 master_1_init.sql

CREATE USER 'repl'@'%' IDENTIFIED WITH caching_sha2_password BY 'repl';
grant replication slave, replication client on *.* to 'repl'@'%';
flush privileges;

[master-1]文件 Dockerfile_master_1

FROM mysql:8.0.31
MAINTAINER "yh<573968217@qq.com>"
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
COPY ./master_1_init.sql /docker-entrypoint-initdb.d

[master-1]文件 docker-compose.yml

version: "3.9"
services:
  mysql8-master-1:
    build:
      context: ./
      dockerfile: ./Dockerfile_master_1
    image: mysql8-master-1
    restart: always
    container_name: mysql8-master-1
    volumes:
      - /docker/mysql8/mysql8data/conf/my.cnf:/etc/mysql/my.cnf
      - /docker/mysql8/mysql8data/data:/var/lib/mysql
      - /docker/mysql8/mysql8data/logs:/var/log/mysql
    ports:
      - 3306:3306
    environment:
      - MYSQL_ROOT_PASSWORD=123456
      - MYSQL_ROOT_HOST=%
    privileged: true
    network_mode: "host"
    extra_hosts:
       # master_1容器可以使用的host访问master_2
      - mysql8-master-2:172.50.2.42
    command: ['--server-id=1',
              '--default-authentication-plugin=mysql_native_password',
              '--sync_binlog=1',
              '--log-bin=mysql8-master-1-bin',
              '--binlog-ignore-db=mysql,information_schema,performance_schema,sys',
              '--binlog_cache_size=256M',
              '--binlog_format=ROW',
              '--relay_log=mysql8-master-1-relay',
              '--lower_case_table_names=1',
              '--character-set-server=utf8mb4',
              '--collation-server=utf8mb4_general_ci',
              '--sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION']

如果是只有一台机子模拟集群(就需要自建网络)

version: "3.9"
services:
  mysql8-master-1:
    build:
      context: ./
      dockerfile: ./Dockerfile_master_1
    image: mysql8-master-1
    restart: always
    container_name: mysql8-master-1
    volumes:
      - /yhcloud/docker_compose_keep_alive_mysql8_both_master/mysql8data/conf/my.cnf:/etc/mysql/my.cnf
      - /yhcloud/docker_compose_keep_alive_mysql8_both_master/mysql8data/data:/var/lib/mysql
      - /yhcloud/docker_compose_keep_alive_mysql8_both_master/mysql8data/logs:/var/log/mysql
    ports:
      - 3308:3306
    networks:
      proxy:
        ipv4_address: 172.50.2.42
    environment:
      - MYSQL_ROOT_PASSWORD=123456
      - MYSQL_ROOT_HOST=%
    privileged: true
    extra_hosts:
       # master_1容器可以使用的host访问master_2
      - mysql8-master-2:169.17.0.11
    command: ['--server-id=1',
              '--default-authentication-plugin=mysql_native_password',
              '--sync_binlog=1',
              '--log-bin=mysql8-master-1-bin',
              '--binlog-ignore-db=mysql,information_schema,performance_schema,sys',
              '--binlog_cache_size=256M',
              '--binlog_format=ROW',
              '--relay_log=mysql8-master-1-relay',
              '--lower_case_table_names=1',
              '--character-set-server=utf8mb4',
              '--collation-server=utf8mb4_general_ci',
              '--sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION']

networks:
  proxy:
    ipam:
      config:
      - subnet: 172.50.0.0/24  #启动容器的网段 

2)配置master-2

cd /
mkdir docker
cd /docker
mkdir mysql8
cd mysql8
mkdir mysql8data
# master_2_init.sql见文件[master-2]
touch master_2_init.sql
# Dockerfile_master_2见文件[master-2]
touch Dockerfile_master_2
# docker-compose.yml见文件[master-2]
touch docker-compose.yml

[master-2]文件 master_2_init.sql

CREATE USER 'repl'@'%' IDENTIFIED WITH caching_sha2_password BY 'repl';
grant replication slave, replication client on *.* to 'repl'@'%';
flush privileges;

[master-2]文件 Dockerfile_master_2

FROM mysql:8.0.31
MAINTAINER "yh<573968217@qq.com>"
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
COPY ./master_2_init.sql /docker-entrypoint-initdb.d

[master-2]文件 docker-compose.yml

version: "3.9"
services:
  mysql8-master-2:
    build:
      context: ./
      dockerfile: ./Dockerfile_master_2
    image: mysql8-master-2
    restart: always
    container_name: mysql8-master-2
    volumes:
      - /docker/mysql8/mysql8data/conf/my.cnf:/etc/mysql/my.cnf
      - /docker/mysql8/mysql8data/data:/var/lib/mysql
      - /docker/mysql8/mysql8data/logs:/var/log/mysql
    ports:
      - 3306:3306
    environment:
      - MYSQL_ROOT_PASSWORD=123456
      - MYSQL_ROOT_HOST=%
    privileged: true
    network_mode: "host"
    extra_hosts:
       # master_1容器可以使用的host访问master_2
      - mysql8-master-1:172.50.2.41
    command: ['--server-id=2',
              '--default-authentication-plugin=mysql_native_password',
              '--sync_binlog=1',
              '--log-bin=mysql8-master-2-bin',
              '--binlog-ignore-db=mysql,information_schema,performance_schema,sys',
              '--binlog_cache_size=256M',
              '--binlog_format=ROW',
              '--relay_log=mysql8-master-2-relay',
              '--lower_case_table_names=1',
              '--character-set-server=utf8mb4',
              '--collation-server=utf8mb4_general_ci',
              '--sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION']

3)启动master-1、master-2数据库服务

[master-1] [master-2]分别执行:

# mysql8真正启动需要一些时间,navicat链接成功说明启动成功
docker-compose up -d

注意:如果是服务器,或者虚拟机,要打开3306端口

# 查看防火墙
systemctl status firewalld

# 查看3306端口是否打开【no/yes】
firewall-cmd --zone=public --query-port=3306/tcp

# 打开3306端口
firewall-cmd --zone=public --add-port=3306/tcp --permanent 

# 防火墙重载
firewall-cmd --reload

# 再次查看3306状态 【yes】
firewall-cmd --zone=public --query-port=3306/tcp

连接navicat

4)启动master-1、master-2互为主从

①查看[master-1]作为主节点 的bin-log-file、bin-log-pos:

show master status

 配置及其查看[master-1]作为从节点的slave并启动(需要获取master-2主节点的日志)
注意:master_log_file、master_log_pos为你自己的数据库实际值

change master to master_host='172.50.2.42', master_user='repl',master_password='repl',master_port=3306,GET_MASTER_PUBLIC_KEY=1,master_log_file='mysql8-master-2-bin.000003', master_log_pos= 157, master_connect_retry=60;
start slave;
show slave status;

在这里插入图片描述

 ②查看[master-2] 作为主节点 的bin-log-file、bin-log-pos:

show master status

配置及其查看[master-2]作为从节点的slave并启动(需要获取master-1主节点的日志)
(注意:master_log_file、master_log_pos为你自己的数据库实际值): 

change master to master_host='172.50.2.41', master_user='repl',master_password='repl',master_port=3306,GET_MASTER_PUBLIC_KEY=1,master_log_file='mysql8-master-1-bin.000003', master_log_pos= 157, master_connect_retry=60;
start slave;
show slave status;

三、验证
1)[master-1]执行操作:

#创建一个测试库db_test
create database db_test;
#使用db_test
USE db_test;
#创建一张测试表tb_user
create table tb_user (id int,name varchar(20));
#插入一条数据
insert into tb_user(id,name) values (1, 'tomcat');
#查看数据
select * from tb_user;

2)[master-2]执行操作:

#使用db_test
USE db_test;
#查看数据
select * from tb_user;

四、keep-alive 配置VIP

另一篇文章

https://blog.51cto.com/u_15906694/6274799
1)master-1、master-2安装依赖包\

yum install -y curl gcc openssl-devel libnl3-devel net-snmp-devel

2)master-1、master-2 使用yum安装keepalived

yum install -y keepalived

3)master-1配置keepalived.conf
(MASTER或BACKUP,MASTER会抢占VIP),
本次原则master-1提供服务,master-1宕机VIP漂移到master-2继续服务

cd /etc/keepalived/
#备份原始的
mv keepalived.conf keepalived.conf.bak
#编辑新的,keepalived.conf见文件
vim keepalived.conf

keepalived.conf文件:

global_defs {
    router_id MySQL-Master-1
}

vrrp_instance MAIN {
    state MASTER
    interface ens33
    virtual_router_id 1
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass hsj
    }
    virtual_ipaddress {
        172.50.2.139
    }
}

#配置virtual_server  ip为上面配置的虚拟vip地址  端口为mysql的端口
virtual_server 172.50.2.139 3306 {
    delay_loop 6
    lb_algo rr
    lb_kind NAT
    persistence_timeout 50
    protocol TCP
    #real_server 该配置为实际物理机ip地址 以及实际物理机mysql端口
    real_server 172.50.2.41 3306 {
        #当该ip 端口连接异常时,执行该脚本
        notify_down /etc/keepalived/shutdown.sh
        TCP_CHECK {
            #实际物理机ip地址
            connect_ip 172.50.2.41
            #实际物理机port端口
            connect_port 3306
            connect_timeout 3
            nb_get_retry 3
            delay_before_retry 3
        }
    }
}

4)master-2配置keepalived.conf

cd /etc/keepalived/
#备份原始的
mv keepalived.conf keepalived.conf.bak
#编辑新的,keepalived.conf见文件
vim keepalived.conf

keepalived.conf文件:

global_defs {
    router_id MySQL-Master-2
}

vrrp_instance MAIN {
    state BACKUP
    # 输入ifconfig查看网卡地址
    interface ens33
    virtual_router_id 1
    priority 90
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass hsj
    }
    virtual_ipaddress {
        172.50.2.139
    }
}

#配置virtual_server  ip为上面配置的虚拟vip地址  端口为mysql的端口
virtual_server 172.50.2.139 3306 {
    delay_loop 6
    lb_algo rr
    lb_kind NAT
    persistence_timeout 50
    protocol TCP
    #real_server 该配置为实际物理机ip地址 以及实际物理机mysql端口
    real_server 172.50.2.42 3306 {
        #当该ip 端口连接异常时,执行该脚本
        notify_down /etc/keepalived/shutdown.sh
        TCP_CHECK {
            #实际物理机ip地址
            connect_ip 172.50.2.42
            #实际物理机port端口
            connect_port 3306
            connect_timeout 3
            nb_get_retry 3
            delay_before_retry 3
        }
    }
}

shutdown.sh文件

#!/bin/bash
#该脚本是在mysql服务出现异常时,将keepalived应用停止,从而使虚拟vip主机自动连接到另一台mysql上
killall keepalived

注意:如果有firewall 防火墙,放行VRRP协议 (用于keepalived搭建高可用规则)

firewall-cmd --direct --permanent --add-rule ipv4 filter INPUT 0 --in-interface enp4s0 --destination 224.0.0.18 --protocol vrrp -j ACCEPT

firewall-cmd --reload

PS:其实上面那命令并没有卵用,目前现象就是如果两边防火墙都关闭后:主节点keepalive的手动杀死后,从节点会晋升。此时把主节点重启,vip有会飘逸会主节点。跟我想要的效果不一样。我想要得是就算主节点down了重启后,vip还是在从节点上,从节点down机后,vip再自动漂移到主节点。事实上,加了防火墙后,从节点启动的时候会因为接收不到主节点的广播,会抢占vip。所以就造成VIP在从节点上,同时两台机子上的keepalive都是master。此时就算从节点宕机,vip也不会飘移了。因为主节点那台机子觉得自己还是master就不会去抢占。就会导致虚拟vip访问不起,mysql服务业访问不起。后面有空再解决,先记录下来!!!

5)master-1、master-2同时启动keepalived服务

systemctl start keepalived

systemctl start keepalived 启动keepalived服务
systemctl stop keepalived 停止keepalived服务
systemctl enable keepalived 设置keepalived服务开机自启动
systemctl disable keepalived 禁止keepalived服务开机自启动

6)测试master-1宕机ip漂移
关闭master-1宿主机实例,模拟master-1宕机。
通过VIP:192.168.1.139 链接数据库操作任然正常,进行操作insert:

insert into tb_user(id,name) values (9, '听妈妈的话');

8)测试master-2宕机ip漂移
关闭master-2宿主机实例,模拟master-2宕机。
通过VIP:192.168.1.139 链接数据库操作任然正常,进行操作insert:

insert into tb_user(id,name) values (10, '听爸爸的话');

结语:
​ 1、当sync_binlog=0的时候,表示每次提交事务都只write,不fsync
​ 2、当sync_binlog=1的时候,表示每次提交事务都执行fsync
​ 3、当sync_binlog=N的时候,表示每次提交事务都write,但积累N个事务后才fsync。

​ 一般在公司的大部分应用场景中,我们建议将此参数的值设置为1,因为这样的话能够保证数据的安全性,但是如果出现主从复制的延迟问题,可以考虑将此值设置为100~1000中的某个数值,非常不建议设置为0,因为设置为0的时候没有办法控制丢失日志的数据量,但是如果是对安全性要求比较高的业务系统,这个参数产生的意义就不是那么大了。

-- 查看并行的slave的线程的个数,默认是0.表示单线程
show global variables like 'slave_parallel_workers';
-- 根据实际情况保证开启多少线程
set global slave_parallel_workers = 4;
-- 设置并发复制的方式,默认是一个线程处理一个库,值为database
show global variables like '%slave_parallel_type%';
-- 停止slave
stop slave;
-- 设置属性值
set global slave_parallel_type='logical_check';
-- 开启slave
start slave
-- 查看线程数
show full processlist;

阿里云部署需要:havip + 弹性公网

高可用虚拟IP(High-Availability Virtual IP Address,简称HaVip)HaVip功能正在公测,您可以登录阿里云配额中心控制台进行自助申请。
—2023-01-12

HaVip具有以下特点:
1、HaVip是1个浮动的私网IP,不会固定在指定的ECS实例或弹性网卡上。ECS实例或弹性网卡可通过ARP协议宣告来更改与HaVip的绑定关系。
2、HaVip具有子网属性,仅支持绑定到同一交换机下的ECS实例或弹性网卡上。
3、1个HaVip支持同时绑定10个ECS实例或同时绑定10个弹性网卡,但1个HaVip不能既绑定ECS实例又绑定弹性网卡。

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

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

相关文章

2023-7-19-第二十式迭代器模式

&#x1f37f;*★,*:.☆(&#xffe3;▽&#xffe3;)/$:*.★* &#x1f37f; &#x1f4a5;&#x1f4a5;&#x1f4a5;欢迎来到&#x1f91e;汤姆&#x1f91e;的csdn博文&#x1f4a5;&#x1f4a5;&#x1f4a5; &#x1f49f;&#x1f49f;喜欢的朋友可以关注一下&#xf…

深入理解Java虚拟机(五)虚拟机类加载机制

代码编译的结果从本地机器码转变为字节码&#xff0c;是存储格式发展的一小步&#xff0c;却是编程语言发展的一大步。 一、概述 Java虚拟机把描述类的数据从Class文件加载到内存&#xff0c;并对数据进行校验、转换解析和初始化&#xff0c;最终形成可以被虚拟机直接使用的Jav…

队列的表示和操作

队列&#xff1a;队列是仅在表尾进行插入操作&#xff0c;在表头进行删除操作的线性表。 表尾即an端&#xff0c;称为队尾&#xff0c;表头即a1端&#xff0c;称为队头。 队列的存储方式&#xff1a;顺序队列和链式队列 队列顺序表示 #define MAXQSIZE 100 //最大队列长度 …

Vue 1 - 安装、快速上手

文章目录 关于 Vue创建应用 关于 Vue 官网&#xff1a; https://cn.vuejs.org官方文档-快速上手&#xff1a; https://cn.vuejs.org/guide/quick-start.htmlgithub : https://github.com/vuejsVue SFC Playground : https://play.vuejs.org/ 其他 作者 尤雨溪 Evan You 主页 …

如何把caj文件改成PDF格式?分享三个免费的方法!

在学术研究中&#xff0c;我们可能会遇到CAJ文件&#xff0c;这是一种在中国学术界广泛使用的文档格式。然而&#xff0c;与PDF文件相比&#xff0c;CAJ文件的查看和分享并不那么便捷。下面&#xff0c;我会为你介绍三种免费且简便的方法&#xff0c;帮助你将CAJ文件转化为PDF格…

PSP - Jackhmmer 搜索 EMBL 序列数据库的相似序列

欢迎关注我的CSDN&#xff1a;https://spike.blog.csdn.net/ 本文地址&#xff1a;https://spike.blog.csdn.net/article/details/131817060 EMBL (European Molecular Biology Laboratory&#xff0c;欧洲分子生物实验室)&#xff1a;EMBL 数据库是一个由欧洲生物信息学研究所…

Microsoft Outlook如何定时发送邮件

点击New Emai 选择Options→Delay Delivery→Do not deliver before→Close

基于linux下的高并发服务器开发(第二章)- 2.13 匿名管道通信案例

实现 ps aux | grep xxx 父子进程间通信 子进程&#xff1a; ps aux, 子进程结束后&#xff0c;将数据发送给父进程 父进程&#xff1a;获取到数据&#xff0c;过滤 pipe() execlp() 子进程将标准输出 stdout_fileno 重定向到管道的写端。 dup2 07 / 匿名管道…

java项目之班级同学录网站(ssm+mysql+jsp)

风定落花生&#xff0c;歌声逐流水&#xff0c;大家好我是风歌&#xff0c;混迹在java圈的辛苦码农。今天要和大家聊的是一款基于ssm的班级同学录网站。技术交流和部署相关看文章末尾&#xff01; 开发环境&#xff1a; 后端&#xff1a; 开发语言&#xff1a;Java 框架&a…

强化学习之DQN(deep Q-network)算法

一、简介 DQN算法是深度学习领域首次广泛应用于强化学习的算法模型之一。它于2013年由DeepMind公司的研究团队提出&#xff0c;通过将深度神经网络与经典的强化学习算法Q-learning结合&#xff0c;实现了对高维、连续状态空间的处理&#xff0c;具备了学习与规划的能力。 二、…

使用Pandas计算两个系统客户名称的相似度

引言&#xff1a; 在日常业务处理中&#xff0c;我们经常会面临将不同系统中的数据进行匹配和比对的情况。特别是在涉及到客户管理的领域&#xff0c;我们需要确保两个系统中的客户记录是准确、一致和无重复的。 本文将介绍如何使用Python的Pandas库来处理这个问题。我们将以…

Linux: cannot read file data

报错&#xff1a; Could not load library libcudnn_cnn_infer.so.8. Error: /home/qc/miniconda3/envs/DNAqc/lib/python3.10/site-packages/torch/lib/libcudnn_cnn_infer.so.8: cannot read file data Please make sure libcudnn_cnn_infer.so.8 is in your library path! A…

淘宝商品详情数据接口(APP端,H5端),监控淘宝商品历史价格及价格走势,接口代码对接

淘宝商品详情数据接口APP端&#xff0c;H5端代码如下&#xff1a; 公共参数 名称类型必须描述交流中心18179014480keyString是调用key&#xff08;必须以GET方式拼接在URL中&#xff09;注册Key和secret接入secretString是调用密钥api_nameString是API接口名称&#xff08;包括…

JMeter做http接口功能测试

1. 普通的以key-value传参的get请求 e.g. 获取用户信息 添加http请求&#xff1b;填写服务器域名或IP&#xff1b;方法选GET&#xff1b;填写路径&#xff1b;添加参数&#xff1b;运行并查看结果。 2. 以Json串传参的post请求 e.g. 获取用户余额 添加http请求&#xff1b;…

行业数据和报告到底应该如何去找?

信息时代&#xff0c;经常要对行业信息进行分析。这时首先就是要进行信息收集和筛选&#xff0c;如果我们懂得构建自己的工作工具和数据来源&#xff0c;效率会蹭蹭往上涨。 找行业报告、了解行业趋势&#xff0c;提高效率。 1. 国家权威 国家统计局&#xff1a;这个网站覆盖…

C++无锁编程——无锁队列(queue)

C无锁编程——无锁队列(queue) 贺志国 2023.7.11 上一篇博客给出了最简单的C数据结构——栈的几种无锁实现方法。队列的挑战与栈的有些不同&#xff0c;因为Push()和Pop()函数在队列中操作的不是同一个地方。因此同步的需求就不一样。需要保证对一端的修改是正确的&#xff0…

CRC校验原理全面解读

目录 1. 简介2. 原理2.1 CRC的发送与接收2.2 CRC校验码的生成2.3 CRC校验码的校验 3. 拓展问题3.1 模2除法为什么等同于异或运算&#xff1f;3.2 为什么除数的位数和被除数补充的位数相差为1&#xff1f;3.3 为什么CRC校验码不能纠正错误&#xff0c;只能检测错误&#xff1f; …

【数据结构】二叉树详解(2)

⭐️ 前言 ✨ 往期文章链接&#xff1a;二叉树的概念性质 上一篇我们讲了二叉树的结构定义&#xff0c;以及前序/中序/后序的递归遍历&#xff0c;还有一些二叉树的接口实现&#xff0c;本篇我们补充一个二叉树的接口 BinaryTreeDepth。✨上一篇文章链接&#xff1a;二叉树详…

第108天:免杀对抗-Python混淆算法反序列化打包生成器Py2exeNuitka

知识点 #知识点&#xff1a; 1、Python-对执行代码做文章 2、Python-对shellcode做文章 3、Python-对代码打包器做文章#章节点&#xff1a; 编译代码面-ShellCode-混淆 编译代码面-编辑执行器-编写 编译代码面-分离加载器-编写 程序文件面-特征码定位-修改 程序文件面-加壳花指…

SpringCloud学习路线(7)—— 统一网关Gateway

一、引言 &#xff08;一&#xff09;需求&#xff1a; 服务器中的微服务只允许内部人员调用或是内网人员进行调用&#xff0c;拒绝外网人员访问。 &#xff08;二&#xff09;如何实现需求&#xff1f; 网关 &#xff08;三&#xff09;网关的功能 身份认证和权限校验服务…