Docker进阶:mysql 主从复制、redis集群3主3从【扩缩容案例】

Docker进阶:mysql 主从复制、redis集群3主3从【扩缩容案例】

  • 一、Docker常规软件安装
    • 1.1 docker 安装 tomcat(默认最新版)
    • 1.2 docker 指定安装 tomcat8.0
    • 1.3 docker 安装 mysql 5.7(数据卷配置)
    • 1.4 演示--删除mysql容器,里面的数据是否能正常恢复
    • 1.5 docker 安装 redis7.0.9 (数据卷配置)
    • 1.6 宿主机修改redis.conf配置文件,验证redis 容器内生效
  • 二、Docker复杂软件安装(mysql 主从复制)
    • 2.1 启动主节点容器mysql-master(3306)
    • 2.2 启动从节点容器mysql-slave(3307)
    • 2.3 主数据库建库测试
    • 2.4 从数据库验证
  • 三、Docker复杂软件安装(redis集群--3主3从--分布式存储案例)
    • 3.1 前言--数据库分区技术
    • 3.2 redis集群--3主3从搭建
    • 3.3 redis集群--主从容错切换迁移案例
    • 3.4 redis集群--读写error
    • 3.5 redis集群--主从扩容案例(4主4从)
    • 3.6 redis集群--主从缩容案例(4主4从--->3主3从)


💖The Begin💖点点关注,收藏不迷路💖

在这里插入图片描述

首先,确保你已经安装了Docker。

一、Docker常规软件安装

1.1 docker 安装 tomcat(默认最新版)

1、创建一个目录用于存放程序文件。
mkdir -p  /home/my-projects

2、在终端或命令行界面中执行以下命令来拉取Tomcat的Docker镜像:
[root@zyl-server ~]# docker pull tomcat


3、查看Docker中已下载的Tomcat镜像
[root@zyl-server ~]# docker images tomcat
REPOSITORY   TAG       IMAGE ID       CREATED         SIZE
tomcat       latest    fb5657adc892   20 months ago   680MB
tomcat       8.0       ef6a7c98d192   4 years ago     356MB
[root@zyl-server ~]#


4、下载完成后,通过以下命令启动Tomcat容器,将宿主机的8080端口映射到容器的8080端口:

[root@zyl-server ~]# docker run -d -p 8080:8080 -v /home/my-projects:/usr/local/tomcat/webapps --privileged=true --name my-tomcat tomcat
8419cf96aaa10b2b3590e12d7d0973343dd9ab18a066be96c07e9bfa0875f632
[root@zyl-server ~]#





参数说明:
-p 小写    主机端口:容器端口
-P 大写    随机分配端口
--name my-tomcat  指定容器的名称为my-tomcat
-it        交互式模式运行
-d         后台运行
-v /home/my-projects:/usr/local/tomcat/webapps:将宿主机当前目录下的/home/my-projects目录挂载到容器中Tomcat的webapps目录,以便可以在宿主机上访问到Tomcat中部署的应用程序。

5、查看正在运行的Docker容器列表,
该命令将列出当前正在运行的容器的详细信息,包括容器ID、镜像名称、创建时间、状态等。

如果希望查看所有包括已停止的容器,可以添加 -a 参数,即 docker ps -a

[root@zyl-server ~]# docker ps
CONTAINER ID   IMAGE     COMMAND             CREATED          STATUS          PORTS                                       NAMES
8419cf96aaa1   tomcat    "catalina.sh run"   16 seconds ago   Up 15 seconds   0.0.0.0:8080->8080/tcp, :::8080->8080/tcp   my-tomcat
[root@zyl-server ~]#



6、进入tomcat容器的命令行界面(拷贝webapps.dist下的文件到webapps---因为镜像是精简版的)

[root@zyl-server ~]# docker exec -it 8419cf96aaa1 /bin/bash
root@8419cf96aaa1:/usr/local/tomcat# cp -r webapps.dist/* webapps/
root@8419cf96aaa1:/usr/local/tomcat# ls
BUILDING.txt     LICENSE  README.md      RUNNING.txt  conf  logs            temp     webapps.dist
CONTRIBUTING.md  NOTICE   RELEASE-NOTES  bin          lib   native-jni-lib  webapps  work
root@8419cf96aaa1:/usr/local/tomcat# cd webapps
root@8419cf96aaa1:/usr/local/tomcat/webapps# ls
ROOT  docs  examples  host-manager  index.html  manager
root@8419cf96aaa1:/usr/local/tomcat/webapps#


7、容器启动后,你可以通过在浏览器中访问 http://ip:8080 来验证Tomcat是否成功安装。如果一切正常,你将看到Tomcat的欢迎页面。

[root@zyl-server home]# curl http://localhost:8080

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <title>Apache Tomcat/10.0.14</title>
        <link href="favicon.ico" rel="icon" type="image/x-icon" />
        <link href="tomcat.css" rel="stylesheet" type="text/css" />
    </head>

。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

在这里插入图片描述

8、发布项目只需在宿主机的/home/my-projects,配置即可,如:

[root@zyl-server my-projects]# mkdir myweb
[root@zyl-server my-projects]# cd myweb/
[root@zyl-server myweb]# vi index.html
[root@zyl-server myweb]#

写入内容:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>


<h1>醉颜凉的第一个web项目。</h1>
<p>Hello Apache Tomcat/10.0.14</p>


</body>
</html>

在这里插入图片描述

1.2 docker 指定安装 tomcat8.0

要下载特定版本的Tomcat镜像,可以在 docker pull 命令后面添加 <image_name>:<tag> 参数。其中 <tag> 制定了镜像的版本号。

1、指定pull  tomcat8.0,下载Tomcat 8.0版本的镜像
[root@zyl-server ~]# docker pull tomcat:8.0


2、基于 Tomcat 8.0 版本的镜像启动一个容器,并将容器的 8080 端口映射到主机的 8081 端口上。
[root@zyl-server myweb]# docker run -d -p 8081:8080 --name tomcat tomcat:8.0
f71f3050a4af5fe02587a4f8f61c8af1e5d254be4ad9b1ae98309c7b46e61be4
[root@zyl-server myweb]#

解释:

-d 参数表示以后台模式运行容器。
-p 8081:8080 参数表示将容器的 8080 端口映射到主机的 8081 端口。这样,当你在浏览器中访问 http://localhost:8081 时,将会被转发到容器中的 Tomcat 服务器。
--name tomcat 参数指定容器的名称为 "tomcat"

在这里插入图片描述

1.3 docker 安装 mysql 5.7(数据卷配置)

1、拉取 MySQL 5.7 镜像:
docker pull mysql:5.7

2、在启动容器之前,创建一个目录来持久化 MySQL 数据()。使用以下命令创建一个目录,用于存储数据库文件:

创建一个目录作为 Docker 数据卷并将其挂载到 MySQL 容器中,可以确保 MySQL 数据在容器被删除或重启后仍然存在。

[root@zyl-server ~]# mkdir -p /mysql/data
[root@zyl-server ~]#

3、使用以下命令启动 MySQL 5.7 容器:
docker run -d -p 3306:3306 --name mysql-5.7 -e MYSQL_ROOT_PASSWORD=123456 -v /mysql/data:/var/lib/mysql mysql:5.7

4、查看正在运行的Docker容器列表:

[root@zyl-server ~]# docker run -d -p 3306:3306 --name mysql-5.7 -e MYSQL_ROOT_PASSWORD=123456 -v /mysql/data:/var/lib/mysql -v /mysql/log:/var/log/mysql -v /mysql/conf:/etc/mysql/conf.d mysql:5.7
ddba7f4cf1f89ea7627a3c3628d7479c31bfdb7d0b0dd82e78cb50ce5b4726d8
[root@zyl-server ~]#

[root@zyl-server ~]# docker ps
CONTAINER ID   IMAGE        COMMAND                  CREATED          STATUS          PORTS                                                  NAMES
ddba7f4cf1f8   mysql:5.7    "docker-entrypoint.s…"   22 seconds ago   Up 21 seconds   0.0.0.0:3306->3306/tcp, :::3306->3306/tcp, 33060/tcp   mysql-5.7
f71f3050a4af   tomcat:8.0   "catalina.sh run"        36 minutes ago   Up 36 minutes   0.0.0.0:8081->8080/tcp, :::8081->8080/tcp              tomcat
8419cf96aaa1   tomcat       "catalina.sh run"        48 minutes ago   Up 48 minutes   0.0.0.0:8080->8080/tcp, :::8080->8080/tcp              my-tomcat
[root@zyl-server ~]#


5、进入mysql-5.7容器:
docker exec -it ddba7f4cf1f8 /bin/bash

6、以 root 用户身份登录到 MySQL 数据库(密码 123456 访问 MySQL 服务):

root@db84734dad6a:/# mysql -u root -p
Enter password:  //123456)
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.36 MySQL Community Server (GPL)

Copyright (c) 2000, 2021, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>

7、例如,创建一个名为 "mydatabase" 的数据库:

CREATE DATABASE mydatabase;

8、使用 USE 命令切换到所需的数据库:
USE mydatabase;

9、例如,创建一个名为 "users" 的表,包含 id、name 和 email 列:

CREATE TABLE users (
  id INT,
  name VARCHAR(50),
  email VARCHAR(100)
);

10、使用 INSERT INTO 语句。向 "users" 表插入三条数据:

INSERT INTO users (id, name, email) VALUES
  (1, 'John', 'john@example.com'),
  (2, 'Jane', 'jane@example.com'),
  (3, 'Tom', 'tom@example.com');

11、本地使用数据库管理工具远程连接:

在这里插入图片描述

解决插入中文报错:

在这里插入图片描述

INSERT INTO users (id, name, email) VALUES (4, '张三', 'zhangsan@example.com');

1、查看数据库的编码方式
SHOW VARIABLES LIKE 'character_set_database';
SHOW VARIABLES LIKE 'character%';

在这里插入图片描述

2、修改数据库的字符集:
[root@zyl-server ~]# cd /mysql/conf
[root@zyl-server conf]# pwd
/mysql/conf
[root@zyl-server conf]#

vi my.cnf,写入下面内容,my.cnf 为前面挂载的数据卷:

[client]

default_character_set=utf8

[mysqld]
collation_server=utf8_general_ci
character_set_server=utf8


3、修改前面创建的数据库、表的字符集:

ALTER DATABASE mydatabase CHARACTER SET utf8;

ALTER TABLE users CONVERT TO CHARACTER SET utf8;

3、重新启动mysql容器
[root@zyl-server conf]# docker restart mysql-5.7
mysql-5.7
[root@zyl-server conf]#


4、再次查看数据库编码方式:
mysql> SHOW VARIABLES LIKE 'character%';
+--------------------------+----------------------------+
| Variable_name            | Value                      |
+--------------------------+----------------------------+
| character_set_client     | utf8                       |
| character_set_connection | utf8                       |
| character_set_database   | utf8                       |
| character_set_filesystem | binary                     |
| character_set_results    | utf8                       |
| character_set_server     | utf8                       |
| character_set_system     | utf8                       |
| character_sets_dir       | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
8 rows in set (0.00 sec)

mysql>

在这里插入图片描述

5、插入数据测试

INSERT INTO users (id, name, email) VALUES (4, '张三', 'zhangsan@example.com');

在这里插入图片描述


总结: docker安装完mysql,运行实例之后,建议先修改完字符集编码后再建库建表。

在创建 MySQL 数据库和表之前,先确保 MySQL 的字符集编码设置是正确的。如果你没有设置正确的字符集编码,就可能会在处理文本数据时出现乱码等问题,影响数据的完整性和可读性。


1.4 演示–删除mysql容器,里面的数据是否能正常恢复

[root@zyl-server ~]# docker ps
CONTAINER ID   IMAGE        COMMAND                  CREATED             STATUS             PORTS                                                  NAMES
ddba7f4cf1f8   mysql:5.7    "docker-entrypoint.s…"   27 minutes ago      Up 20 minutes      0.0.0.0:3306->3306/tcp, :::3306->3306/tcp, 33060/tcp   mysql-5.7
[root@zyl-server ~]#


1、删除刚创建 MySQL 容器(线上环境慎用) docker rm -f mysql-5.7

[root@zyl-server ~]# docker rm -f mysql-5.7
mysql-5.7
[root@zyl-server ~]#

2、重新启动MySQL 容器

[root@zyl-server ~]# docker run -d -p 3306:3306 --name mysql-5.7 -e MYSQL_ROOT_PASSWORD=123456 -v /mysql/data:/var/lib/mysql -v /mysql/log:/var/log/mysql -v /mysql/conf:/etc/mysql/conf.d mysql:5.7
0f129eb516f74872334f3c46b9b57b0808de2441bfd0db3a54c564aca838ddff
[root@zyl-server ~]#
[root@zyl-server ~]# docker ps
CONTAINER ID   IMAGE        COMMAND                  CREATED             STATUS             PORTS                                                  NAMES
0f129eb516f7   mysql:5.7    "docker-entrypoint.s…"   5 seconds ago       Up 3 seconds       0.0.0.0:3306->3306/tcp, :::3306->3306/tcp, 33060/tcp   mysql-5.7
[root@zyl-server ~]#

3、进入重新启动的MySQL 容器
docker exec -it mysql-5.7 /bin/bash

或者
docker exec -it 0f129eb516f7 /bin/bash


4、验证,刚才创建的mydatabase库和users表数据

[root@zyl-server ~]# docker exec -it mysql-5.7 /bin/bash
root@0f129eb516f7:/# mysql -u root -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.36 MySQL Community Server (GPL)

Copyright (c) 2000, 2021, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mydatabase         |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
5 rows in set (0.00 sec)

mysql>

mysql> use mydatabase;
Database changed
mysql> select * from users;
+------+--------+----------------------+
| id   | name   | email                |
+------+--------+----------------------+
|    1 | John   | john@example.com     |
|    2 | Jane   | jane@example.com     |
|    3 | Tom    | tom@example.com      |
|    4 | 张三   | zhangsan@example.com |
+------+--------+----------------------+
4 rows in set (0.00 sec)

mysql>

在这里插入图片描述

总结:使用 Docker 数据卷的方法来进行存储。保留 MySQL 数据库和表的持久化数据。容器实例删除,里面的数据在重启启动容器实例之后也能正常恢复

1.5 docker 安装 redis7.0.9 (数据卷配置)

redis.conf文件下载

1、宿主机下/下创建 /apps/redis  目录
[root@zyl-server /]# mkdir -p /apps/redis

2、在/apps/redis  目录,创建redis.conf文件

3、修改redis.conf文件
## 开启redis验证,添加该行(可选)
requirepass 123456

## 允许redis远程连接,注释# bind 127.0.0.1
# bind 127.0.0.1

## 将 daemonize yes 改为 
daemonize no

因为该配置和docker run -d 参数冲突,会导致容器启动一直失败

## 开启redis 数据持久化 appendonly yes (可选)
appendonly yes

1、运行以下命令来下载并运行 Redis7.0.9  的 Docker 镜像:
docker run -d -p 6379:6379 --privileged=true --name my-redis -v /apps/redis/redis.conf:/etc/redis/redis.conf -v /apps/redis/data:/data -d redis:7.0.9 redis-server /etc/redis/redis.conf

这个命令将以后台方式运行Redis容器,并进行以下配置:

开放主机的6379端口并将其映射到容器的6379端口。
启用特权模式,以便在容器内部执行一些特殊操作(如修改文件权限)。
将容器的名称设置为my-redis。
将主机上的/apps/redis/redis.conf文件挂载到容器内的/etc/redis/redis.conf文件,以应用自定义的Redis配置。
将主机上的/apps/redis/data目录挂载到容器内的/data目录,以作为Redis数据的持久化存储。

2、检查容器的运行状态:
[root@zyl-server redis]# docker ps
CONTAINER ID   IMAGE         COMMAND                  CREATED              STATUS              PORTS                                                  NAMES
6293c1f5fc5e   redis:7.0.9   "docker-entrypoint.s…"   About a minute ago   Up About a minute   0.0.0.0:6379->6379/tcp, :::6379->6379/tcp              my-redis

3、在 my-redis容器中打开交互式终端

docker exec -it my-redis /bin/bash

4、连接到Redis服务器:

[root@zyl-server redis.conf]# docker exec -it my-redis /bin/bash
root@508d58462ff3:/data# redis-cli

或者使用

docker exec -it my-redis redis-cli

在Docker容器中打开一个交互式终端,并直接进入Redis客户端。

127.0.0.1:6379> set k1 v1
(error) NOAUTH Authentication required.
127.0.0.1:6379>

这是因为redis设置了密码,我们需要使用密码来进行验证之后再来对redis客户端进行操作,否则我们没有操作redis缓存数据库的权限。

解决方法----> 我们使用命令:auth '123456'
127.0.0.1:6379> auth '123456'
OK
127.0.0.1:6379> set k1 v1
OK
127.0.0.1:6379> get k1
"v1"
127.0.0.1:6379>

1.6 宿主机修改redis.conf配置文件,验证redis 容器内生效

在Redis的配置文件redis.conf中,可以设置参数databases来指定Redis服务器的数据库数量。

默认情况下,Redis服务器的数据库数量为16,这意味着你可以在一个Redis实例中创建最多16个不同的数据库。每个数据库都是独立的,并且可以使用SELECT命令进行切换。

1、redis.conf 服务器的数据库数量
databases 16

2、使用SELECT命令切换到指定的数据库。在命令行中输入的SELECT 18表示要切换到数据库18
127.0.0.1:6379> select 18
(error) ERR DB index is out of range
127.0.0.1:6379>

3、修改宿主机redis.conf,保存
databases 20

4、重启 my-redis 容器
docker restart my-redis

5、验证
[root@zyl-server redis.conf]# docker exec -it my-redis redis-cli
127.0.0.1:6379> auth '123456'
OK
127.0.0.1:6379> select 18
OK
127.0.0.1:6379[18]>

----结论---------修改宿主机redis.conf,容器内生效。。

二、Docker复杂软件安装(mysql 主从复制)

2.1 启动主节点容器mysql-master(3306)

1、启动主节点容器mysql-master:

docker run -p 3306:3306 --name mysql-master \
-v /mydata/mysql-master/log:/var/log/mysql \
-v /mydata/mysql-master/data:/var/lib/mysql \
-v /mydata/mysql-master/conf:/etc/mysql \
-e MYSQL_ROOT_PASSWORD=123456 \
-d mysql:5.7

以后台模式运行MySQL 5.7容器作为主节点:
各个选项的含义:

-p 3306:3306:将主机的3306端口映射到容器的3306端口,这样可以从主机上访问MySQL服务。
--name mysql-master:给容器指定一个名称为"mysql-master"-v /mydata/mysql-master/log:/var/log/mysql:将主机上的"/mydata/mysql-master/log"目录挂载到容器中的"/var/log/mysql"目录,用于持久化存储MySQL的日志文件。
-v /mydata/mysql-master/data:/var/lib/mysql:将主机上的"/mydata/mysql-master/data"目录挂载到容器中的"/var/lib/mysql"目录,用于持久化存储MySQL的数据文件。
-v /mydata/mysql-master/conf:/etc/mysql:将主机上的"/mydata/mysql-master/conf"目录挂载到容器中的"/etc/mysql"目录,用于持久化存储MySQL的配置文件。
-e MYSQL_ROOT_PASSWORD=123456:设置MySQL的root用户密码为"123456"-d mysql:5.7:使用MySQL 5.7镜像启动一个后台运行的容器。

2、列出正在运行的Docker容器:

[root@zyl-server ~]# docker ps
CONTAINER ID   IMAGE       COMMAND                  CREATED         STATUS         PORTS                                                  NAMES
5ea683a60e95   mysql:5.7   "docker-entrypoint.s…"   5 seconds ago   Up 4 seconds   0.0.0.0:3306->3306/tcp, :::3306->3306/tcp, 33060/tcp   mysql-master
[root@zyl-server ~]#

3、cd /mydata/mysql-master/conf目录新建my.cnf文件

vi 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

##将MySQL容器的字符集和排序规则设置为UTF-8编码
collation_server=utf8_general_ci
character_set_server=utf8


4、修改后,重启mysql-master容器实例
[root@zyl-server conf]# docker restart mysql-master
mysql-master
[root@zyl-server conf]# docker ps
CONTAINER ID   IMAGE       COMMAND                  CREATED         STATUS          PORTS                                                  NAMES
5ea683a60e95   mysql:5.7   "docker-entrypoint.s…"   6 minutes ago   Up 16 seconds   0.0.0.0:3306->3306/tcp, :::3306->3306/tcp, 33060/tcp   mysql-master
[root@zyl-server conf]#

5、进入到mysql-master容器
docker exec -it mysql-master /bin/bash

6、进入MySQL容器后以root用户身份登录到MySQL数据库


root@5ea683a60e95:/# mysql -u root -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.36-log MySQL Community Server (GPL)

Copyright (c) 2000, 2021, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>

7、创建数据同步用户,在MySQL数据库中创建一个名为'slave'的用户,并设置密码为'123456',该用户允许从任何主机连接:

CREATE USER 'slave'@'%' IDENTIFIED BY '123456';

mysql> CREATE USER 'slave'@'%' IDENTIFIED BY '123456';
Query OK, 0 rows affected (0.00 sec)

mysql>


8、为'slave'用户授予复制(REPLICATION)相关的权限和客户端(CLIENT)权限:

GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'slave'@'%';

mysql> GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'slave'@'%';
Query OK, 0 rows affected (0.00 sec)

mysql>

2.2 启动从节点容器mysql-slave(3307)

1、启动从节点容器mysql-slave:
docker run -p 3307:3306 --name mysql-slave \
-v /mydata/mysql-slave/log:/var/log/mysql \
-v /mydata/mysql-slave/data:/var/lib/mysql \
-v /mydata/mysql-slave/conf:/etc/mysql \
-e MYSQL_ROOT_PASSWORD=123456 \
-d mysql:5.7

2、列出正在运行的Docker容器:

[root@zyl-server ~]# docker ps
CONTAINER ID   IMAGE       COMMAND                  CREATED          STATUS         PORTS                                                  NAMES
77e48a50155d   mysql:5.7   "docker-entrypoint.s…"   5 seconds ago    Up 4 seconds   33060/tcp, 0.0.0.0:3307->3306/tcp, :::3307->3306/tcp   mysql-slave
5ea683a60e95   mysql:5.7   "docker-entrypoint.s…"   12 minutes ago   Up 6 minutes   0.0.0.0:3306->3306/tcp, :::3306->3306/tcp, 33060/tcp   mysql-master
[root@zyl-server ~]#

3、cd /mydata/mysql-slave/conf目录新建my.cnf文件
vi my.conf


[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

##将MySQL容器的字符集和排序规则设置为UTF-8编码
collation_server=utf8_general_ci
character_set_server=utf8


4、修改后,重启mysql-slave容器实例:
[root@zyl-server conf]# docker restart mysql-slave
mysql-slave
[root@zyl-server conf]#

[root@zyl-server conf]# docker ps
CONTAINER ID   IMAGE       COMMAND                  CREATED          STATUS          PORTS                                                  NAMES
77e48a50155d   mysql:5.7   "docker-entrypoint.s…"   2 minutes ago    Up 17 seconds   33060/tcp, 0.0.0.0:3307->3306/tcp, :::3307->3306/tcp   mysql-slave
5ea683a60e95   mysql:5.7   "docker-entrypoint.s…"   15 minutes ago   Up 9 minutes    0.0.0.0:3306->3306/tcp, :::3306->3306/tcp, 33060/tcp   mysql-master
[root@zyl-server conf]#

5、在主数据mysql-master库查看主从同步状态

docker exec -it mysql-master /bin/bash

root@5ea683a60e95:/# mysql -u root -p

mysql> show master status;
+-----------------------+----------+--------------+------------------+-------------------+
| File                  | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+-----------------------+----------+--------------+------------------+-------------------+
| mall-mysql-bin.000001 |      617 |              | mysql            |                   |
+-----------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

mysql>

6、进入mysql-slave 容器:

docker exec -it mysql-slave /bin/bash

mysql -u root -p

[root@zyl-server conf]# docker exec -it mysql-slave /bin/bash
root@77e48a50155d:/# mysql -u root -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.36-log MySQL Community Server (GPL)

Copyright (c) 2000, 2021, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>


7、在从数据库mysql-slave中配置主从复制,配置MySQL复制的主服务器信息:

change master to master_host='192.168.234.10', master_user='slave', master_password='123456', master_port=3306, master_log_file='mall-mysql-bin.000001', master_log_pos=617, master_connect_retry=30;

mysql> change master to master_host='192.168.234.10', master_user='slave', master_password='123456', master_port=3306, master_log_file='mall-mysql-bin.000001', master_log_pos=617, master_connect_retry=30;
Query OK, 0 rows affected, 2 warnings (0.01 sec)

mysql>


其中master_log_file,master_log_pos为mysql-master中查到的结果:

mysql> show master status;
+-----------------------+----------+--------------+------------------+-------------------+
| File                  | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+-----------------------+----------+--------------+------------------+-------------------+
| mall-mysql-bin.000001 |      617 |              | mysql            |                   |
+-----------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

各个参数含义如下:

MASTER_HOST:指定主服务器的IP地址或主机名。
MASTER_USER:指定用于复制的用户(在之前创建的'slave'用户)。
MASTER_PASSWORD:指定复制用户的密码。
MASTER_PORT:指定主服务器的端口号。
MASTER_LOG_FILE:指定主服务器的二进制日志文件名。
MASTER_LOG_POS:指定要从哪个位置开始复制主服务器的二进制日志。
MASTER_CONNECT_RETRY:指定在连接失败后重试连接的时间间隔(以秒为单位)。


8、在从数据库mysql-master中查看主从同步状态:

mysql> show slave status \G;
*************************** 1. row ***************************
               Slave_IO_State:
                  Master_Host: 192.168.234.10
                  Master_User: slave
                  Master_Port: 3306
                Connect_Retry: 30
              Master_Log_File: mall-mysql-bin.000001
          Read_Master_Log_Pos: 617
               Relay_Log_File: mall-mysql-relay-bin.000001
                Relay_Log_Pos: 4
        Relay_Master_Log_File: mall-mysql-bin.000001
             Slave_IO_Running: No
            Slave_SQL_Running: No
              Replicate_Do_DB:
          Replicate_Ignore_DB:
           Replicate_Do_Table:
       Replicate_Ignore_Table:
      Replicate_Wild_Do_Table:
  Replicate_Wild_Ignore_Table:
                   Last_Errno: 0
                   Last_Error:
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 617
              Relay_Log_Space: 154
              Until_Condition: None
               Until_Log_File:
                Until_Log_Pos: 0
           Master_SSL_Allowed: No
           Master_SSL_CA_File:
           Master_SSL_CA_Path:
              Master_SSL_Cert:
            Master_SSL_Cipher:
               Master_SSL_Key:
        Seconds_Behind_Master: NULL
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error:
               Last_SQL_Errno: 0
               Last_SQL_Error:
  Replicate_Ignore_Server_Ids:
             Master_Server_Id: 0
                  Master_UUID:
             Master_Info_File: /var/lib/mysql/master.info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State:
           Master_Retry_Count: 86400
                  Master_Bind:
      Last_IO_Error_Timestamp:
     Last_SQL_Error_Timestamp:
               Master_SSL_Crl:
           Master_SSL_Crlpath:
           Retrieved_Gtid_Set:
            Executed_Gtid_Set:
                Auto_Position: 0
         Replicate_Rewrite_DB:
                 Channel_Name:
           Master_TLS_Version:
1 row in set (0.00 sec)

ERROR:
No query specified

mysql>

当Slave_IO_Running和Slave_SQL_Running状态为"No"时,表示MySQL复制的I/O线程和SQL线程都未在运行。

原因:从数据库未开启主从同步

在这里插入图片描述

解决:启动从服务器的复制进程

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

mysql> start slave;
Query OK, 0 rows affected (0.00 sec)

mysql>


10、再次在从数据库mysql-master中查看主从同步状态:
mysql> show slave status \G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.234.10
                  Master_User: slave
                  Master_Port: 3306
                Connect_Retry: 30
              Master_Log_File: mall-mysql-bin.000001
          Read_Master_Log_Pos: 617
               Relay_Log_File: mall-mysql-relay-bin.000002
                Relay_Log_Pos: 325
        Relay_Master_Log_File: mall-mysql-bin.000001
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB:
          Replicate_Ignore_DB:
           Replicate_Do_Table:
       Replicate_Ignore_Table:
      Replicate_Wild_Do_Table:
  Replicate_Wild_Ignore_Table:
                   Last_Errno: 0
                   Last_Error:
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 617
              Relay_Log_Space: 537
              Until_Condition: None
               Until_Log_File:
                Until_Log_Pos: 0
           Master_SSL_Allowed: No
           Master_SSL_CA_File:
           Master_SSL_CA_Path:
              Master_SSL_Cert:
            Master_SSL_Cipher:
               Master_SSL_Key:
        Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error:
               Last_SQL_Errno: 0
               Last_SQL_Error:
  Replicate_Ignore_Server_Ids:
             Master_Server_Id: 101
                  Master_UUID: 4dd5c496-49ba-11ee-a195-0242ac110002
             Master_Info_File: /var/lib/mysql/master.info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
           Master_Retry_Count: 86400
                  Master_Bind:
      Last_IO_Error_Timestamp:
     Last_SQL_Error_Timestamp:
               Master_SSL_Crl:
           Master_SSL_Crlpath:
           Retrieved_Gtid_Set:
            Executed_Gtid_Set:
                Auto_Position: 0
         Replicate_Rewrite_DB:
                 Channel_Name:
           Master_TLS_Version:
1 row in set (0.00 sec)

ERROR:
No query specified

mysql>

在这里插入图片描述

2.3 主数据库建库测试

1、例如,创建一个名为 "mydatabase" 的数据库:

CREATE DATABASE mydatabase;

2、使用 USE 命令切换到所需的数据库:
USE mydatabase;

3、例如,创建一个名为 "users" 的表,包含 id、name 和 email 列:

CREATE TABLE users (
  id INT,
  name VARCHAR(50),
  email VARCHAR(100)
);

4、使用 INSERT INTO 语句。向 "users" 表插入三条数据:

INSERT INTO users (id, name, email) VALUES
  (1, 'John', 'john@example.com'),
  (2, 'Jane', 'jane@example.com'),
  (3, 'Tom', 'tom@example.com');

在这里插入图片描述

2.4 从数据库验证

1、从数据库查看数据库列表:
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mydatabase         |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
5 rows in set (0.00 sec)

mysql>

在这里插入图片描述

2、切换到mydatabase数据库

USE mydatabase;

3、显示当前数据库中的所有表

SHOW TABLES;

4、查询"users"表中的所有记录:

select * from users;


mysql> select * from users;
+------+------+------------------+
| id   | name | email            |
+------+------+------------------+
|    1 | John | john@example.com |
|    2 | Jane | jane@example.com |
|    3 | Tom  | tom@example.com  |
+------+------+------------------+
3 rows in set (0.00 sec)

mysql>

在这里插入图片描述

三、Docker复杂软件安装(redis集群–3主3从–分布式存储案例)

3.1 前言–数据库分区技术

哈希取余分区:通过将数据的哈希值与分区数进行取余运算来确定数据所属的分区。例如,如果有4个分区,对数据的哈希值进行取余运算,将其分配到0至3之间的一个分区。这种方法简单且容易实现,但可能会导致数据分布不均衡。

一致性哈希算法分区:一致性哈希算法使用一个哈希环来表示分区的范围,数据的哈希值将映射到哈希环上的某个位置。在一致性哈希算法中,当分区发生变化时,只有少量的数据需要重新映射到新的分区,因此可以实现动态的分区扩展或缩减。这种方法能够提供较好的负载均衡和可扩展性。

哈希槽分区:哈希槽分区将数据均匀地分布在一组预定义的哈希槽中。每个分区被映射到一个哈希槽,数据的哈希值决定了它所属的哈希槽。这种方法可以随着分区数的增加或减少而调整哈希槽数量,从而实现动态的扩展和缩减。这种方法提供了良好的负载均衡和扩展性。

这些分区技术可以用于在数据库中水平划分数据以提高性能、灵活性和可伸缩性。每种分区技术都有其特定的优点和适用场景,选择合适的分区技术应根据具体需求和系统特点进行评估。

3.2 redis集群–3主3从搭建

1、启动6个Redis节点

docker run -d --name redis-node-1 --net host --privileged=true -v /data/redis/share/redis-node-1:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6381
docker run -d --name redis-node-2 --net host --privileged=true -v /data/redis/share/redis-node-2:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6382
docker run -d --name redis-node-3 --net host --privileged=true -v /data/redis/share/redis-node-3:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6383
docker run -d --name redis-node-4 --net host --privileged=true -v /data/redis/share/redis-node-4:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6384
docker run -d --name redis-node-5 --net host --privileged=true -v /data/redis/share/redis-node-5:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6385
docker run -d --name redis-node-6 --net host --privileged=true -v /data/redis/share/redis-node-6:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6386

参数:

--name: 指定容器的名称,例如redis-node-1、redis-node-2等。
--net host: 使用主机网络模式,使容器可以使用主机的网络栈。
--privileged=true: 在容器内部提供特权访问,通常用于需要访问主机设备或文件系统的情况。
-v /data/redis/share/redis-node-X:/data: 将主机上的/data/redis/share/redis-node-X目录挂载到容器内的/data目录,用于持久化存储Redis数据。
redis:6.0.8: 指定使用的Redis镜像及版本号。
--cluster-enabled yes: 启用Redis集群功能。
--appendonly yes: 开启AOF(Append Only File)持久化方式。
--port XXXX: 指定Redis节点的端口号,例如63816382等。

2、列出当前正在运行的Docker容器

[root@zyl-server ~]# docker ps
CONTAINER ID   IMAGE         COMMAND                  CREATED         STATUS         PORTS     NAMES
51fa09a6a3e6   redis:6.0.8   "docker-entrypoint.s…"   5 seconds ago   Up 4 seconds             redis-node-6
74faf0961119   redis:6.0.8   "docker-entrypoint.s…"   6 seconds ago   Up 5 seconds             redis-node-5
2bb58b50c70a   redis:6.0.8   "docker-entrypoint.s…"   6 seconds ago   Up 5 seconds             redis-node-4
9a0fd2b62b14   redis:6.0.8   "docker-entrypoint.s…"   6 seconds ago   Up 5 seconds             redis-node-3
cb67d2dfecd0   redis:6.0.8   "docker-entrypoint.s…"   6 seconds ago   Up 6 seconds             redis-node-2
59bcc7ed00e5   redis:6.0.8   "docker-entrypoint.s…"   7 seconds ago   Up 6 seconds             redis-node-1
[root@zyl-server ~]#

3、进入redis-node-16台机器配置构建集群关系

redis-cli --cluster create 192.168.234.10:6381 192.168.234.10:6382 192.168.234.10:6383 192.168.234.10:6384 192.168.234.10:6385 192.168.234.10:6386 --cluster-replicas 1

[root@zyl-server ~]# docker exec -it redis-node-1 /bin/bash
root@zyl-server:/data# redis-cli --cluster create 192.168.234.10:6381 192.168.234.10:6382 192.168.234.10:6383 192.168.234.10:6384 192.168.234.10:6385 192.168.234.10:6386 --cluster-replicas 1
>>> Performing hash slots allocation on 6 nodes...
Master[0] -> Slots 0 - 5460
Master[1] -> Slots 5461 - 10922
Master[2] -> Slots 10923 - 16383
Adding replica 192.168.234.10:6385 to 192.168.234.10:6381
Adding replica 192.168.234.10:6386 to 192.168.234.10:6382
Adding replica 192.168.234.10:6384 to 192.168.234.10:6383
>>> Trying to optimize slaves allocation for anti-affinity
[WARNING] Some slaves are in the same host as their master
M: 1ea11eda762c317ac5b9f398827c51085e553652 192.168.234.10:6381
   slots:[0-5460] (5461 slots) master
M: f0a14e3d08738655dd7ed0b702187f7096f06bba 192.168.234.10:6382
   slots:[5461-10922] (5462 slots) master
M: 553a35ceea6fb2f0d2c668923d6650f65525a370 192.168.234.10:6383
   slots:[10923-16383] (5461 slots) master
S: dd03b2ff3629d360da59294c0b547849de41e8fb 192.168.234.10:6384
   replicates f0a14e3d08738655dd7ed0b702187f7096f06bba
S: 0b1cfb29bc066c74a831a948e3c23f8dc6e0bbe6 192.168.234.10:6385
   replicates 553a35ceea6fb2f0d2c668923d6650f65525a370
S: 6ebb4441ded1cfb4ce346e4349e155a685acdffd 192.168.234.10:6386
   replicates 1ea11eda762c317ac5b9f398827c51085e553652
Can I set the above configuration? (type 'yes' to accept): yes
>>> Nodes configuration updated
>>> Assign a different config epoch to each node
>>> Sending CLUSTER MEET messages to join the cluster
Waiting for the cluster to join
.
>>> Performing Cluster Check (using node 192.168.234.10:6381)
M: 1ea11eda762c317ac5b9f398827c51085e553652 192.168.234.10:6381
   slots:[0-5460] (5461 slots) master
   1 additional replica(s)
M: f0a14e3d08738655dd7ed0b702187f7096f06bba 192.168.234.10:6382
   slots:[5461-10922] (5462 slots) master
   1 additional replica(s)
S: 0b1cfb29bc066c74a831a948e3c23f8dc6e0bbe6 192.168.234.10:6385
   slots: (0 slots) slave
   replicates 553a35ceea6fb2f0d2c668923d6650f65525a370
M: 553a35ceea6fb2f0d2c668923d6650f65525a370 192.168.234.10:6383
   slots:[10923-16383] (5461 slots) master
   1 additional replica(s)
S: 6ebb4441ded1cfb4ce346e4349e155a685acdffd 192.168.234.10:6386
   slots: (0 slots) slave
   replicates 1ea11eda762c317ac5b9f398827c51085e553652
S: dd03b2ff3629d360da59294c0b547849de41e8fb 192.168.234.10:6384
   slots: (0 slots) slave
   replicates f0a14e3d08738655dd7ed0b702187f7096f06bba
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

在这里插入图片描述

4、主节点查看集群状态
root@zyl-server:/data# redis-cli -p 6381

##获取有关Redis集群的信息,例如集群的状态、节点数量、槽位分配情况
127.0.0.1:6381> cluster info
cluster_state:ok
cluster_slots_assigned:16384
cluster_slots_ok:16384
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:6
cluster_size:3
cluster_current_epoch:6
cluster_my_epoch:1
cluster_stats_messages_ping_sent:138
cluster_stats_messages_pong_sent:146
cluster_stats_messages_sent:284
cluster_stats_messages_ping_received:141
cluster_stats_messages_pong_received:138
cluster_stats_messages_meet_received:5
cluster_stats_messages_received:284
127.0.0.1:6381>

##获取当前集群中所有节点的信息
127.0.0.1:6381> cluster nodes
f0a14e3d08738655dd7ed0b702187f7096f06bba 192.168.234.10:6382@16382 master - 0 1693680656000 2 connected 5461-10922
0b1cfb29bc066c74a831a948e3c23f8dc6e0bbe6 192.168.234.10:6385@16385 slave 553a35ceea6fb2f0d2c668923d6650f65525a370 0 1693680659111 3 connected
1ea11eda762c317ac5b9f398827c51085e553652 192.168.234.10:6381@16381 myself,master - 0 1693680659000 1 connected 0-5460
553a35ceea6fb2f0d2c668923d6650f65525a370 192.168.234.10:6383@16383 master - 0 1693680657069 3 connected 10923-16383
6ebb4441ded1cfb4ce346e4349e155a685acdffd 192.168.234.10:6386@16386 slave 1ea11eda762c317ac5b9f398827c51085e553652 0 1693680658091 1 connected
dd03b2ff3629d360da59294c0b547849de41e8fb 192.168.234.10:6384@16384 slave f0a14e3d08738655dd7ed0b702187f7096f06bba 0 1693680660128 2 connected
127.0.0.1:6381>

在这里插入图片描述

3.3 redis集群–主从容错切换迁移案例

master:6381下线,slave:6386上位:

1、停止redis-node-1的Docker容器

[root@zyl-server ~]# docker stop redis-node-1
redis-node-1
[root@zyl-server ~]#

2、列出当前正在运行的Docker容器

[root@zyl-server ~]# docker ps
CONTAINER ID   IMAGE         COMMAND                  CREATED        STATUS        PORTS     NAMES
51fa09a6a3e6   redis:6.0.8   "docker-entrypoint.s…"   10 hours ago   Up 10 hours             redis-node-6
74faf0961119   redis:6.0.8   "docker-entrypoint.s…"   10 hours ago   Up 10 hours             redis-node-5
2bb58b50c70a   redis:6.0.8   "docker-entrypoint.s…"   10 hours ago   Up 10 hours             redis-node-4
9a0fd2b62b14   redis:6.0.8   "docker-entrypoint.s…"   10 hours ago   Up 10 hours             redis-node-3
cb67d2dfecd0   redis:6.0.8   "docker-entrypoint.s…"   10 hours ago   Up 10 hours             redis-node-2
[root@zyl-server ~]#

3、进入名为redis-node-2的Docker容器

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

4、连接到Redis节点
root@zyl-server:/data# redis-cli -p 6382
127.0.0.1:6382>

5##获取有关Redis集群的信息,例如集群的状态、节点数量、槽位分配情况
127.0.0.1:6382> cluster info
cluster_state:ok
cluster_slots_assigned:16384
cluster_slots_ok:16384
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:6
cluster_size:3
cluster_current_epoch:7
cluster_my_epoch:2
cluster_stats_messages_ping_sent:1260
cluster_stats_messages_pong_sent:1243
cluster_stats_messages_meet_sent:1
cluster_stats_messages_auth-ack_sent:1
cluster_stats_messages_sent:2505
cluster_stats_messages_ping_received:1243
cluster_stats_messages_pong_received:1261
cluster_stats_messages_fail_received:1
cluster_stats_messages_auth-req_received:1
cluster_stats_messages_received:2506
127.0.0.1:6382>



##获取当前集群中所有节点的信息
127.0.0.1:6382> cluster nodes
6ebb4441ded1cfb4ce346e4349e155a685acdffd 192.168.234.10:6386@16386 master - 0 1693716720009 7 connected 0-5460
1ea11eda762c317ac5b9f398827c51085e553652 192.168.234.10:6381@16381 master,fail - 1693716449472 1693716444000 1 disconnected
0b1cfb29bc066c74a831a948e3c23f8dc6e0bbe6 192.168.234.10:6385@16385 slave 553a35ceea6fb2f0d2c668923d6650f65525a370 0 1693716719000 3 connected
553a35ceea6fb2f0d2c668923d6650f65525a370 192.168.234.10:6383@16383 master - 0 1693716721031 3 connected 10923-16383
f0a14e3d08738655dd7ed0b702187f7096f06bba 192.168.234.10:6382@16382 myself,master - 0 1693716720000 2 connected 5461-10922
dd03b2ff3629d360da59294c0b547849de41e8fb 192.168.234.10:6384@16384 slave f0a14e3d08738655dd7ed0b702187f7096f06bba 0 1693716722056 2 connected
127.0.0.1:6382>

在这里插入图片描述

还原之前的3主3从:

1、启动名为redis-node-1的Docker容器
[root@zyl-server ~]# docker start redis-node-1
redis-node-1
[root@zyl-server ~]#

2、获取当前集群中所有节点的信息

127.0.0.1:6382> cluster nodes
6ebb4441ded1cfb4ce346e4349e155a685acdffd 192.168.234.10:6386@16386 master - 0 1693716888112 7 connected 0-5460
1ea11eda762c317ac5b9f398827c51085e553652 192.168.234.10:6381@16381 slave 6ebb4441ded1cfb4ce346e4349e155a685acdffd 0 1693716888000 7 connected
0b1cfb29bc066c74a831a948e3c23f8dc6e0bbe6 192.168.234.10:6385@16385 slave 553a35ceea6fb2f0d2c668923d6650f65525a370 0 1693716887097 3 connected
553a35ceea6fb2f0d2c668923d6650f65525a370 192.168.234.10:6383@16383 master - 0 1693716889129 3 connected 10923-16383
f0a14e3d08738655dd7ed0b702187f7096f06bba 192.168.234.10:6382@16382 myself,master - 0 1693716887000 2 connected 5461-10922
dd03b2ff3629d360da59294c0b547849de41e8fb 192.168.234.10:6384@16384 slave f0a14e3d08738655dd7ed0b702187f7096f06bba 0 1693716886000 2 connected
127.0.0.1:6382>

在这里插入图片描述

3、停止上位的slave:6386,相当于给master:6381,上位机会

docker stop redis-node-6

4、获取当前集群中所有节点的信息

127.0.0.1:6382>  cluster nodes
6ebb4441ded1cfb4ce346e4349e155a685acdffd 192.168.234.10:6386@16386 master,fail - 1693717524807 1693717521000 7 disconnected
1ea11eda762c317ac5b9f398827c51085e553652 192.168.234.10:6381@16381 master - 0 1693717614888 8 connected 0-5460
0b1cfb29bc066c74a831a948e3c23f8dc6e0bbe6 192.168.234.10:6385@16385 slave 553a35ceea6fb2f0d2c668923d6650f65525a370 0 1693717614000 3 connected
553a35ceea6fb2f0d2c668923d6650f65525a370 192.168.234.10:6383@16383 master - 0 1693717612843 3 connected 10923-16383
f0a14e3d08738655dd7ed0b702187f7096f06bba 192.168.234.10:6382@16382 myself,master - 0 1693717615000 2 connected 5461-10922
dd03b2ff3629d360da59294c0b547849de41e8fb 192.168.234.10:6384@16384 slave f0a14e3d08738655dd7ed0b702187f7096f06bba 0 1693717615913 2 connected
127.0.0.1:6382>

在这里插入图片描述

5、重新启动6386

[root@zyl-server ~]# docker start redis-node-6
redis-node-6
[root@zyl-server ~]#

6、获取当前集群中所有节点的信息

127.0.0.1:6382> cluster nodes
6ebb4441ded1cfb4ce346e4349e155a685acdffd 192.168.234.10:6386@16386 slave 1ea11eda762c317ac5b9f398827c51085e553652 0 1693717773565 8 connected
1ea11eda762c317ac5b9f398827c51085e553652 192.168.234.10:6381@16381 master - 0 1693717772000 8 connected 0-5460
0b1cfb29bc066c74a831a948e3c23f8dc6e0bbe6 192.168.234.10:6385@16385 slave 553a35ceea6fb2f0d2c668923d6650f65525a370 0 1693717773000 3 connected
553a35ceea6fb2f0d2c668923d6650f65525a370 192.168.234.10:6383@16383 master - 0 1693717771000 3 connected 10923-16383
f0a14e3d08738655dd7ed0b702187f7096f06bba 192.168.234.10:6382@16382 myself,master - 0 1693717772000 2 connected 5461-10922
dd03b2ff3629d360da59294c0b547849de41e8fb 192.168.234.10:6384@16384 slave f0a14e3d08738655dd7ed0b702187f7096f06bba 0 1693717771547 2 connected
127.0.0.1:6382>

在这里插入图片描述

3.4 redis集群–读写error

1、进入redis-node-1set k1 v1

[root@zyl-server ~]# docker exec -it redis-node-1 /bin/bash

root@zyl-server:/data# redis-cli -p 6381
127.0.0.1:6381> set k1 v1
(error) MOVED 12706 192.168.234.10:6383
127.0.0.1:6381> set k2 v2
OK
127.0.0.1:6381> set k3 v3
OK
127.0.0.1:6381> set k4 v4
(error) MOVED 8455 192.168.234.10:6382
127.0.0.1:6381>

这个错误提示是因为尝试执行的命令被Redis集群转发到了错误的节点。在Redis集群中,不同的槽位可能分布在不同的节点上,并且某些命令需要在正确的节点上执行。

解决方法如下:使用-c 选项来启用集群模式

首先,使用redis-cli连接到Redis集群中的任意一个节点:redis-cli -c -h <任意一个节点IP地址> -p <任意一个节点端口>。
root@zyl-server:/data# redis-cli -p 6381 -c
127.0.0.1:6381> FLUSHALL  ##清空当前Redis节点上的所有数据
OK
127.0.0.1:6381>


2、使用了-c 选项来启用集群模式,后再set测试
在集群中,不同的键会根据其哈希值被分配到不同的槽位和节点上。

127.0.0.1:6381> set k1 v1
-> Redirected to slot [12706] located at 192.168.234.10:6383
OK
192.168.234.10:6383> set k2 v2
-> Redirected to slot [449] located at 192.168.234.10:6381
OK
192.168.234.10:6381> set k3 v3
OK
192.168.234.10:6381> set k4 v4
-> Redirected to slot [8455] located at 192.168.234.10:6382
OK
192.168.234.10:6382>"k1"被重定向到位于192.168.234.10:6383的槽位[12706]上。
键"k2"被重定向到位于192.168.234.10:6381的槽位[449]上。
键"k3"直接被设置在位于192.168.234.10:6381的节点上。
键"k4"被重定向到位于192.168.234.10:6382的槽位[8455]上。

3.5 redis集群–主从扩容案例(4主4从)

在原来3主3从基础上,变为4主4从,新增master:6387,slave:6388。

新建6387、6388两个节点+新建后启动+查看是否8节点。

1、创建两个Redis节点,并将它们加入到Redis集群中
docker run -d --name redis-node-7 --net host --privileged=true -v /data/redis/share/redis-node-7:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6387
docker run -d --name redis-node-8 --net host --privileged=true -v /data/redis/share/redis-node-8:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6388

-d参数表示以后台模式运行容器。
--name参数指定了容器的名称为"redis-node-7"--net host参数表示容器与主机共享网络命名空间,以便容器能够使用主机的网络。
--privileged=true参数授予容器特权级别,以便在容器中执行底层操作。
-v /data/redis/share/redis-node-7:/data参数将主机上的目录/data/redis/share/redis-node-7挂载到容器内的/data目录。这样可以持久化保存容器内的数据。
redis:7.0.9指定了使用的Redis镜像和版本。
--cluster-enabled yes表示启用Redis集群。
--appendonly yes表示启用AOF(Append Only File)持久化模式。
--port 6387表示将Redis节点的端口设置为63872、列出正在运行的Docker容器
docker ps
[root@zyl-server ~]# docker ps
CONTAINER ID   IMAGE         COMMAND                  CREATED         STATUS          PORTS     NAMES
d9a5a558f377   redis:6.0.8   "docker-entrypoint.s…"   5 seconds ago   Up 4 seconds              redis-node-8
26773aa52c7c   redis:6.0.8   "docker-entrypoint.s…"   6 seconds ago   Up 5 seconds              redis-node-7
51fa09a6a3e6   redis:6.0.8   "docker-entrypoint.s…"   11 hours ago    Up 38 minutes             redis-node-6
74faf0961119   redis:6.0.8   "docker-entrypoint.s…"   11 hours ago    Up 11 hours               redis-node-5
2bb58b50c70a   redis:6.0.8   "docker-entrypoint.s…"   11 hours ago    Up 11 hours               redis-node-4
9a0fd2b62b14   redis:6.0.8   "docker-entrypoint.s…"   11 hours ago    Up 11 hours               redis-node-3
cb67d2dfecd0   redis:6.0.8   "docker-entrypoint.s…"   11 hours ago    Up 11 hours               redis-node-2
59bcc7ed00e5   redis:6.0.8   "docker-entrypoint.s…"   11 hours ago    Up 53 minutes             redis-node-1
[root@zyl-server ~]#


3、进入6387容器实例内部
docker exec -it redis-node-7 /bin/bash


4、将新增的6387节点(空槽号)作为master节点加入原集群
redis-cli --cluster add-node 自己实际IP地址:6387 自己实际IP地址:6381
6387 就是将要作为master新增节点
6381 就是原来集群节点里面的领路人,相当于6387拜拜6381的码头从而找到组织加入集群

redis-cli --cluster add-node 192.168.234.10:6387 192.168.234.10:6381

root@zyl-server:/data# redis-cli --cluster add-node 192.168.234.10:6387 192.168.234.10:6381
>>> Adding node 192.168.234.10:6387 to cluster 192.168.234.10:6381
>>> Performing Cluster Check (using node 192.168.234.10:6381)
M: 1ea11eda762c317ac5b9f398827c51085e553652 192.168.234.10:6381
   slots:[0-5460] (5461 slots) master
   1 additional replica(s)
S: 0b1cfb29bc066c74a831a948e3c23f8dc6e0bbe6 192.168.234.10:6385
   slots: (0 slots) slave
   replicates 553a35ceea6fb2f0d2c668923d6650f65525a370
S: 6ebb4441ded1cfb4ce346e4349e155a685acdffd 192.168.234.10:6386
   slots: (0 slots) slave
   replicates 1ea11eda762c317ac5b9f398827c51085e553652
S: dd03b2ff3629d360da59294c0b547849de41e8fb 192.168.234.10:6384
   slots: (0 slots) slave
   replicates f0a14e3d08738655dd7ed0b702187f7096f06bba
M: f0a14e3d08738655dd7ed0b702187f7096f06bba 192.168.234.10:6382
   slots:[5461-10922] (5462 slots) master
   1 additional replica(s)
M: 553a35ceea6fb2f0d2c668923d6650f65525a370 192.168.234.10:6383
   slots:[10923-16383] (5461 slots) master
   1 additional replica(s)
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
>>> Getting functions from cluster
>>> Failed retrieving Functions from the cluster, skip this step as Redis version do not support function command (error = 'ERR unknown command `FUNCTION`, with args beginning with: `DUMP`, ')
>>> Send CLUSTER MEET to node 192.168.234.10:6387 to make it join the cluster.
[OK] New node added correctly.
root@zyl-server:/data#

在这里插入图片描述

5、检查集群情况第1次,6387没有任何键、槽位或从节点。
redis-cli --cluster check 192.168.234.10:6381

在这里插入图片描述

6、重新分派槽号
命令:redis-cli --cluster reshard IP地址:端口号

redis-cli --cluster reshard 192.168.234.10:6381

在这里插入图片描述

7、检查集群情况第2次

root@zyl-server:/data# redis-cli --cluster check 192.168.234.10:6381


在这里插入图片描述

为什么6387是3个新的区间,以前的槽位号还是连续?

重新分配成本太高,所以前3家各自匀出来一部分,从6381/6382/6383三个旧节点分别匀出1364个坑位给新节点6387。

8、为主节点6387分配从节点6388

命令:redis-cli --cluster add-node ip:新slave端口 ip:新master端口 --cluster-slave --cluster-master-id 新主机节点ID


redis-cli --cluster add-node 192.168.234.10:6388 192.168.234.10:6387 --cluster-slave --cluster-master-id a8a40f0db21abc2db2c159e9c7931d2a7acdc8f2  -------这个是6387的编号,按照自己实际情况

redis-cli --cluster add-node 192.168.234.10:6388 192.168.234.10:6387  --cluster-slave --cluster-master-id a8a40f0db21abc2db2c159e9c7931d2a7acdc8f2

在这里插入图片描述

9、检查集群情况第3次
redis-cli --cluster check 192.168.234.10:6381

在这里插入图片描述


redis集群--主从扩容案例(4主4从)——————成功!!!


3.6 redis集群–主从缩容案例(4主4从—>3主3从)

目的:6387和6388下线。

1、检查集群情况1获得6388的节点ID

redis-cli --cluster check 192.168.234.10:6388

a0abf90dbec7d33cb0cd3179cb5efb7e653a1a4c

2、将6388删除 ,从集群中将4号从节点6388删除

命令:redis-cli --cluster del-node ip:从机端口 从机6388节点ID

redis-cli --cluster del-node 192.168.234.10:6388 a0abf90dbec7d33cb0cd3179cb5efb7e653a1a4c

root@zyl-server:/data# redis-cli --cluster del-node 192.168.234.10:6388 a03a551fb6f8320ee404f07254e6c934beb52d7e
>>> Removing node a03a551fb6f8320ee404f07254e6c934beb52d7e from cluster 192.168.234.10:6388
>>> Sending CLUSTER FORGET messages to the cluster...
>>> Sending CLUSTER RESET SOFT to the deleted node.
root@zyl-server:/data#

3、再次检查集群
redis-cli --cluster check 192.168.234.10:6381

在这里插入图片描述

4、将6387的槽号清空,重新分配,本例将清出来的槽号都给6381
redis-cli --cluster reshard 192.168.234.10:6381

在这里插入图片描述

5、检查集群情况第二次
redis-cli --cluster check 192.168.234.10:6381

在这里插入图片描述

6、将6387删除
命令:redis-cli --cluster del-node ip:端口 6387节点ID

redis-cli --cluster del-node 192.168.234.10:6387 f0eea5b2dfe28c742b00bb660bb67a2d0ee30004


root@zyl-server:/data# redis-cli --cluster del-node 192.168.234.10:6387 f0eea5b2dfe28c742b00bb660bb67a2d0ee30004
>>> Removing node f0eea5b2dfe28c742b00bb660bb67a2d0ee30004 from cluster 192.168.234.10:6387
>>> Sending CLUSTER FORGET messages to the cluster...
>>> Sending CLUSTER RESET SOFT to the deleted node.
root@zyl-server:/data#


7、检查集群情况第三次
redis-cli --cluster check 192.168.234.10:6381

在这里插入图片描述


redis集群--主从缩容案例(4主4从--->3主3从)——————成功!!!


在这里插入图片描述


💖The End💖点点关注,收藏不迷路💖

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

eureka服务注册和服务发现

文章目录 问题实现以orderservice为例orderservice服务注册orderservice服务拉取 总结 问题 我们要在orderservice中根据查询到的userId来查询user&#xff0c;将user信息封装到查询到的order中。 一个微服务&#xff0c;既可以是服务提供者&#xff0c;又可以是服务消费者&a…

Python零基础超详细教程:字典(Dictionary)相关介绍使用

前言 嗨喽~大家好呀&#xff0c;这里是魔王呐 ❤ ~! Python字典是另一种可变容器模型&#xff0c; 且可存储任意类型对象&#xff0c;如字符串、数字、元组等其他容器模型。 python更多源码/资料/解答/教程等 点击此处跳转文末名片免费获取 一、创建字典 字典由键和对应值…

LNMP架构:搭建Discuz论坛

文章目录 1. 编译安装Nginx1.1 前置准备1.2 编译安装1.3 添加nginx系统服务 2.编译安装MySql2.1 前置准备2.2 编译安装2.3 修改mysql 配置文件2.4 设置路径环境变量2.5 初始化数据库2.6 添加musql系统服务2.7 修改MySql登录密码 3. 编译安装PHP3.1 前置准备3.2 编译安装3.3 复制…

IDEA打开一个项目时,idea左侧project模式下,不显示项目工程目录的解决方法

在IDEA打开一个一个已有的项目chapter3时&#xff0c;idea左侧project模式下&#xff0c;左侧也没有project按钮&#xff0c;如下问题截图&#xff1a;&#xff08;ps:项目结构可以显示&#xff0c;但是src等目录不见&#xff09; 在网上查了一些方法&#xff1a; 1、解决办法…

QT 界面相关操作

1> 创建自定义类时需要指定父类 2> 第一个界面的相关操作 #include "widget.h" #include<iostream> //printf #include<QDebug> //qDebuf #include<QIcon> //图标的头文件 using namespace std; //coutWidget::Widget(QWidget *…

外观模式:简化复杂子系统的访问与使用

文章目录 1. 简介2. 外观模式的基本结构3. 外观模式的实现步骤4. 外观模式的应用与实例4.1 图形界面库的外观模式应用4.2 文件压缩与解压缩的外观模式应用4.3 订单处理系统的外观模式应用 5. 外观模式的优缺点5.1 优点5.2 缺点 6. 总结 1. 简介 外观模式是一种结构型设计模式&…

微服务通信[HTTP|RPC同步通信、MQ异步通信]

概念 A服务调用B服务,B服务调C服务,C服务调D服务,即微服务之间的通信(也可以叫微服务之间的调用) HTTP同步通信 一种轻量级的通信协议,常用于在不同的微服务之间进行通信,也是最简单的通信方式使用REST ful为开发规范&#xff0c;将服务对外暴露的HTTP调用方式为REST API(如GET…

Python 没有 pip 包问题解决

最近需要搞一个干净的Python,从官网上直接下载解压可用的绿色版&#xff0c;发现无法正常使用PiP 一 官网下载Python https://www.python.org/downloads/ 选择 embeddable package,这种是免安装的包&#xff0c;解压后可以直接使用。 二 配置环境变量 添加环境变量&#xff1a…

肖sir__linux详解__001

linux详解: 1、ifconfig 查看ip地址 2、6版本&#xff1a;防火墙的命令&#xff1a; service iptables status 查看防火墙状态 service iptables statrt 开启防火墙 service iptables stop 关闭防火墙 service iptables restart 重启防火墙状态 7版本&#xff1a; systemctl s…

【leetcode 力扣刷题】数学题之计算次幂//次方:快速幂

利用乘法求解次幂问题—快速幂 50. Pow(x, n)372. 超级次方 50. Pow(x, n) 题目链接&#xff1a;50. Pow(x, n) 题目内容&#xff1a; 题目就是要求我们去实现计算x的n次方的功能函数&#xff0c;类似c的power()函数。但是我们不能使用power()函数直接得到答案&#xff0c;那…

纵行科技与山鹰绿能达成合作,提供物联网资产管理数据服务

近日&#xff0c;纵行科技与山鹰绿能宣布双方达成深度合作关系&#xff0c;纵行科技将为山鹰绿能提供专业的物联网技术服务&#xff0c;使用物联网技术帮助山鹰绿能对循环包装载具等资产进行在线管理和数字化运营。 据悉&#xff0c;山鹰绿能是一家由山鹰国际控股的全资子公司…

SpringCloud(十)——ElasticSearch简单了解(二)DSL查询语句及RestClient查询文档

文章目录 1. DSL查询文档1.1 DSL查询分类1.2 全文检索查询1.3 精确查询1.4 地理查询1.5 查询算分1.6 布尔查询1.7 结果排序1.8 分页查询1.9 高亮显示 2. RestClient查询文档2.1 查询全部2.2 其他查询语句2.3 排序和分页2.4 高亮显示 1. DSL查询文档 1.1 DSL查询分类 查询所有…

【图像分割】实现snake模型的活动轮廓模型以进行图像分割研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

机器人中的数值优化(七)——修正阻尼牛顿法

本系列文章主要是我在学习《数值优化》过程中的一些笔记和相关思考&#xff0c;主要的学习资料是深蓝学院的课程《机器人中的数值优化》和高立编著的《数值最优化方法》等&#xff0c;本系列文章篇数较多&#xff0c;不定期更新&#xff0c;上半部分介绍无约束优化&#xff0c;…

Ubuntu入门03——Ubuntu用户操作

1.Ubuntu如何进入root用户 进入ROOT用户的指令&#xff1a; Linux用su命令来切换用户&#xff1a; su root执行命令后&#xff0c;会提示你输入密码&#xff0c;而Ubuntu是没有设置root初始密码的。 若su命令不能切换root&#xff0c;提示su: Authentication failure&#x…

ASP.NET修改默认端口

找到发布目录下的appsettings.json文件 加入下面内容 "Kestrel":{"Endpoints": {"Https": {"Url": "https://*:8827"},"Http": {"Url": "http://*:8828"}}} 不使用https的话去掉https,修改…

二进制安全虚拟机Protostar靶场 安装,基础知识讲解,破解STACK ZERO

简介 pwn是ctf比赛的方向之一&#xff0c;也是门槛最高的&#xff0c;学pwn前需要很多知识&#xff0c;这里建议先去在某宝上买一本汇编语言第四版&#xff0c;看完之后学一下python和c语言&#xff0c;python推荐看油管FreeCodeCamp的教程&#xff0c;c语言也是 pwn题目大部…

【洛谷】P3853 路标设置

原题链接&#xff1a;https://www.luogu.com.cn/problem/P3853 目录 1. 题目描述 2. 思路分析 3. 代码实现 1. 题目描述 2. 思路分析 整体思路&#xff1a;二分答案 由题意知&#xff0c;公路上相邻路标的最大距离定义为该公路的“空旷指数”。在公路上增设一些路标&…

【ELK日志收集系统】

目录 一、概述 1.作用 2.为什么使用&#xff1f; 二、组件 1.elasticsearch 1.1 作用 1.2 特点 2.logstash 2.1 作用 2.2 工作过程 2.3 INPUT 2.4 FILETER 2.5 OUTPUTS 3.kibana 三、架构类型 1.ELK 2.ELKK 3.ELFK 4.ELFKK 四、案例 - 构建ELK集群 1.环境…

MFC网络编程简单例程

目录 一、关于网络的部分概念1 URL(网址)及URL的解析2 URL的解析3 域名及域名解析3 IP及子网掩码4 什么是Web服务器5 HTTP的基本概念6 Socket库概念7 协议栈8 Socket库收发数据基本步骤 二、基于TCP的网络应用程序三、基于UDP的网络应用程序 一、关于网络的部分概念 1 URL(网址…