CentOS7双主四从的MySQL集群

CentOS7双主四从的MySQL集群

CentOS中搭建Docker环境

  1. 关闭SELINUX服务

    和很多程序冲突,找到/etc/sysconfig/selunux文件,把SELTNUX设置为disabled,保存重启CentOS

1
2
3
4
5
6
7
8
9
10
11
vi /etc/sysconfig/selinux

i键编辑

SELINUX=disabled

:w保存

:q退出

reboot重启

2.docker安装

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
yum update -y

yum install docker -y

// 启动docker
service docker start

service docker stop

// 查看镜像列表
docker images

// 删除某个镜像
docker rmi 镜像名字

// 列出Docker 容器
docker ps -a

// 停止mysql_1节点
docker stop mysql_1

// 启动mysql_1节点
docker start mysql_1

// 删除mysql_1节点
docker rm mysql_1

Linux的SSH服务软件

1.window MobaXterm

2.Mac Termius

双主四从的MySQL集群概念

一个高可用、高负载、高性能的“三高”MySQL集群,至少需要12个MySQL节点。

数据同步

单节点的MySQL抗风险性很差,就这么一个MySQL,如果遇上故障数据库挂了,项目没法用了,MySQL要有冗余节点。
既然要添加冗余节点,就必须借助于数据同步,保证两个MySQL节点数据完全一致。这样挂掉任何一个节点,另一个节点都能立即接替工作。MVSQL自带了Master-Slave数据同步模式,也被称作主从同步模式。例如MySQL A节点开启了binlog日志文件之后,MySQL A上面执行SQL语句(查询语句除外)都会被记录在binlog日志里面。MySQLB节点通过订阅MySQL A的binlog文件,能实时下载到这个日志文件,然后在MySQL B节点上运行这些SQL语句,于是就保证了自己的数据和MySQL A节点一致。

MySQL A被称作Master(主节点),MySQL B被称作Slave(从节点)。需要注意,主从同步模式里面,数据同步是单项的,如果你在MySQLA上写入数据,可以同步到MySQL B上面;如果在MySQL B上面写入数据,是不能同步到MySQL A节点的。假设MYSQL A挂了,MySQL B可以接替工作。但是如果MySQL A经过维修重新上线,MySQL A应该从MySQL B上同步数据,所以我们必须要给MySQL A和MySQL B设置双向主从同步,也就是互为主从节点。

读写分离

搭建MVSQL集群的时候,划定MVSQL1用来处理写任务,MySQL2和MySQL 3负责处理读请求。原来一个节点的处理所有SQL语句变成三个节点来分担,MSQL集群的读写性能比单节点MySQL是翻倍的,能并发执行的SQL语句条数也翻倍了。

如果MySQL 1宕机,MySQL 4可以接替MySQL1的工作。由于MySQL 2和MySQL 3是与MySQL 1同步,所以MySQL 1宕机之后,MySQL 2和MySQL 3的数据也就不能同步了。况且MySQL 2和MySQL 3不能自动切换到与MySQL 4同步。因此我们要给MySQL 4配置上两个读节点:MySQL 5和MySQL 6。也就是说MySQL 4接替MySQL1的时候,要用自己的两个从节点。相反MySQL 4宕机,MySQL1也是用自己的两个从节点。

数据切分

因为MySQL数据库单表数据量如果超过两千万,该表的读写性能会急剧下降,所以我们要做数据切分,俗称分库分表。比如说一个中型电商网站,每天能产生2万笔订单,算下来10年间大概会有7300万条订单记录。单节点MySQL单表保存这么多记录肯定吃不消,所以我们可以用10个MySQL节点共同承担数据存储任务。每个MySQL节点只存储730万条订单记录,压力并不大。
怎么能把7300万条记录切分存储到10个MVSQL节点上呢?其实有很多种算法,最简单的是按照主键求余数切分比如说每个订单记录的主键值对10求余数,余数范围是0~9之间。如果余数是0,这个INSERT语句被MyCat发送给MVSQL1执行;余数是1,INSERT语句被发送给MVSQL2执行,然后以此类推,由于每个MSQL节点可以被称作分片,所以我们可以说成数据被切分到10个分片之中。

如果每个分片都要用6个MySQL节点,10个分片总共就得用60个MySQL节点。对于一个中型电商网站来说,数据库集群的成本还能接受。也许有的同学担心日积月累,20年之后10个分片肯定也不够用,到时候应该怎么做呢?这个也不复杂,有两个办法。其一是做扩容,比如说再增加10个分片。增加分片就牵扯到数据重新切分,数据迁移的时间成本还是很高的。不到万不得已,一般不添加分片。其二是定期缩表,就是把几年前的数据迁移到MongoDB或者HBase这样的大数据库平台上面,它们保存PB级数据都毫无压力。我们只在MySQL集群中保存最近今年的数据,这样就能缓解数据存储的压力了。

为什么使用MySQL5.7版本?

因为MVSQL8.0的主从同步功能做的不好,MSQL宕机重新上线之后,数据不能自动同步,需要人工对比日志和维护,才能重新实现数据同步。比如MySQL1和MySQL2为双向主从同步,如果MySQL1宕机了两个小时,经过检查维修之后重新上线,按理说MySQL1应该自动去同步MySQL 2的数据。但是8.0版本的MySQL偏偏不行人工对比两个数据库之间日志的差异,然后执行若干的命令才能让MySQL 1成功同步到MySQL 2。如果MySQL 2一直不断的有新数据写入,人工核对日志的速度远远赶不上数据写入的速度,就只纰掉业务系统了。这么看来,一个宕机的MySQL节点想要重新上线,代价就是停掉前后端业务系统,这个成才
不应该盲目的追求MySQL新版本,稳定省心的MySQL5.7才是最佳方案,而且MySQL5.同样支持JSON字段类型,我们可以放心的使用。

为什么使用MyCat管理数据库集群

管理MySQL集群可以选用很多种中间件方案,比如说 myÇat、shardingsphere、proxysQL,MyCat是很老的中间件产品了,而且版本更新也不是很快,还不如选用 shardingsphere 呢。shardingSphere做数据切分的。如果不需要数据切分,只需要主从同步和读写分离就够了。shardingsphere 恰恰对这两块支持的特别不好。

搭建双主四从的MySQL集群

先创建一个自定义网络(子网段要和下面的 IP 对应):
1
docker network create --subnet=172.18.0.0/16 mynet
创建容器 mysql_1 主节点
1
2
3
4
5
6
7
8
9
10
docker run -it -d --name mysql_1 \
-p 7001:3306 \
--net mynet --ip 172.18.0.2 \
-m 400m \
-v /root/mysql_1/data:/var/lib/mysql \
-v /root/mysql_1/config:/etc/mysql/conf.d \
-e MYSQL_ROOT_PASSWORD=abc123456 \
-e TZ=Asia/Shanghai \
--privileged=true \
mysql:5.7 --lower_case_table_names=1
  • docker run :创建并运行一个新容器
  • -it :交互式 + 伪终端(通常用来保持终端连接,搭配 -d 一起用其实没啥作用)
  • -d :后台运行容器(detached 模式)
  • –name mysql_1 :容器的名字叫 mysql_1
  • -p 7001:3306 把宿主机的 7001 端口 映射到容器的 3306 端口(MySQL 默认端口)
  • –net mynet :让容器加入一个用户自定义网络 mynet
  • -m 400m 限制这个容器最多使用 400MB 内存,避免单个容器占用太多宿主机资源。
  • -v 宿主机目录:容器目录 :做数据卷映射。
  • /root/mysql_1/data:/var/lib/mysql :把 MySQL 的数据文件存放在宿主机。/root/mysql_1/data,实现数据持久化,容器删掉数据不会丢。
  • /root/mysql_1/config:/etc/mysql/conf.d :把宿主机的配置目录挂载到容器,让你在宿主机写配置文件(如 my.cnf)直接生效。
  • MYSQL_ROOT_PASSWORD=abc123456 :初始化 root 用户的密码。
  • TZ=Asia/Shanghai :设置容器时区为上海(中国标准时间)。
  • –privileged=true 让容器获得宿主机的 特权模式,几乎等同于 root 权限。
  • mysql:5.7 :使用官方 MySQL 5.7 镜像。
  • –lower_case_table_names=1 :强制 MySQL 表名不区分大小写(在 Linux 默认是区分大小写的)。
在Navicat上面给MySQL_1创建一个新账户,将来给MySQL_2和MySQL_3的从节点订阅binglog日志的使用用这个账户登录MySQL_1节点
1
2
3
4
5
6
7
8
9
10
11
12
13
用户名 sync
主机 %
插件 mysql_native_password
密码
确认密码
密码过期策略 DEFAULT

服务器权限
Reload
Replication Slave
Super

点击保存
my.cnf文件配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
[mysqld]
#数据库字符集
character-set-server=utf8
#唯一ID,集群里不能重复
server-id=1

#开启binlog日志,规定日志文件名称
log_bin=mysql-bin
#开启relaylog日志,规定日志文件名称
relay_log=relay-bin
#从库的写操作是否写入binlog日志
log_slave_updates=1
#采用严格的SQL模式
sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
创建容器 mysql_2 从节点(mysql_1的从节点)
1
2
3
4
5
6
7
8
9
10
docker run -it -d --name mysql_2 \
-p 7002:3306 \
--net mynet --ip 172.18.0.3 \
-m 400m \
-v /root/mysql_2/data:/var/lib/mysql \
-v /root/mysql_2/config:/etc/mysql/conf.d \
-e MYSQL_ROOT_PASSWORD=abc123456 \
-e TZ=Asia/Shanghai \
--privileged=true \
mysql:5.7 --lower_case_table_names=1
my.cnf文件配置

log_bin=mysql-bin 将来挂在更多读节点而准备的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[mysqld]
#数据库字符集
character-set-server=utf8
#唯一ID,集群里不能重复
server-id=2

#开启binlog日志,规定日志文件名称
log_bin=mysql-bin
#开启relaylog日志,规定日志文件名称
relay_log=relay-bin
#限制普通用户无法INSERT、UPDATE、DELETE等操作,但对改配置对管理员无效
read_only=1
#采用严格的SQL模式
sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES

1
2
3
4
5
6
7
8
9
10
11
#停止数据同步服务
stop slave;

#设置与MySQL 1同步数据
change master to master_host='172.18.0.2',master_port=3306,master_user='sync',master_password='abc123456'

#开启数据同步服务
start slave;

#查询数据同步状态
show slave status;

如果SQL语句执行结果中出现两个YES,说明主从同步就配置成功了。如果不成功,你就再检查上述的步骤,然后重新运行这几行SQL语句。或者先停掉容器,再删除容器和映射到 /root 目录的mysql目录,重新创建容器,严格遵守每个配置步骤,重新弄一遍主从同步。

创建容器 mysql_3 从节点(mysql_1的从节点)
1
2
3
4
5
6
7
8
9
10
docker run -it -d --name mysql_3 \
-p 7003:3306 \
--net mynet --ip 172.18.0.4 \
-m 400m \
-v /root/mysql_3/data:/var/lib/mysql \
-v /root/mysql_3/config:/etc/mysql/conf.d \
-e MYSQL_ROOT_PASSWORD=abc123456 \
-e TZ=Asia/Shanghai \
--privileged=true \
mysql:5.7 --lower_case_table_names=1
my.cnf文件配置

log_bin=mysql-bin 将来挂在更多读节点而准备的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[mysqld]
#数据库字符集
character-set-server=utf8
#唯一ID,集群里不能重复
server-id=3

#开启binlog日志,规定日志文件名称
log_bin=mysql-bin
#开启relaylog日志,规定日志文件名称
relay_log=relay-bin
#限制普通用户无法INSERT、UPDATE、DELETE等操作,但对改配置对管理员无效
read_only=1
#采用严格的SQL模式
sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES

创建容器 mysql_4 主节点
1
2
3
4
5
6
7
8
9
10
docker run -it -d --name mysql_4 \
-p 7004:3306 \
--net mynet --ip 172.18.0.5 \
-m 400m \
-v /root/mysql_4/data:/var/lib/mysql \
-v /root/mysql_4/config:/etc/mysql/conf.d \
-e MYSQL_ROOT_PASSWORD=abc123456 \
-e TZ=Asia/Shanghai \
--privileged=true \
mysql:5.7 --lower_case_table_names=1
my.cnf文件配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
[mysqld]
#数据库字符集
character-set-server=utf8
#唯一ID,集群里不能重复
server-id=4

#开启binlog日志,规定日志文件名称
log_bin=mysql-bin
#开启relaylog日志,规定日志文件名称
relay_log=relay-bin
#从库的写操作是否写入binlog日志
log_slave_updates=1
#采用严格的SQL模式
sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
创建容器 mysql_5 从节点(mysql_4的从节点)
1
2
3
4
5
6
7
8
9
10
docker run -it -d --name mysql_5 \
-p 7005:3306 \
--net mynet --ip 172.18.0.6 \
-m 400m \
-v /root/mysql_5/data:/var/lib/mysql \
-v /root/mysql_5/config:/etc/mysql/conf.d \
-e MYSQL_ROOT_PASSWORD=abc123456 \
-e TZ=Asia/Shanghai \
--privileged=true \
mysql:5.7 --lower_case_table_names=1
my.cnf文件配置

log_bin=mysql-bin 将来挂在更多读节点而准备的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[mysqld]
#数据库字符集
character-set-server=utf8
#唯一ID,集群里不能重复
server-id=5

#开启binlog日志,规定日志文件名称
log_bin=mysql-bin
#开启relaylog日志,规定日志文件名称
relay_log=relay-bin
#限制普通用户无法INSERT、UPDATE、DELETE等操作,但对改配置对管理员无效
read_only=1
#采用严格的SQL模式
sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES

1
2
3
4
5
6
7
8
9
10
11
#停止数据同步服务
stop slave;

#设置与MySQL 1同步数据
change master to master_host='172.18.0.5',master_port=3306,master_user='sync',master_password='abc123456'

#开启数据同步服务
start slave;

#查询数据同步状态
show slave status;
创建容器 mysql_6 从节点(mysql_4的从节点)
1
2
3
4
5
6
7
8
9
10
docker run -it -d --name mysql_6 \
-p 7006:3306 \
--net mynet --ip 172.18.0.7 \
-m 400m \
-v /root/mysql_6/data:/var/lib/mysql \
-v /root/mysql_6/config:/etc/mysql/conf.d \
-e MYSQL_ROOT_PASSWORD=abc123456 \
-e TZ=Asia/Shanghai \
--privileged=true \
mysql:5.7 --lower_case_table_names=1
my.cnf文件配置

log_bin=mysql-bin 将来挂在更多读节点而准备的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[mysqld]
#数据库字符集
character-set-server=utf8
#唯一ID,集群里不能重复
server-id=6

#开启binlog日志,规定日志文件名称
log_bin=mysql-bin
#开启relaylog日志,规定日志文件名称
relay_log=relay-bin
#限制普通用户无法INSERT、UPDATE、DELETE等操作,但对改配置对管理员无效
read_only=1
#采用严格的SQL模式
sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES

配置双向主从同步

1.配置MySQL_1节点,到MySQL_1执行4条SQL语句。以MySQL_4为主节点,订阅日志同步数据。

1
2
3
4
5
6
7
8
9
10
11
#停止数据同步服务
stop slave;

#设置与MySQL 1同步数据
change master to master_host='172.18.0.5',master_port=3306,master_user='sync',master_password='abc123456'

#开启数据同步服务
start slave;

#查询数据同步状态
show slave status;

2.配置MySQL_4节点

1
2
3
4
5
6
7
8
9
10
11
#停止数据同步服务
stop slave;

#设置与MySQL 1同步数据
change master to master_host='172.18.0.2',master_port=3306,master_user='sync',master_password='abc123456'

#开启数据同步服务
start slave;

#查询数据同步状态
show slave status;

MyCat管理数据库集群

要用于实现 MySQL 的读写分离、分库分表、多数据源整合等功能。

这是一个基于 MyCat 1.6.7.4 版本构建的镜像,适用于 Linux/amd64 架构
1
docker pull liuyi71sinacom/mycat:1.6.7.4
docker 启动 MyCat 容器
1
2
3
4
5
6
7
8
docker run -d \
--name mycat \
--net mynet --ip 172.18.0.8 \
-p 8066:8066 -p 9066:9066 \
-v /root/mycat/conf:/usr/local/mycat/conf \
-v /root/mycat/logs:/usr/local/mycat/logs \
-e TZ=Asia/Shanghai \
liuyi71sinacom/mycat:1.6.7.4
确认宿主机配置目录

1.查看

1
ls -l /root/mycat/conf

2.获取默认 wrapper.conf

1
2
3
4
5
6
7
8
docker run --name mycat_temp -it liuyi71sinacom/mycat:1.6.7.4 /bin/bash

cd /usr/local/mycat/conf
ls # 应该能看到 wrapper.conf, server.xml, schema.xml
exit

docker cp mycat_temp:/usr/local/mycat/conf /root/mycat/conf
docker rm -f mycat_temp

这样 /root/mycat/conf 就有完整的默认配置

3.自定义 server.xml 和 schema.xml

server.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
<?xml version="1.0" encoding="UTF-8"?>
<!-- - - Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License. - You
may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0
- - Unless required by applicable law or agreed to in writing, software -
distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the
License for the specific language governing permissions and - limitations
under the License. -->
<!DOCTYPE mycat:server SYSTEM "server.dtd">
<mycat:server xmlns:mycat="http://io.mycat/">
<system>
<property name="nonePasswordLogin">0</property> <!-- 0为需要密码登陆、1为不需要密码登陆 ,默认为0,设置为1则需要指定默认账户-->
<property name="ignoreUnknownCommand">0</property><!-- 0遇上没有实现的报文(Unknown command:),就会报错、1为忽略该报文,返回ok报文。
在某些mysql客户端存在客户端已经登录的时候还会继续发送登录报文,mycat会报错,该设置可以绕过这个错误-->
<property name="useHandshakeV10">1</property>
<property name="removeGraveAccent">1</property>
<property name="useSqlStat">0</property> <!-- 1为开启实时统计、0为关闭 -->
<property name="useGlobleTableCheck">0</property> <!-- 1为开启全加班一致性检测、0为关闭 -->
<property name="sqlExecuteTimeout">300</property> <!-- SQL 执行超时 单位:秒-->
<property name="sequnceHandlerType">1</property>
<!--<property name="sequnceHandlerPattern">(?:(\s*next\s+value\s+for\s*MYCATSEQ_(\w+))(,|\)|\s)*)+</property>
INSERT INTO `travelrecord` (`id`,user_id) VALUES ('next value for MYCATSEQ_GLOBAL',"xxx");
-->
<!--必须带有MYCATSEQ_或者 mycatseq_进入序列匹配流程 注意MYCATSEQ_有空格的情况-->
<property name="sequnceHandlerPattern">(?:(\s*next\s+value\s+for\s*MYCATSEQ_(\w+))(,|\)|\s)*)+</property>
<property name="subqueryRelationshipCheck">false</property> <!-- 子查询中存在关联查询的情况下,检查关联字段中是否有分片字段 .默认 false -->
<property name="sequenceHanlderClass">io.mycat.route.sequence.handler.HttpIncrSequenceHandler</property>
<!-- <property name="useCompression">1</property>--> <!--1为开启mysql压缩协议-->
<!-- <property name="fakeMySQLVersion">5.6.20</property>--> <!--设置模拟的MySQL版本号-->
<!-- <property name="processorBufferChunk">40960</property> -->
<!--
<property name="processors">1</property>
<property name="processorExecutor">32</property>
-->
<!--默认为type 0: DirectByteBufferPool | type 1 ByteBufferArena | type 2 NettyBufferPool -->
<property name="processorBufferPoolType">0</property>
<!--默认是65535 64K 用于sql解析时最大文本长度 -->
<!--<property name="maxStringLiteralLength">65535</property>-->
<!--<property name="sequnceHandlerType">0</property>-->
<!--<property name="backSocketNoDelay">1</property>-->
<!--<property name="frontSocketNoDelay">1</property>-->
<!--<property name="processorExecutor">16</property>-->
<!--
<property name="serverPort">8066</property> <property name="managerPort">9066</property>
<property name="idleTimeout">300000</property> <property name="bindIp">0.0.0.0</property>
<property name="dataNodeIdleCheckPeriod">300000</property> 5 * 60 * 1000L; //连接空闲检查
<property name="frontWriteQueueSize">4096</property> <property name="processors">32</property> -->
<!--分布式事务开关,0为不过滤分布式事务,1为过滤分布式事务(如果分布式事务内只涉及全局表,则不过滤),2为不过滤分布式事务,但是记录分布式事务日志-->
<property name="handleDistributedTransactions">0</property>

<!--
off heap for merge/order/group/limit 1开启 0关闭
-->
<property name="useOffHeapForMerge">0</property>

<!--
单位为m
-->
<property name="memoryPageSize">64k</property>

<!--
单位为k
-->
<property name="spillsFileBufferSize">1k</property>

<property name="useStreamOutput">0</property>

<!--
单位为m
-->
<property name="systemReserveMemorySize">384m</property>


<!--是否采用zookeeper协调切换 -->
<property name="useZKSwitch">false</property>

<!-- XA Recovery Log日志路径 -->
<!--<property name="XARecoveryLogBaseDir">./</property>-->

<!-- XA Recovery Log日志名称 -->
<!--<property name="XARecoveryLogBaseName">tmlog</property>-->
<!--如果为 true的话 严格遵守隔离级别,不会在仅仅只有select语句的时候在事务中切换连接-->
<property name="strictTxIsolation">false</property>

<property name="useZKSwitch">true</property>
<!--如果为0的话,涉及多个DataNode的catlet任务不会跨线程执行-->
<property name="parallExecute">0</property>
</system>

<!-- 全局SQL防火墙设置 -->
<!--白名单可以使用通配符%或着*-->
<!--例如<host host="127.0.0.*" user="root"/>-->
<!--例如<host host="127.0.*" user="root"/>-->
<!--例如<host host="127.*" user="root"/>-->
<!--例如<host host="1*7.*" user="root"/>-->
<!--这些配置情况下对于127.0.0.1都能以root账户登录-->
<!--
<firewall>
<whitehost>
<host host="1*7.0.0.*" user="root"/>
</whitehost>
<blacklist check="false">
</blacklist>
</firewall>
-->

<user name="root" defaultAccount="true">
<property name="password">abc123456</property>
<property name="schemas">his</property>
<property name="defaultSchema">his</property>
<!--No MyCAT Database selected 错误前会尝试使用该schema作为schema,不设置则为null,报错 -->

<!-- 表级 DML 权限设置 -->
<!--
<privileges check="false">
<schema name="TESTDB" dml="0110" >
<table name="tb01" dml="0000"></table>
<table name="tb02" dml="1111"></table>
</schema>
</privileges>
-->
</user>

<!-- <user name="user">
<property name="password">user</property>
<property name="schemas">TESTDB</property>
<property name="readOnly">true</property>
<property name="defaultSchema">TESTDB</property>
</user> -->

</mycat:server>

schema.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
<schema name="his" checkSQLschema="true" sqlMaxLimit="100" randomDataNode="dn1">
<table name="tb_action" primaryKey="id" dataNode="dn1" type="global" />
<table name="tb_customer" primaryKey="id" dataNode="dn1" type="global" />
<table name="tb_dept" primaryKey="id" dataNode="dn1" type="global" />
<table name="tb_goods" primaryKey="id" dataNode="dn1" type="global" />
<table name="tb_module" primaryKey="id" dataNode="dn1" type="global" />
<table name="tb_permission" primaryKey="id" dataNode="dn1" type="global" />
<table name="tb_role" primaryKey="id" dataNode="dn1" type="global" />
<table name="tb_user" primaryKey="id" dataNode="dn1" type="global" />
<table name="tb_rule" primaryKey="id" dataNode="dn1" type="global" />
<table name="tb_order" primaryKey="id" dataNode="dn1" type="global" />
<table name="tb_appointment" primaryKey="id" dataNode="dn1" type="global" />
<table name="tb_appointment_restriction" primaryKey="id" dataNode="dn1" type="global" />
<table name="tb_system" primaryKey="id" dataNode="dn1" type="global" />
<table name="tb_checkup_report" primaryKey="id" dataNode="dn1" type="global" />
<table name="tb_customer_location" primaryKey="id" dataNode="dn1" type="global" />
<table name="tb_flow_regulation" primaryKey="id" dataNode="dn1" type="global" />
<table name="tb_customer_im" primaryKey="id" dataNode="dn1" type="global" />
</schema>

<dataNode name="dn1" dataHost="dh1" database="his"/>

<dataHost name="dh1" maxCon="1000" minCon="10" balance="1" writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
<heartbeat>select 1</heartbeat>

<!-- 主节点1 -->
<writeHost host="w1" url="172.18.0.2:3306" user="root" password="abc123456">
<readHost host="w1r1" url="172.18.0.3:3306" user="root" password="abc123456"/>
<readHost host="w1r2" url="172.18.0.4:3306" user="root" password="abc123456"/>
</writeHost>

<!-- 主节点2 -->
<writeHost host="w2" url="172.18.0.5:3306" user="root" password="abc123456">
<readHost host="w2r1" url="172.18.0.6:3306" user="root" password="abc123456"/>
<readHost host="w2r2" url="172.18.0.7:3306" user="root" password="abc123456"/>
</writeHost>

</dataHost>
</mycat:schema>

Redis

1
2
3
4
5
6
7
8
9
10
11
12
docker pull redis:6.0.10


docker run -d \
--name redis \
-p 6379:6379 \
--net mynet \
--ip 172.18.0.9 \
-v /root/redis/conf:/usr/local/etc/redis \
-e TZ=Asia/Shanghai \
-m 400m \
redis:6.0.10 redis-server /usr/local/etc/redis/redis.conf

/root/redis/conf/redis.conf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
bind 0.0.0.0
protected-mode yes
port 6379
tcp-backlog 511
timeout 0
tcp-keepalive 0
loglevel notice
logfile ""
databases 4
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb
dir ./
requirepass abc123456

MongoDB

1
2
3
4
5
6
7
8
9
10
11
12
13
14
docker pull mongo:4.4.7


docker run -d \
--name mongo \
-p 27017:27017 \
--net mynet \
--ip 172.18.0.10 \
-v /root/mongo:/etc/mongo \
-v /root/mongo/data/db:/data/db \
-e MONGO_INITDB_ROOT_USERNAME=root \
-e MONGO_INITDB_ROOT_PASSWORD=abc123456 \
-m 800m \
mongo:4.4.7 --config /etc/mongo/mongod.conf

/root/mongo/mongod.conf

1
2
3
4
5
6
7
8
9
net:
port: 27017
bindIp: "0.0.0.0"

storage:
dbPath: "/data/db"

security:
authorization: "enabled"

RabbitMQ

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
docker pull rabbitmq:3.8.9-management

docker run -it -d \
--name mq \
-p 4369:4369 \
-p 5671:5671 \
-p 5672:5672 \
-p 15672:15672 \
--net mynet \
--ip 172.18.0.11 \
-m 400m \
-e RABBITMQ_DEFAULT_USER=admin \
-e RABBITMQ_DEFAULT_PASS=abc123456 \
-e TZ=Asia/Shanghai \
rabbitmq:3.8.9-management

访问 Web 管理界面:

通过浏览器访问 http://<宿主机的IP>:15672,例如 http://localhost:15672。

默认的登录凭据是:

用户名:admin

密码:abc123456

minio

一款高性能的对象存储解决方案,在文件存储场景中被广泛采用,主要源于其独特的技术特性和优势,尤其适合现代云原生架构和大规模数据存储需求。

1
docker pull minio/minio

创建/root/minio/data文件夹,然后设置文件夹权限,不然无法存储文件。

1
chmod -R 777 /root/minio/data
1
2
3
4
5
6
7
8
9
10
11
12
docker run -d \
--name minio \
-p 9000:9000 \
-p 9001:9001 \
--net mynet \
--ip 172.18.0.12 \
-m 400m \
-e TZ=Asia/Shanghai \
-e MINIO_ROOT_USER="root" \
-e MINIO_ROOT_PASSWORD="abc123456" \
-v /root/minio/data:/data \
minio/minio server /data --console-address ":9001"

http://localhost:9001/ 访问管理页面