04 . Mysql主从复制和Mycat读写分离

Mysql AB复制

​ AB复制又称之为主从复制,用于实现数据同步,实现Mysql的AB复制时,数据库的版本尽量保持一致,如果不能保持一致,最起码从服务器的版本要高于主服务器,但是就无法实现双向复制技术.

Mysql AB复制的好处

1.解决宕机带来的数据不一致问题,因为Mysql复制可以实时备份数据.

2.多台服务器的性能一般比单台好,且可以减轻数据库服务器的压力,因为备份等操作可以在从服务器上进行,但是AB复制不适用于大数据量,如果是一个主服务器有多台从服务器,那么主服务器需要同时向多台服务器中写入数据,压力会很大,这个时候就推荐使用集群.

​ Mysql复制(replication)是一个异步的复制,从一个Mysql实例(Master)复制到另一个Mysql实例(Slave),整个主从复制需要由Master服务器上的IO进程,Slave服务器上的Sql线程和IO线程共同完成,首先Master端必须打开binary log(bin-log),因为整个Mysql复制过程实际上就是Slave从Master端获取相应的二进制日志,然后在本地完全顺序的执行日志中所记录的各种操作.

传统主从复制基本过程:

# 1.  Mysql slave端的ID进程连接上Master,向Master请求指定日志文件的指定位置(或者最开始日志)之后的日志内容;

# 2.  Master接收到来自Slave的IO进程的请求后,负责复制的IO进程根据Slave的请求信息,读取相应日志内容,返回Slave的IO进程,并将相应日志内容返回给Slave的IO进程,并将本次请求读取的bin-log文件名及位置一起返回Slave端.

# 3.  Slave的IO进程接收到信息后,将接收到的日志内容依次添加到Slave端的relay-log文件的最末端,并将读取到的Master端的 bin-log的文件名和位置记录到master-info文件中,以便在下一次读取的时候能够清楚的告诉Master“我需要从某个bin-log的哪个位置开始往后的日志内容,请发给我”;

# 4.  Slave的Sql进程检测到relay-log中新增加了内容后,会马上解析relay-log的内容成为在Master端真实执行时候的那些可执行的内容,并在自身执行。
复制原理

从库生成两个线程,一个I/O,一个SQL线程,I/O线程去请求主库的binlog,并将得到的binlog日志写到relay log(中继日志)文件中;

主库会生成一个Log dump线程,用来给从库I/O线程传binlog;

从库的SQL线程会读取relay log文件的日志,并解析成具体操作,从而实现主从数据一致

# 两个进程一个线程
# IO进程:  		负责下载日志,中继日志
# SQL进程: 		SQL负责将中继日志应用到数据库中,完成AB复制数据同步.
# logdump线程:

主从复制方式

# 1. 同步复制
	# master服务器操作完成,当操作作为时间写入二进制日志,传递给slave,存放到中继日志中,然后再本地执行完成功,即反馈成功.
    
# 2. 半同步复制
	# 当有多台slave服务器时,master向离自己最近的slave服务器同步二进制文件后,即为反馈成功,不是Mysql官方提供的,是5.5版本时google研发半同步不定后支持,需要semi插件.
    
# 3. 异步复制:
	# Master服务器操作完成,当操作作为事件写入二进制日志,即反馈成功(默认)
    
# 4. 基于GTID复制技术(5.6版本才有)
	# 见下面
    
# 5. 多源复制(5.7)
	# 1. 方便备份数据
    # 2. 方便对数据进行统一分析
    

GTID复制

GTID作用

1. 使用GITD技术可以让两台服务器自动交换事务ID,经过对比,请求数据,保证服务器之间的数据是同步的;

2. 提升安全性,多事务并行执行时,也不会造成数据混乱;

3. 多线程复制,从服务器可以启动多个SQL Threfad,并发执行多个库的复制,提升速度

GTID复制案例

注意事项

网络问题

# 要注意mysql主库和从库所在服务器间的网络问题,因为是要做数据库的主从,主从之间的网络是要能通的,及从库可通过网络访问到主库,否则无法同步数据.

# 如果mysql主从使用的是云服务器,注意去该云服务器的管理平台,开放相应数据库的安全组(如阿里云,青云,腾讯云)

mysql的版本问题

# 主从的数据是要进行同步的,如果数据库版本或者安装方式不同,会影响数据的同步,产生无法同步或字符集报错的情况

# 主库和从库的服务器,安装mysql数据库时,要选择相应的版本,并且安装方式最好相同

配置文件问题

# mysql或mariadb的关键配置文件是my.cnf,默认位置为etc/my.cnf(由于安装方式的不同,此配置文件,并不一定在此)

# 做主从时,注意要在启动数据库前,修改配置文件my.cnf后,再启动数据库服务

# 注意主从配置时,必须要在my.cnf中添加server-id,主的server-id的数值要小于从的server-id,每一个server-id都必须是唯一的

# 注意主从配置时,必须要在my.cnf中添加log-bin,开启二进制文件

# 数据库如配置有调优参数,应使主从的配置文件中参数数值相同,避免因参数不同导致的失败

授权问题

# 数据库的同步是要通过主库专门创建的一个用户来使从库进行数据的同步的,因此要注意授权的问题

# 注意主库授权时的ip,用户,密码grant replication slave on . to ‘用户’@‘从库的IP’ identified by ‘密码’

# 注意从库连接主库的各项参数
# change master to master_host = ‘主库的IP’, master_user = ‘设置主从时设定的主库的用户’, master_port=主库的端口, master_password=’主库设定的密码’, master_log_file = ‘主库状态的File’, master_log_pos=主库状态的Position;

数据库差别问题

# 我们在做新的mysql主从的时候,由于主库并没有产生较多的数据,从库很容易就进行同步,报错也几乎不会产生

# 但是,当我们的主库的数据已经有很多了或者是把一个用了很久的数据库来做主从,这时就需要先将主库的数据备份导入从库中,再进行从库的连接到主库的步骤。否则,就会从库就会因数据差别较大,产生各种报错
安装Mysql

先在两台机器执行下面脚本,分别安装好数据库,并改好密码

#!/usr/bin/env bash
# Author: ZhouJian
# Mail: 18621048481@163.com
# Time: 2019-9-3
# Describe: CentOS 7 Install Mysql.rpm Script
clear
echo -ne "\\033[0;33m"
cat<<EOT
                                  _oo0oo_
                                 088888880
                                 88" . "88
                                 (| -_- |)
                                  0\\ = /0
                               ___/'---'\\___
                             .' \\\\\\\\|     |// '.
                            / \\\\\\\\|||  :  |||// \\\\
                           /_ ||||| -:- |||||- \\\\
                          |   | \\\\\\\\\\\\  -  /// |   |
                          | \\_|  ''\\---/''  |_/ |
                          \\  .-\\__  '-'  __/-.  /
                        ___'. .'  /--.--\\  '. .'___
                     ."" '<  '.___\\_<|>_/___.' >'  "".
                    | | : '-  \\'.;'\\ _ /';.'/ - ' : | |
                    \\  \\ '_.   \\_ __\\ /__ _/   .-' /  /
                ====='-.____'.___ \\_____/___.-'____.-'=====
                                  '=---='
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                建议系统                    CentOS7
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
# PS:请尽量使用纯净的CentOS7系统,我们会在服务器安装Mysql5.7,
# 将mysql-5.7.23-1.el7.x86_64.rpm-bundle.tar包和脚本放到root目录下执行即可,密码为ZHOUjian.20
EOT
echo -ne "\\033[m"
init_security() {
systemctl stop firewalld
systemctl disable firewalld &>/dev/null
setenforce 0
sed -i '/^SELINUX=/ s/enforcing/disabled/'  /etc/selinux/config
sed -i '/^GSSAPIAu/ s/yes/no/' /etc/ssh/sshd_config
sed -i '/^#UseDNS/ {s/^#//;s/yes/no/}' /etc/ssh/sshd_config
systemctl enable sshd crond &> /dev/null
echo -e "\033[32m [安全配置] ==> OK \033[0m"
}
init_yumsource() {
if [ ! -d /etc/yum.repos.d/backup ];then
    mkdir /etc/yum.repos.d/backup
fi
mv /etc/yum.repos.d/* /etc/yum.repos.d/backup 2>/dev/null

if ! ping -c2 www.baidu.com &>/dev/null    
then
    echo "您无法上外网,不能配置yum源"
    exit    
fi
curl -o /etc/yum.repos.d/163.repo http://mirrors.163.com/.help/CentOS7-Base-163.repo
curl -o /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
timedatectl set-timezone Asia/Shanghai
echo "nameserver 114.114.114.114" > /etc/resolv.conf
echo "nameserver 8.8.8.8" >> /etc/resolv.conf
chattr +i /etc/resolv.conf


echo -e "\033[32m [YUM Source] ==> OK \033[0m"
}
init_mysql() {
rpm -e mariadb-libs --nodeps
rm -rf /var/lib/mysql
rm -rf /etc/my.cnf
tar xvf /root/mysql-5.7.23-1.el7.x86_64.rpm-bundle.tar -C /usr/local/
cd /usr/local
rpm -ivh mysql-community-server-5.7.23-1.el7.x86_64.rpm \
mysql-community-client-5.7.23-1.el7.x86_64.rpm \
mysql-community-common-5.7.23-1.el7.x86_64.rpm \
mysql-community-libs-5.7.23-1.el7.x86_64.rpm 
rm -rf mysql-community-* 
}
changepass() {
sed -i '/\[mysqld]/ a skip-grant-tables' /etc/my.cnf
systemctl restart mysqld
mysql <<EOF
        update mysql.user set authentication_string='' where user='root' and Host='localhost';
        flush privileges;
EOF
sed -i '/skip-grant/d' /etc/my.cnf
systemctl restart mysqld
yum -y install expect ntpdate

expect <<-EOF
spawn  mysqladmin -uroot -p password "ZHOUjian.20"
        expect {
                "password" { send "\r"  }
}
        expect eof
EOF
systemctl restart mysqld
}
main() {
init_hostname
init_security
init_yumsource
init_mysql
changepass
}
main
修改配置文件

mysql主库配置

[root@mysqlhost ~]# cat /etc/my.cnf
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
symbolic-links=0
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid

server-id = 1
log-bin=mysql-bin

mysql从库配置

[root@mysql-from ~]# cat /etc/my.cnf
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
symbolic-links=0
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid

server-id = 2
log-bin = mysql-bin

主从两台服务器分别重启服务

systemctl restart mysqld

主数据库授权从库
# 创建用于同步的用户账号及密码
grant replication slave on *.* to 'slave'@'192.168.0.%' identified by 'ZHOUjian.200';

# 重新加载权限表,更新权限
flush privileges;

# 查看master的状态
#mysql> show master status;
#+------------------+----------+--------------+------------------+-------------------+
#| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
#+------------------+----------+--------------+------------------+-------------------+
#| mysql-bin.000001 |      600 |              |                  |                   |
#+------------------+----------+--------------+------------------+-------------------+
#1 row in set (0.00 sec)

从库开启Slave
change master to
master_host='192.168.0.102',
master_user='slave',
master_password='ZHOUjian.200',
master_auto_position=0;

mysql> start slave;

# 查看从库状态
mysql> show slave status\G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.0.117
                  Master_User: slave
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000001
          Read_Master_Log_Pos: 600
               Relay_Log_File: mysql-from-relay-bin.000002
                Relay_Log_Pos: 813
        Relay_Master_Log_File: mysql-bin.000001
             Slave_IO_Running: Yes   # 此处两个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: 600
              Relay_Log_Space: 1025
              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: 1
                  Master_UUID: ff0c0da9-8f72-11ea-9d83-000c29245a7e
             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)

主从复制基础添加多个从库

以下操作是基于上面的GTID复制案例喔,请做完GTID再做这里,大佬请无视这句话

更改新增从库my.cnf的配置
[root@mysql-from2 ~]# cat /etc/my.cnf
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
symbolic-links=0
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid

server-id = 3
log-bin = mysql-bin

修改配置记得重启mysqld服务生效配置

systemctl restart mysqld

主库给新加的从库创建用于同步的账号和密码
# 创建用于同步的用户账号及密码
grant replication slave on *.* to 'slave'@'192.168.0.%' identified by 'ZHOUjian.200';

# 重新加载权限表,更新权限
flush privileges;
进入主库
# 先进入主库,进行锁表,此处锁定为只读状态,防止数据写入 (可选,因如有数据库备份,可直接利用备份)

flush tables with read lock;
mysqldump -uroot -p‘….’ -hlocalhost > mysql.back.sql

scp mysql.back.sql 从库IP:/root/(任意位置)

# 从库导入数据
mysql -uroot -p... -f < mysql.back.sql


# 主库解锁
unlock tables;
进入从库连接主库
# 从库开启slave
change master to
master_host='192.168.0.102',
master_user='slave',
master_password='ZHOUjian.200',
master_auto_position=0;

mysql> start slave;

# 查看从库状态
mysql> show slave status\G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.0.102
                  Master_User: slave
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000001
          Read_Master_Log_Pos: 600
               Relay_Log_File: mysql-from-relay-bin.000002
                Relay_Log_Pos: 813
        Relay_Master_Log_File: mysql-bin.000001
             Slave_IO_Running: Yes   # 此处两个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: 600
              Relay_Log_Space: 1025
              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: 1
                  Master_UUID: ff0c0da9-8f72-11ea-9d83-000c29245a7e
             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)

数据库中间 MyCAT 读写分离实现

Mysql读写分离实现方式

解决并发问题,不同于分表,分表用于解决数据量过大的问题

方式一: 业务层使用不同的数据库

方式二: 使用负载均衡,判断是什么语句,分配到不同的数据库

基于应用层和数据层中间件的代理层,主要解决方案如下:

# 1. 开发人员
# 2. 软件
# 		mysql-proxy    Mysql官方
# 		amoeba JAVA    阿里
# 		Atlas   	   奇虎360
# 		Sharding-JDBC  
# 		DBProxy			美团点评
#       Amoeba			早期阿里巴巴
# 		cobar   		(MyCAT前身,java)
# 		MyCat          阿里巴巴

# 	这些中间件,统一为多个数据库进行代理,应用只需要连接中间件(分布式数据库系统),执行SQL,中间件就会根据规则,将SQL分配到不同的数据库中
MyCat简介

Mycat 是一个开源的分布式数据库系统,但是由于真正的数据库需要存储引擎,而 Mycat 并没有存 储引擎,所以并不是完全意义的分布式数据库系统。 那么 Mycat 是什么?Mycat 是数据库中间件,就是介于数据库与应用之间,进行数据处理与交互的中间服 务。

MyCAT 是使用 JAVA 语言进行编写开发,使用前需要先安装 JAVA 运行环境(JRE),由于 MyCAT 中使用了 JDK7 中的一些特性,所以要求必须在 JDK7 以上的版本上运行。

认识MyCat 中的概念

逻辑架构图

DBA 或者运维人员对数据进行分片处理之后,从原有的一个库,被切分为多个分片数据库,所有的分片数据库集 群构成了整个完整的数据库存储。

如上图所表示,数据被分到多个分片数据库后,应用如果需要读取数据,就要需要处理多个数据源的数据。 如果没有数据库中间件,那么应用将直接面对分片集群,数据源切换、事务处理、数据聚合都需要应用直接处 理,原本该是专注于业务的应用,将会花大量的工作来处理分片后的问题,最重要的是每个应用处理将是完全的 重复造轮子。 所以有了数据库中间件,应用只需要集中与业务处理,大量的通用的数据聚合,事务,数据源切换都由中间 件来处理,中间件的性能与处理能力将直接决定应用的读写性能,所以一款好的数据库中间件至关重要。

逻辑库(schema)

通常对实际应用来说,并不需要知道中间件的存在,业务开发人员只需要知道 数据库的概念,所以数据库中间件可以被看做是一个或多个数据库集群构成的逻辑库。

在云计算时代,数据库中间件可以以多租户的形式给一个或多个应用提供服务,每个应用访问的可能是一个 独立或者是共享的物理库,常见的如阿里云数据库服务器 RDS。

逻辑表(table)

既然有逻辑库,那么就会有逻辑表,分布式数据库中,对应用来说,读写数据的表就是逻辑表。逻辑表,可 以是数据切分后,分布在一个或多个分片库中,也可以不做数据切分,不分片,只有一个表构成。

分片规则(rule)

数据切分,一个大表被分成若干个分片表,就需要一定的规则,这样按照某种业务规则把数据分到 某个分片的规则就是分片规则,数据切分选择合适的分片规则非常重要,将极大的避免后续数据处理的难度。

部署MyCat

系统环境清单

list

[MysqlRead-Write-Server]
	System = CentOS7.6.1810
	jdk-8u151-linux-x64.tar.gz
	mysql-5.7.23-1.el7.x86_64.rpm-bundle.tar
	Mycat-server-1.6-RELEASE-20161028204710-linux.tar.gz
节点名 IP 软件版本 硬件 网络 说明
mysql_host 192.168.171.143 list 里面 2C4G Nat,内网 测试环境
mysql_from 192.168.171.144 list里面 2C4G Nat,内网 测试环境
mycat 192.168.171.128 list里面 2C4G Nat,内网 测试环境
test_clent 192.168.171.132 list里面 2C4G Nat,内网 测试环境
安装Java环境
tar xvf jdk-8u151-linux-x64.tar.gz -C /usr/local/
ln -s /usr/local/jdk1.8.0_151/ /usr/local/java

# 配置环境变量
vi /etc/profile.d/java.sh
export JAVA_HOME=/usr/local/java
export PATH=$JAVA_HOME/bin:$PATH
export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar

source /etc/profile.d/java.sh
下载安装MyCat
wget http://dl.mycat.io/1.6-RELEASE/Mycat-server-1.6-RELEASE=20161028204710-linux.tar.gz

# 解压
tar -xf Mycat-server-1.6-RELEASE-20161028204710-linux.tar.gz -C /usr/local/

ls /usr/local/mycat/
bin  catlet  conf  lib  logs  version.txt

MyCAT 目前主要通过配置文件的方式来定义逻辑库和相关配置

/usr/local/mycat/conf/server.xml`
# 定义用户以及系统相关变量,如端口等。其中用户信息是前端应用程序连接 mycat 的用户信息。
/usr/local/mycat/conf/schema.xml`
# 定义逻辑库,表、分片节点等内容。
/usr/local/mycat/conf/rule.xml`
# 中定义分片规则
配置 server.xml

下面的用户和密码是应用程序连接到 MyCat 使用的,可以自定义配置

而其中的schemas 配置项所对应的值是逻辑数据库的名字,也可以自定义,但是这个名字需要和后面 schema.xml 文件中配置的一致。

shell> vim server.xml
<user name="mycatdb">
    <property name="password">ZHOUjian.21</property>
    <property name="schemas">schema_shark_db</property>

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

<!--下面是另一个用户,并且设置的访问 TESTED 逻辑数据库的权限是 只读
<user name="user">
        <property name="password">user</property>
        <property name="schemas">TESTDB</property>
        <property name="readOnly">true</property>
</user>
-->

上面的配置中,假如配置了用户访问的逻辑库,那么必须在 schema.xml 文件中也配置这个逻辑库,否则报错,启动 mycat 失败

配置 schema.xml

以下是配置文件中的每个部分的配置块儿

逻辑库和分表设置

<schema name="schema_shark_db"   // 逻辑库名称
        checkSQLschema="false"   // 不检查
        sqlMaxLimit="100"        // 最大连接数
        dataNode='dn1'>          // 数据节点名称
<!--这里定义的是分表的信息-->
</schema>

数据节点

<dataNode name="dn1"              // 此数据节点的名称
          dataHost="localhost1"   // 主机组
          database="shark_db">    // 真实的数据库名称
</dataNode>

主机组

<dataHost name="localhost1"
            maxCon="1000" minCon="10"   // 连接
            balance="0"                 // 负载均衡
            writeType="0"               // 写模式配置
            dbType="mysql" dbDriver="native" // 数据库配置
            switchType="1" slaveThreshold="100">
    <!--这里可以配置关于这个主机组的成员信息,和针对这些主机的健康检查语句-->
</dataHost>
# balance属性
# 负载均衡类型,目前的取值有三种
# 1. balance="0",不开启读写分离机制,所有读操作都发送到当前的writeHost上.

# 2. balance="1",全部的readHost与stand by writeHost参与select语句的负载均衡,简单的说,当双主双从模式(M1->S2,M2->S2,并且M1与M2互为主备),正常情况下,M2,S1,S2参与select语句的负载均衡.

# 3. balance="2",所有的读操作都随机的再writeHost,readhost上分发.
# 4. balance="3",所有读请求随机的分发到writeHost对应的readhost执行,writeHost不分担读压力,注意balance=3只在1.4以及以后版本有,1.3没有

# writeType属性
# 负载均衡类型,目前的取值有三种:
# 1. writeType="0",所有写操作发送到配置的第一个writeHost,第一个挂了切换到还生存的第二个writeHost,重新启动后已切换后的为准

# 2. writeType="1",所有写操作都随机的发送到配置的writeHost,1.5以后飞起不推荐

健康检查

<heartbeat>select user()</heartbeat>

读写配置

<writeHost host="hostM1" url="172.16.153.10:3306"
               user="root" password="123">
      <!-- can have multi read hosts -->
      <readHost host="hostS2" url="172.16.153.11:3306"
                user="root" password="123" /></writeHost>

以下是组合为完整的配置文件,适用于一主一从的架构

<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">

        <schema name="youmen" checkSQLschema="false" sqlMaxLimit="100" dataNode="dn1">
            <!--这里定义的是分库分表的信息-->
        </schema>
    
    		<!--下面是配置读写分离的信息-->
        <dataNode name="dn1" dataHost="localhost1" database="yueyue" />
        <dataHost name="localhost1" maxCon="1000" minCon="10" balance="1"
                          writeType="0" dbType="mysql" dbDriver="native" switchType="1"  slaveThreshold="100">
                <heartbeat>select user()</heartbeat>

                <writeHost host="hostM1" url="192.168.171.144:3306" user="mycatuser" password="ZHOUjian.21">
                        <readHost host="hostS2" url="192.168.171.143:3306" user="mycatuser" password="ZHOUjian.21" />
                </writeHost>
        </dataHost>
</mycat:schema>

配置 log4j2.xml
<!--设置日志级别为 debug , 默认是 info-->
<asyncRoot level="debug" includeLocation="true">
在真实的 master 数据库上给用户授权
grant all on *.* to "mycatuser"@"%" identified by "ZHOUjian.21";
flush privileges;
启动 mycat
/usr/local/mycat/bin/mycat  start

# 支持一下参数
start | restart |stop | status


# 看一下端口
ss -antp |grep -E  "8066|9066"
LISTEN     0      100         :::9066                    :::*                   users:(("java",pid=14923,fd=72))
LISTEN     0      100         :::8066                    :::*                   users:(("java",pid=14923,fd=76))

测试

在 mycat 的机器上测试用户权限有效性

# Mycat这台机器不需要装Mysql,只要有mysql命令即可

# 测试是否能正常登录上 主服务器
mysql -umycatuser -pZHOUjian.21 -h 192.168.171.143

# 继续测试是否能登录上从服务器
mysql -umycatuser -pZHOUjian.21 -h 192.168.171.144

接下来我们使用客户端,看是否能不能连接到Mycat做代理

# 此处的账号密码是你server.xml文件定义的
mysql -uzhou -pZHOUjian.21 -h 192.168.171.128 -P 8066
mysql> show databases;
+----------+
| DATABASE |
+----------+
| youmen   |
+----------+
mysql> use youmen
Database changed
mysql> create table zhou(id int,name varchar(20),age int);


# 接下来我们去主库从库验证,看代理有没有把我们创建的表同步
mysql -uroot -pZHOUjian.20  -e 'use yueyue; show tables;'
+------------------+
| Tables_in_yueyue |
+------------------+
| zhou             |          |
+------------------+

继续测试读写分离策略

使用 mysql 客户端工具使用 mycat 的账户和密码登录 mycat ,
之后执行 select 语句。

之后查询 mycat 主机上 mycat 安装目录下的 logs/mycat.log 日志。

在日志重搜索查询的语句或者查询 从库的 ip 地址,应该能搜索到

posted @ 2019-11-25 20:11  常见-youmen  阅读(703)  评论(0编辑  收藏  举报