分布式:实例
redis存储数据,可以使得数据扩容
node1中我们存储了1-10000的数据,并且我们保存了10000-20000的备份
node2中我们存储了10000-20000的数据,并且我们保存了30000-40000的备份
node3中我们存储了30000-40000的数据,并且我们保存了1-10000的备份
MySQL-MMM 是 Master-Master Replication Manager for MySQL(mysql 主主复制管理 器)的简称,是 Google 的开源项目 (Perl 脚本)。MMM 基于 MySQL Replication 做的扩展架构,主要用 来监控 mysql 主主复制并做失败转 移。其原理是将真实数据库节点的 IP(RIP)映射为虚拟 IP(VIP)集。 mysql-mmm 的监管端会提供多个 虚拟 IP(VIP),包括一个可写 VIP, 多个可读 VIP,通过监管的管理,这 些 IP 会绑定在可用 mysql 之上,当 某一台 mysql 宕机时,监管会将 VIP 迁移至其他 mysql。在整个监管过 程中,需要在 mysql 中添加相关授 权用户,以便让 mysql 可以支持监 理机的维护。授权的用户包括一个
mmm_monitor 用户和一个 mmm_agent 用户,如果想使用 mmm 的备份工具则还要添 加一个 mmm_tools 用户。
目前在 MySQL 高可用方面是一个相对成熟的解决方案, 由日本 DeNA 公司 youshimaton(现就职于 Facebook 公司)开发,是一套优秀的作为 MySQL高可用性环境下故障切换和主从提升的高可用软件。在MySQL故障切换过程中, MHA 能做到在 0~30 秒之内自动完成数据库的故障切换操作(以 2019 年的眼光来说太 慢了),并且在进行故障切换的过程中,MHA 能在最大程度上保证数据的一致性,以 达到真正意义上的高可用。
InnoDB Cluster 支持自动 Failover、强一致性、读写分离、读库高可用、读请求负载均 衡,横向扩展的特性,是比较完备的一套方案。但是部署起来复杂,想要解决 router 单点问题好需要新增组件,如没有其他更好的方案可考虑该方案。 InnoDB Cluster 主 要由 MySQL Shell、MySQL Router 和 MySQL 服务器集群组成,三者协同工作,共同为 MySQL 提供完整的高可用性解决方案。MySQL Shell 对管理人员提供管理接口,可以 很方便的对集群进行配置和管理,MySQL Router 可以根据部署的集群状况自动的初始 化,是客户端连接实例。如果有节点 down 机,集群会自动更新配置。集群包含单点写 入和多点写入两种模式。在单主模式下,如果主节点 down 掉,从节点自动替换上来, MySQL Router 会自动探测,并将客户端连接到新节点。
--mysql集群主从备份----------------------------------------------------------start---
# 第一步:创建主库
## 1、下载 mysql 镜像
## 2、创建 Master 实例并启动
docker run -p 3307: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=root -d mysql:5.7
### 参数说明:
### -p 3307:3306:将容器的 3306 端口映射到主机的 3307 端口
### -v /mydata/mysql/master/conf:/etc/mysql:将配置文件夹挂在到主机
### -v /mydata/mysql/master/log:/var/log/mysql:将日志文件夹挂载到主机
### -v /mydata/mysql/master/data:/var/lib/mysql/:将配置文件夹挂载到主机
### -e MYSQL_ROOT_PASSWORD=root:初始化 root 用户的密码
## 3、修改 master 基本配置 具体内容在下方,
## 注意:`skip-name-resolve 一定要加,不然连接 mysql 会超级慢`
vim /mydata/mysql/master/conf/my.cnf
[client] default-character-set=utf8
[mysql] default-character-set=utf8
[mysqld]
init_connect='SET collation_connection = utf8_unicode_ci'
init_connect='SET NAMES utf8'
character-set-server=utf8
collation-server=utf8_unicode_ci
skip-character-set-client-handshake
skip-name-resolve
## 4、添加 master 主从复制部分配置 具体内容在下方
vi /mydata/mysql/slaver/conf/my.cnf
##内容:
server_id=1
log-bin=mysql-bin
read-only=0
binlog-do-db=gulimall_ums
binlog-do-db=gulimall_pms
binlog-do-db=gulimall_oms
binlog-do-db=gulimall_sms
binlog-do-db=gulimall_wms
binlog-do-db=gulimall_admin
replicate-ignore-db=mysql
replicate-ignore-db=sys
replicate-ignore-db=information_schema
replicate-ignore-db=performance_schema
## 5、重启 master
docker ps
docker restart mysql-master
--------------------------------
# 第二步:创建从库
## 2、创建Slave实例
docker run -p 3317:3306 --name mysql-slaver-01 -v /mydata/mysql/slaver/log:/var/log/mysql -v /mydata/mysql/slaver/data:/var/lib/mysql -v /mydata/mysql/slaver/conf:/etc/mysql -e MYSQL_ROOT_PASSWORD=root -d mysql:5.7
## 3、修改 slave 基本配置
vi /mydata/mysql/slaver/conf/my.cnf
[client] default-character-set=utf8
[mysql] default-character-set=utf8
[mysqld]
init_connect='SET collation_connection = utf8_unicode_ci'
init_connect='SET NAMES utf8'
character-set-server=utf8
collation-server=utf8_unicode_ci
skip-character-set-client-handshake
skip-name-resolve
## 4、添加 Slave主从复制部分配置
server_id=2
log-bin=mysql-bin
read-only=1
binlog-do-db=gulimall_ums
binlog-do-db=gulimall_pms
binlog-do-db=gulimall_oms
binlog-do-db=gulimall_sms
binlog-do-db=gulimall_wms
binlog-do-db=gulimall_admin
replicate-ignore-db=mysql
replicate-ignore-db=sys
replicate-ignore-db=information_schema
replicate-ignore-db=performance_schema
## 5、重启 slaver
docker ps
docker restart mysql-slaver-01
------------------------------------------
# 第三步:配置 master 授权用户来他的同步数据
docker ps
## 1、进入 master 容器
docker exec -it mysql-master /bin/bash
## 2、进入 mysql 内部 (mysql –uroot -p)密码是(上一步下载镜像的时候设置的):root
mysql -uroot -p
### 1)、授权 root 可以远程访问( 主从无关,为了方便我们远程连接 mysql)
grant all privileges on *.* to 'root'@'%' identified by 'root' with grant option; flush privileges;
### 2)、添加用来同步的用户
GRANT REPLICATION SLAVE ON *.* to 'backup'@'%' identified by '123456';
## 3、查看 master 状态
show master status\G;
show master status;
## 结果
+------------------+----------+---------------------------------------------------------------------------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+---------------------------------------------------------------------------------+------------------+-------------------+
| mysql-bin.000001 | 889 | gulimall_ums,gulimall_pms,gulimall_oms,gulimall_sms,gulimall_wms,gulimall_admin | | |
+------------------+----------+---------------------------------------------------------------------------------+------------------+-------------------+
File:二进制文件 Position 更新的开始位置 Binlog_Do_DB 需要同步的库 Binlog_Ignore_DB 不需要同步的库,我们设置了,可能默认就是不同步系统的库
exit;
exit;
------------------------------------------
# 第四步:配置 slaver 同步 master 数据
## 1、进入 slaver 容器
docker ps
docker exec -it mysql-slaver-01 /bin/bash
## 2、进入 mysql 内部 (mysql –uroot -p)密码是(上一步下载镜像的时候设置的):root
mysql -uroot -p
### 1)、授权 root 可以远程访问( 主从无关,为了方便我们远程连接 mysql)
grant all privileges on *.* to 'root'@'%' identified by 'root' with grant option; flush privileges;
### 2)、设置主库连接master_host='192.168.3.124',master_user='backup',master_password='123456',master_log_file='mysql-bin.000001',master_log_pos=0,master_port=3307
### 这些内容都要与主库进行对应master_log_pos=0 这是开始位置可以填0 它会自动同步开始位置
###//关闭线程
STOP SLAVE IO_THREAD;
### 设置同步信息 如果 ERROR 3021 (HY000)这个错误,需要先关闭io线程,执行完后再开启
change master to master_host='192.168.3.124',master_user='backup',master_password='123456',master_log_file='mysql-bin.000001',master_log_pos=0,master_port=3307;
### //开启io线程
start SLAVE IO_THREAD;
### 3)、启动从库同步
start slave;
### 4)、查看从库状态
### 主要看:一定要保证这两个状态都是yes才正确
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
### 如果这两个数据为次状态表示可以进行同步
show slave status\G;
### 结果
*************************** 1. row ***************************
Slave_IO_State: Connecting to master
Master_Host: 192.168.3.124
Master_User: backup
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000001
Read_Master_Log_Pos: 4
Relay_Log_File: 69f30c66cc41-relay-bin.000001
Relay_Log_Pos: 4
Relay_Master_Log_File: mysql-bin.000001
Slave_IO_Running: Connecting
Slave_SQL_Running: Yes
Replicate_Do_DB:
Replicate_Ignore_DB: mysql,sys,information_schema,performance_schema
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: 4
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: 2003
Last_IO_Error: error connecting to master '[email protected]:3306' - retry-time: 60 retries: 1
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: Slave has read all relay log; waiting for more updates
Master_Retry_Count: 86400
Master_Bind:
Last_IO_Error_Timestamp: 210807 11:14:29
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:
# 第五步:测试
### 在mster主节点新建两个库:test库t1 gulimall_oms 库t1
docker ps
docker exec -it mysql-master /bin/bash
mysql -uroot -p
create database test;
create database gulimall_oms;
show databases;
use test;
CREATE TABLE t1
(
id INT(11),
name VARCHAR(25),
deptId INT(11),
salary FLOAT
);
show tables;
insert into t1 values(1,'zhangsan',1001,8.0);
select * from t1;
+------+----------+--------+--------+
| id | name | deptId | salary |
+------+----------+--------+--------+
| 1 | zhangsan | 1001 | 8 |
+------+----------+--------+--------+
exit;
exit;
### 从库会自动同步数据,在mysql-slaver-01从节点查看同步情况
docker exec -it mysql-slaver-01 /bin/bash
mysql -uroot -p
show databases;
## 结果,可以看出gulimall_oms已经被同步了过来,由于test在主库和存库设置的时候没有设置为同步的库,所以不会进行同步。
+--------------------+
| Database |
+--------------------+
| information_schema |
| gulimall_oms |
| mysql |
| performance_schema |
| sys |
+--------------------+
use test;
show tables;
select * from t1;
--mysql集群主从备份----------------------------------------------------------end-----
具体步骤:
参数说明:
-p 3307:3306:将容器的 3306 端口映射到主机的 3307 端口
-v /mydata/mysql/master/conf:/etc/mysql:将配置文件夹挂在到主机
-v /mydata/mysql/master/log:/var/log/mysql:将日志文件夹挂载到主机
-v /mydata/mysql/master/data:/var/lib/mysql/:将配置文件夹挂载到主机
-e MYSQL_ROOT_PASSWORD=root:初始化 root 用户的密码
无法同步时,需要查看日志
至此主从配置完成; 总结:
1)、主从数据库在自己配置文件中声明需要同步哪个数据库,忽略哪个数据库等信息。 并且 server-id 不能一样
2)、主库授权某个账号密码来同步自己的数据
3)、从库使用这个账号密码连接主库来同步数据
上面的方案我们进行了主从复制,但是对于一个数据表来说没有实现的数据的扩容,那么如何才能实现数据扩容呢,这就用到了MyCat 或者 ShardingSphere,来实现分库分表。
http://shardingsphere.apache.org/index_zh.html
在当前文件加下 cmd
tar -xzvf apache-shardingsphere-4.1.0-sharding-proxy-bin
第一步:配置server
server时必须要配置的,server中认证账号,所有的操作都是通过这个账号和密码登录到sharding-proxy代理的。
server.yaml
authentication:
users:
root:
password: root
sharding:
password: sharding
authorizedSchemas: sharding_db
props:
executor.size: 16 # Infinite by default.
sql.show: true
配置分库分表规则
在此之前:需要在192.168.3.124:3307把demo_ds_0 demo_ds_1 这两个库建出来。
schemaName: sharding_db 设置分库分表后,我们所有的操作就在sharding_db 库中执行
config-sharding.yaml
schemaName: sharding_db
dataSources:
ds_0:
url: jdbc:mysql://192.168.3.124:3307/demo_ds_0?serverTimezone=UTC&useSSL=false
username: root
password: root
connectionTimeoutMilliseconds: 30000
idleTimeoutMilliseconds: 60000
maxLifetimeMilliseconds: 1800000
maxPoolSize: 50
ds_1:
url: jdbc:mysql://192.168.3.124:3307/demo_ds_1?serverTimezone=UTC&useSSL=false
username: root
password: root
connectionTimeoutMilliseconds: 30000
idleTimeoutMilliseconds: 60000
maxLifetimeMilliseconds: 1800000
maxPoolSize: 50
shardingRule:
tables:
t_order:
actualDataNodes: ds_${0..1}.t_order_${0..1}
tableStrategy:
inline:
shardingColumn: order_id
algorithmExpression: t_order_${order_id % 2}
keyGenerator:
type: SNOWFLAKE
column: order_id
t_order_item:
actualDataNodes: ds_${0..1}.t_order_item_${0..1}
tableStrategy:
inline:
shardingColumn: order_id
algorithmExpression: t_order_item_${order_id % 2}
keyGenerator:
type: SNOWFLAKE
column: order_item_id
bindingTables:
- t_order,t_order_item
defaultDatabaseStrategy:
inline:
shardingColumn: user_id
algorithmExpression: ds_${user_id % 2}
defaultTableStrategy:
none:
读写分离
由于我们时2主2从,所以设置读写分离时要设置两个这样的文件
config-master_slave.yaml
schemaName: master_slave_db
dataSources:
master_ds_0:
url: jdbc:mysql://192.168.3.124:3307/demo_ds_0?serverTimezone=UTC&useSSL=false
username: root
password: root
connectionTimeoutMilliseconds: 30000
idleTimeoutMilliseconds: 60000
maxLifetimeMilliseconds: 1800000
maxPoolSize: 50
slave_ds_0:
url: jdbc:mysql://192.168.3.124:3317/demo_ds_0?serverTimezone=UTC&useSSL=false
username: root
password: root
connectionTimeoutMilliseconds: 30000
idleTimeoutMilliseconds: 60000
maxLifetimeMilliseconds: 1800000
maxPoolSize: 50
masterSlaveRule:
name: ms_ds
masterDataSourceName: master_ds_0
slaveDataSourceNames:
- slave_ds_0
config-master_slave_1.yaml
schemaName: master_slave_db_1
dataSources:
master_ds_1:
url: jdbc:mysql://192.168.3.124:3307/demo_ds_1?serverTimezone=UTC&useSSL=false
username: root
password: root
connectionTimeoutMilliseconds: 30000
idleTimeoutMilliseconds: 60000
maxLifetimeMilliseconds: 1800000
maxPoolSize: 50
slave_ds_1:
url: jdbc:mysql://192.168.3.124:3317/demo_ds_1?serverTimezone=UTC&useSSL=false
username: root
password: root
connectionTimeoutMilliseconds: 30000
idleTimeoutMilliseconds: 60000
maxLifetimeMilliseconds: 1800000
maxPoolSize: 50
masterSlaveRule:
name: ms_ds_1
masterDataSourceName: master_ds_1
slaveDataSourceNames:
- slave_ds_1
第一步:启动sharding-proxy
cmd 在bin下运行 start.bat 3088 记住我们需要指定一个端口号,要不然我们不知道 sharding-proxy的连接端口就会无法连接。
start.bat 3088
第二步:连接sharding-proxy 需要用navicat连接,sqlyog会报错
CREATE TABLE `t_order` (
`order_id` BIGINT (20) NOT NULL,
`user_id` INT (11) NOT NULL,
`status` VARCHAR (50) COLLATE utf8_bin DEFAULT NULL,
PRIMARY KEY (`order_id`)
) ENGINE = INNODB DEFAULT CHARSET = utf8 COLLATE = utf8_bin;
CREATE TABLE `t_order_item` (
`order_item_id` BIGINT (20) NOT NULL,
`order_id` BIGINT (20) NOT NULL,
`user_id` INT (11) NOT NULL,
`content` VARCHAR (255) COLLATE utf8_bin DEFAULT NULL,
`status` VARCHAR (50) COLLATE utf8_bin DEFAULT NULL,
PRIMARY KEY (`order_item_id`)
) ENGINE = INNODB DEFAULT CHARSET = utf8 COLLATE = utf8_bin;
INSERT INTO t_order(user_id,STATUS) VALUES(1,1);
INSERT INTO t_order(user_id,STATUS) VALUES(2,2);
INSERT INTO t_order(user_id,STATUS) VALUES(3,3);
INSERT INTO t_order(user_id,STATUS) VALUES(4,4);