mysql集群

一、集群的目标

mysql集群_第1张图片

二、集群的基本形式

mysql集群_第2张图片
分布式:实例
redis存储数据,可以使得数据扩容
node1中我们存储了1-10000的数据,并且我们保存了10000-20000的备份
node2中我们存储了10000-20000的数据,并且我们保存了30000-40000的备份
node3中我们存储了30000-40000的数据,并且我们保存了1-10000的备份

三、mysql的集群

3.1 集群原理

mysql集群_第3张图片

3.2 企业中常用的数据库解决方案

3.2.1 MySQL-MMM 主主复制方式

mysql集群_第4张图片

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 用户。

3.2.2 MHA(Master High Availability)只做了解

目前在 MySQL 高可用方面是一个相对成熟的解决方案, 由日本 DeNA 公司 youshimaton(现就职于 Facebook 公司)开发,是一套优秀的作为 MySQL高可用性环境下故障切换和主从提升的高可用软件。在MySQL故障切换过程中, MHA 能做到在 0~30 秒之内自动完成数据库的故障切换操作(以 2019 年的眼光来说太 慢了),并且在进行故障切换的过程中,MHA 能在最大程度上保证数据的一致性,以 达到真正意义上的高可用。

3.2.3 InnoDB Cluster

mysql集群_第5张图片

InnoDB Cluster 支持自动 Failover、强一致性、读写分离、读库高可用、读请求负载均 衡,横向扩展的特性,是比较完备的一套方案。但是部署起来复杂,想要解决 router 单点问题好需要新增组件,如没有其他更好的方案可考虑该方案。 InnoDB Cluster 主 要由 MySQL Shell、MySQL Router 和 MySQL 服务器集群组成,三者协同工作,共同为 MySQL 提供完整的高可用性解决方案。MySQL Shell 对管理人员提供管理接口,可以 很方便的对集群进行配置和管理,MySQL Router 可以根据部署的集群状况自动的初始 化,是客户端连接实例。如果有节点 down 机,集群会自动更新配置。集群包含单点写 入和多点写入两种模式。在单主模式下,如果主节点 down 掉,从节点自动替换上来, MySQL Router 会自动探测,并将客户端连接到新节点。

3.2.4 常用的解决方案

mysql集群_第6张图片

3.3 mysql主从复制

--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 用户的密码
mysql集群_第7张图片
无法同步时,需要查看日志
mysql集群_第8张图片

至此主从配置完成; 总结:
1)、主从数据库在自己配置文件中声明需要同步哪个数据库,忽略哪个数据库等信息。 并且 server-id 不能一样
2)、主库授权某个账号密码来同步自己的数据
3)、从库使用这个账号密码连接主库来同步数据

3.4 测试

mysql集群_第9张图片

四、MyCat 或者 ShardingSphere(sharding-proxy形式)

上面的方案我们进行了主从复制,但是对于一个数据表来说没有实现的数据的扩容,那么如何才能实现数据扩容呢,这就用到了MyCat 或者 ShardingSphere,来实现分库分表。
mysql集群_第10张图片

4.1 下载

http://shardingsphere.apache.org/index_zh.html
mysql集群_第11张图片
mysql集群_第12张图片

在当前文件加下 cmd

tar -xzvf apache-shardingsphere-4.1.0-sharding-proxy-bin

解压后:
mysql集群_第13张图片

4.2 配置

mysql集群_第14张图片
引入mysql驱动
把驱动放在 lib 目录下
mysql集群_第15张图片

第一步:配置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

mysql集群_第16张图片

配置分库分表规则
在此之前:需要在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:

mysql集群_第17张图片

读写分离
由于我们时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

mysql集群_第18张图片

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

4.3 测试

第一步:启动sharding-proxy
cmd 在bin下运行 start.bat 3088 记住我们需要指定一个端口号,要不然我们不知道 sharding-proxy的连接端口就会无法连接。

start.bat 3088

mysql集群_第19张图片

第二步:连接sharding-proxy 需要用navicat连接,sqlyog会报错
mysql集群_第20张图片

mysql集群_第21张图片
mysql集群_第22张图片
第三步:在sharding_db 中新建2张表插入4条数据

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);

第四步:结果
实现了分库分表
mysql集群_第23张图片
mysql集群_第24张图片
主从备份
mysql集群_第25张图片

你可能感兴趣的:(mysql集群)