当前位置: 首页 > news >正文

Docker复杂安装--最详细的MySQL主从复制与Redis集群安装、主从复制、主从扩容主从缩容实战版

目录

一、前言

二、MySQL的主从复制

MySQL主从复制原理

主从搭建

新建主服务器容器实例3307

配置文件

修改完配置重启容器

进入容器实例内

master容器实例内创建数据同步用户并授权

新建从服务器容器实例3308

配置文件

重启容器

在主数据库中查看主从同步状态

进入mysql-slave容器

在从数据库中配置主从复制

在从数据库中查看主从同步状态

在从数据库中开启主从同步

查看从数据库状态发现已经同步

主从复制测试

三、Redis集群搭建

面试题

3主3从redis集群扩缩容配置案例架构

分别启动6台redis容器

构建主从关系

查看集群状态

查看集群节点信息

Redis集群读写出错

集群信息检查

​编辑主从扩容

启动两台新的容器节点

将6387作为master加入集群

检查当前集群状态

重新分配

分配从节点

检查集群当前状态

主从缩容

首先删除从节点6388

对6387哈希槽分走

删除节点6387

查看集群情况


一、前言

上篇文章中我们已经学习了基本的docker上的安装数据库,对于大部分的安装都是大差不差的,但是上文中我们主要针对的是单机版的数据库安装,在实际生产中我们往往需要的是多台服务器,如MySQL的主从复制和Redis的集群,在本文中我们就来看看多台服务器的安装是什么样子。

二、MySQL的主从复制

MySQL主从复制原理

MySQL主从复制原理

主从搭建

新建主服务器容器实例3307

docker run -p 3307:3306 
--name mysql-master 
--privileged=true 
-v /mydata/mysql-master/log:/var/log/mysql 
-v /mydata/mysql-master/data:/var/lib/mysql 
-v /mydata/mysql-master/conf:/etc/mysql/conf.d 
-e MYSQL_ROOT_PASSWORD=root -d mysql:5.7

配置文件

进入 /mydata/mysql-master/conf 目录下新建my.cnf

[mysqld]
## 设置server_id, 同一个局域网中需要唯一
server_id=101
## 指定不需要同步的数据库名称
binlog-ignore-db=mysql
## 开启二进制日志功能
log-bin=mall-mysql-bin
## 设置二进制日志使用内存大小(事务)
binlog_cache_size=1M
## 设置使用的二进制日志格式(mixed,statement,row)
binlog_format=mixed
## 二进制日志过期清理时间。默认值为0,表示不自动清理
expire_logs_days=7
## 跳过主从复制中遇到的所有错误或指定类型的错误,避免slave端复制中断
## 如:1062错误是指一些主键重复,1032错误是因为主从数据库数据不一致
slave_skip_errors=1062

修改完配置重启容器

docker restart mysql-master

进入容器实例内

docker exec -it mysql-master /bin/bash
mysql -uroot -proot

master容器实例内创建数据同步用户并授权

-- 创建数据同步用户
create user 'slave'@'%' identified by '123456';
-- 授权
grant replication slave, replication client on *.* to 'slave'@'%';
flush privileges;
  • 第一条命令创建了一个名为slave的用户,允许从任何IP地址(用%表示)连接到数据库,并设置密码为123456。
  • 第二条命令授予slave用户REPLICATION SLAVE和REPLICATION CLIENT权限。这些权限是进行主从复制所必需的:
    • REPLICATION SLAVE:允许用户读取主服务器的二进制日志,这是实现数据复制的基础。
    • REPLICATION CLIENT:允许用户查询主服务器的状态,例如查看二进制日志文件和位置。

新建从服务器容器实例3308

docker run -p 3308:3306 
--name mysql-slave 
--privileged=true 
-v /mydata/mysql-slave/log:/var/log/mysql 
-v /mydata/mysql-slave/data:/var/lib/mysql 
-v /mydata/mysql-slave/conf:/etc/mysql/conf.d 
-e MYSQL_ROOT_PASSWORD=root -d mysql:5.7

配置文件

进入/mydata/mysql-slave/conf目录下新建my.cnf

[mysqld]
## 设置server_id, 同一个局域网内需要唯一
server_id=102
## 指定不需要同步的数据库名称
binlog-ignore-db=mysql
## 开启二进制日志功能,以备slave作为其它数据库实例的Master时使用
log-bin=mall-mysql-slave1-bin
## 设置二进制日志使用内存大小(事务)
binlog_cache_size=1M
## 设置使用的二进制日志格式(mixed,statement,row)
binlog_format=mixed
## 二进制日志过期清理时间。默认值为0,表示不自动清理
expire_logs_days=7
## 跳过主从复制中遇到的所有错误或指定类型的错误,避免slave端复制中断
## 如:1062错误是指一些主键重复,1032是因为主从数据库数据不一致
slave_skip_errors=1062
## relay_log配置中继日志
relay_log=mall-mysql-relay-bin
## log_slave_updates表示slave将复制事件写进自己的二进制日志
log_slave_updates=1
## slave设置只读(具有super权限的用户除外)
read_only=1

重启容器

docker restart mysql-slave

在主数据库中查看主从同步状态

show master status;

进入mysql-slave容器

docker exec -it mysql-slave /bin/bash
mysql -uroot -proot

在从数据库中配置主从复制

change master to master_host='宿主机ip', master_user='slave', master_password='123456', 
master_port=3307, master_log_file='mall-mysql-bin.000001', master_log_pos=617, master_connect_retry=30;
  • master_host:主数据库的IP地址;
  • master_port:主数据库的运行端口;
  • master_user:在主数据库创建的用于同步数据的用户账号;
  • master_password:在主数据库创建的用于同步数据的用户密码;
  • master_log_file:指定从数据库要复制数据的日志文件,通过查看主数据的状态,获取File参数;
  • master_log_pos:指定从数据库从哪个位置开始复制数据,通过查看主数据的状态,获取Position参数;
  • master_connect_retry:连接失败重试的时间间隔,单位为秒。

在从数据库中查看主从同步状态

show slave status \G;

在从数据库中开启主从同步

    start slave;

    查看从数据库状态发现已经同步

    主从复制测试

    1. 主机新建库-使用库-新建表-插入数据,ok
    2. 从机使用库-查看记录,ok

    三、Redis集群搭建

    面试题

    1~2亿条数据需要缓存,请问如何设计这个存储案例?

    回答:单机单台100%不可能,肯定是分布式存储,用redis如何落地?

    上述问题阿里P6~P7工程案例和场景设计类必考题目, 一般业界有3种解决方案

    1. 哈希取余分区
    2. 一致性哈希算法分区
    3. 哈希槽分区

    这三个分区的原理及其优缺点详见Redis集群https://blog.csdn.net/newbie5277/article/details/150447281?spm=1001.2014.3001.5502

    3主3从redis集群扩缩容配置案例架构

    本文的集群搭建为三主三从,并演示它的扩容和缩容案例

    关闭防火墙,打开docker

    systemctl stop firewalld
    systemctl start docker

    分别启动6台redis容器

    # 启动第1台节点
    # --net host 使用宿主机的IP和端口,默认
    # --cluster-enabled yes 开启redis集群
    # --appendonly yes 开启redis持久化
    # --port 6381 配置redis端口号
    docker run -d --name redis-node-1 --net host --privileged=true -v /app/redis-cluster/share/redis-node-1:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6381# 启动第2台节点
    docker run -d --name redis-node-2 --net host --privileged=true -v /app/redis-cluster/share/redis-node-2:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6382# 启动第3台节点
    docker run -d --name redis-node-3 --net host --privileged=true -v /app/redis-cluster/share/redis-node-3:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6383# 启动第4台节点
    docker run -d --name redis-node-4 --net host --privileged=true -v /app/redis-cluster/share/redis-node-4:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6384# 启动第5台节点
    docker run -d --name redis-node-5 --net host --privileged=true -v /app/redis-cluster/share/redis-node-5:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6385# 启动第6台节点
    docker run -d --name redis-node-6 --net host --privileged=true -v /app/redis-cluster/share/redis-node-6:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6386

    构建主从关系

    随便进入一个节点,此次为节点1

    docker exec -it redis-node-1 /bin/bash

    构建主从关系

    # 宿主机IP:端口
    redis-cli --cluster create 192.168.xxx.xxx:6381 192.168.xxx.xxx:6382 192.168.xxx.xxx:6383 192.168.xxx.xxx:6384 192.168.xxx.xxx:6385 192.168.xxx.xxx:6386 --cluster-replicas 1

    如果这里不成功,可以使用本地回环地址 127.0.0.1 来代替

    查看集群状态

    //进入容器节点1(或集群中其他节点)
    docker exec -it redis-node-1 /bin/bash
    //使用redis-cli连接到6381节点:
    redis-cli -p 6381
    //使用redis的相关命令查看集群状态: 
    cluster info

    其中分配的哈希槽数量 cluster_slots_assigned为16384,集群节点数量cluster_known_nodes为6 

    查看集群节点信息

    到这里我们的三主三从的Redis架构就配置完成了。

    Redis集群读写出错

    接下来进入容器节点1 并使用使用客户端连接

    docker exec -it redis-node-1 /bin/bash
    redis-cli -p 6381

    接下来我们尝试向redis中添加键值对,如下

    发现有时候插入成功,有时候报错,这是什么原因呢?

    k1经过计算得到的哈希槽为12706,但是当前连接的redis-server为6381(即节点1),它的哈希槽为:[0,5460](在创建构建主从关系时redis有提示,也可以通过 cluster nodes查看),所以会因为存不进去而报错。 
    执行 set k2 v2可以成功,因为k2计算出的哈希槽在[0-5460]区间中。

    这时候我们只需要在连接客户端的时候带上选项 -c,插入的时候,它会自动路由到对应哈希槽

    集群信息检查

    docker exec -it redis-node-1 /bin/bash
    # 输入任意一台主节点地址都可以进行集群检查
    redis-cli --cluster check 192.168.xxx.xxx:6381

    主从扩容

    假如因为业务量激增,需要向当前3主3从的集群中再加入1主1从两个节点。

    启动两台新的容器节点

    进入6387(节点7)容器内部

    docker exec -it redis-node-7 /bin/bash

    将6387作为master加入集群

    检查当前集群状态

    可以发现,6371节点已经作为master加入了集群,但是该节点没有被分配槽位。

    重新分配

    完成后,可以进行集群信息检查,查看分配结果:

    redis经过槽位检查后,会提示需要分配的槽位数量: 
    例如,我们现在是4台master,我们想要给node7分配4096个槽位,这样每个节点都是4096个槽位。
    输入4096后,会让输入要接收这些哈希槽的节点ID,填入node7的节点ID即可。(就是节点信息中很长的一串十六进制串)。
    然后会提示,询问要从哪些节点中拨出一部分槽位凑足4096个分给Node7。一般选择 all,即将之前的3个主节点的槽位都均一些给Node7,这样可以使得每个节点的槽位数相等均衡。
    输入all之后,redis会列出一个计划,内容是自动从前面的3台master中拨出一部分槽位分给Node7的槽位,需要确认一下分配的计划。
    输入yes确认后,redis便会自动重新洗牌,给Node7分配槽位。 

    可以发现重新洗牌后的槽位分配为:

    因为可能有些槽位中已经存储了key,完全的重新洗牌重新分配的成本过高,所以redis选择从前3个节点中匀出来一部分给节点7

    分配从节点

    为主节点6387分配从节点6388:redis便会向6388发送消息,使其加入集群并成为6387的从节点。

    redis-cli --cluster add-node 192.168.xxx.xxx:6388 192.168.xxx.xxx:6387 --cluster-slave --cluster-master-id node7节点的十六进制编号字符串

    检查集群当前状态

    主从缩容

    假如业务高峰期过去,需要将4主4从重新缩容到3主3从。即从集群中移除node8和node7.

    首先删除从节点6388

    //进入容器节点1 
    docker exec -it redis-node-1 /bin/bash
    // 检查容器状态,获取6388的节点编号 
    redis-cli --cluster check 192.168.xxx.xxx:6381
    // 将6388从集群中移除 
    redis-cli --cluster del-node 192.168.xxx.xxx:6388 6388节点编号

    对6387哈希槽分走

    如果我们想直接把node7的4096个哈希槽全部分给某个节点,可以直接输入4096。
    输入4096后,会让输入要接收这些哈希槽的节点ID。假如我们想把这4096个槽都分给Node1,直接输入node1节点的编号即可。
    然后会提示,询问要从哪些节点中拨出一部分槽位凑足4096个分给Node1。这里我们输入node7的节点编号,回车后输入done。 

    删除节点6387

    查看集群情况

    可以看到6387和6388已经没有了,集群又恢复到了三主三从。


    感谢阅读!

    http://www.dtcms.com/a/341189.html

    相关文章:

  1. 03-dockerfile
  2. 8月7日国赛全真模拟!2025“华数杯”数学建模竞赛,常用模型及算法总结
  3. 网络连接的核心机制
  4. Python 数据可视化:Matplotlib 与 Seaborn 实战
  5. [TryHackMe](知识学习)Hacking with PowerShell
  6. 浅显易懂——Redis、SpringDataRedis
  7. 充值系统开源版,支持对接码支付,支持三级分销
  8. 深入解析 Containerd 的工作原理
  9. K8S-Ingress资源对象
  10. 【C2000常见问题】当板子处于强电噪声环境下,或带重载时C2000芯片的PWM发波会出现异常,导致炸管。
  11. StarRocks学习4-查询优化与性能调优
  12. 使用 FastAPI 的 WebSockets 和 Elasticsearch 来构建实时应用
  13. 永磁同步电机谐波抑制算法(13)——传统预测控制与传统谐波抑制的碰撞
  14. 【学习笔记】大话设计模式——一些心得及各设计模式思想记录
  15. 372. 超级次方
  16. 力扣hot100:最大子数组和的两种高效方法:前缀和与Kadane算法(53)
  17. 【数据结构】递归与非递归:归并排序全解析
  18. CreateRef和useRef
  19. 继续记事本项目
  20. 三轴云台之闭环反馈技术
  21. MySQL数据库安全配置核心指南
  22. 十二,数据结构-链表
  23. BeyondWeb:大规模预训练合成数据的启示
  24. 解决程序无响应自动重启
  25. 高压柜无线测温:给智能化配电室装上“智能体温监测仪”
  26. 前端基础知识操作系统系列 - 03(linux系统下 文件操作常用的命令有哪些)
  27. C++ string(reserve , resize , insert , erase)
  28. Clonezilla live 再生龙还原系统各个版本的不同
  29. Sklearn 机器学习 房价预估 拆分训练集和测试集
  30. Pydantic介绍(基于Python类型注解的数据验证和解析库)(BaseModel、校验邮箱校验EmailStr、BaseSettings)