Docker进阶:mysql 主从复制、redis集群3主3从【扩缩容案例】
温馨提示:这篇文章已超过382天没有更新,请注意相关的内容是否还可用!
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 Apache Tomcat/10.0.14 。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。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]# 写入内容:
醉颜凉的第一个web项目。
Hello Apache Tomcat/10.0.14
1.2 docker 指定安装 tomcat8.0
要下载特定版本的Tomcat镜像,可以在 docker pull 命令后面添加 : 参数。其中 制定了镜像的版本号。
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节点的端口号,例如6381、6382等。 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-1 为6台机器配置构建集群关系 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-1,set 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 -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节点的端口设置为6387。 2、列出正在运行的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💖点点关注,收藏不迷路💖
































