一、读写分离概述
读写分离:读写操作,分发不同的服务器,读分发到对应的服务器 (slave),写分发到对应的服务器(master)
读写分离 将读写业务分配到不同的服务器上,让服务器做特定的操作,不 需要不断的切换工作模式,使工作效率提高 写主服务器,读从服务器
同时降低主服务器的压力,在正常业务下,也是读比较多的情况,写相对 读少一些。
大约比例在写3/7读
读写分离:
①M-S下,读写必须分离,如果不分离,业务不可用出问题
②M-M 在此架构中,虽然可以随意读写操作,特定的操作交由特定的服务 器操作,工作效率更高
mysql的读写分离的基本原理是:
SQL语句
让master(主数据库)来响应事务性操作(insert,update,delete, create,drop)
让slave(从数据库)来响应select非事务性操作
然后再采用主从复制来把master上的事务性操作同步到slave数据库中
没有主从复制,就无法实现业务上的读写分离
① 业务代码的读写分离
需要在业务代码中,判断数据操作是读还是写,读连接从数据服务器操 作,写连接主数据库服务器操作mysql01/mysql02
以当前LNMP为例,就需要使用PHP代码实现读写分离
在代码端对数据库的操作进行判断:
操作MySQL01 => MASTER主数据库
增加:
mysql> insert into 数据表 values ('字段值1','字段值2',...);
删除:
mysql> delete from 数据表 where 条件;
mysql> delete from 数据表 where 字段 in (字段值1,字段值2,...);
mysql> delete from 数据表;
更新:
mysql> update 数据表 set 字段1=字段值1,字段2=字段值2,... where 条件;
操作MySQL02 => SLAVE从数据库
查询:
mysql> select */字段列表 from 数据表 where条件 group by分组 having子句 order by排序 limit子句;
② 中间件代理方式的读写分离
在业务代码中,数据库的操作,不直接连接数据库,而是先请求到中间件 服务器(代理)
由代理服务器,判断是读操作去从数据服务器,写操作去主数据服务器
名称 |
描述 |
---|---|
MySQL Proxy |
MySQL官方 测试版 不再维护 |
DBProxy |
美团点评 |
Amoeba |
早期阿里巴巴 |
cobar |
阿里巴巴 |
MyCat |
基于阿里开源的Cobar |
kingshard |
go语言开发 |
1、MySQL主从配置
第一步:生成MySQL02数据库服务器(从)
编号 |
IP地址 |
主机名称 |
角色 |
---|---|---|---|
1 |
10.1.1.12 |
mysql01.liuluanyi.cn |
MASTER |
2 |
10.1.1.14 |
mysql02.liuluanyi.cn |
SLAVE |
第二步:在MySQL02服务器中安装MySQL5.6.35 GLIBC版本与MySQL01 组建主从服务器
使用rsync传输文件到MySQL02
# tar -zxf mysql-5.6.35-linux-glibc2.5-x86_64.tar.gz
# mv mysql-5.6.35-linux-glibc2.5-x86_64 /usr/local/mysql
# useradd -r -s /sbin/nologin mysql
# chown -R mysql.mysql /usr/local/mysql
# cd /usr/local/mysql
# rm -rf data/*
第三步:在MySQL01服务器中,把/usr/local/mysql/data/目录下的所有 文件传输MySQL02中
# rsync -av /usr/local/mysql/data/*
[email protected]:/usr/local/mysql/data/
第四步:在MySQL02服务器中,删除/usr/local/mysql/data/auto.cnf文件
# rm /usr/local/mysql/data/auto.cnf
第五步:后续配置
# cp support-files/mysql.server /etc/init.d/mysql
# service mysql start
# echo 'export PATH=$PATH:/usr/local/mysql/bin' >>
/etc/profile
# source /etc/profile
第六步:配置MySQL01与MySQL02的my.cnf文件(关键)
[root@master ~]# cat /etc/my.cnf
[mysqld]
basedir=/usr/local/mysql
datadir=/usr/local/mysql/data
port=3306
socket=/tmp/mysql.sock
log-error=/usr/local/mysql/data/mysql.err
character_set_server=utf8mb4
server_id = 10
log-bin=/usr/local/mysql/data/binlog
[root@slave ~]# cat /etc/my.cnf
[mysqld]
basedir=/usr/local/mysql
datadir=/usr/local/mysql/data
port=3306
socket=/tmp/mysql.sock
log-error=/usr/local/mysql/data/mysql.err
character_set_server=utf8mb4
server_id=20
relay-log=/usr/local/mysql/data/relaylog
设置完成后,重启MySQL数据库
# service mysql restart
第七步:在MASTER(MySQL01)中创建一个账号slave,专门用于实现数 据同步
mysql> grant replication slave on *.* to
'slave'@'10.1.1.%' identified by '123';
mysql> flush privileges;
第八步:锁表,查看二进制文件名称与位置,然后在从服务器实现change master to
MySQL01:
mysql> show master status\G
MySQL02:
mysql> help change master to;
CHANGE MASTER TO
MASTER_HOST='10.1.1.12',
MASTER_USER='slave',
MASTER_PASSWORD='123',
MASTER_PORT=3306,
MASTER_LOG_FILE='binlog.000001',
MASTER_LOG_POS=405,
MASTER_CONNECT_RETRY=10;
mysql> start slave;
mysql> show slave status\G
MyCAT工作原理:
编号 |
IP地址 |
主机名称 |
角色 |
---|---|---|---|
1 |
10.1.1.15 |
mycat.liuluanyi.cn |
MyCAT中间件 |
MyCAT是基于Java语言开发的程序,其操作系统中必须拥有Java的运行环 境,否则MyCAT无法运行。
JDK包含了JRE,目前JDK公用的版本一共有两个:OpenJDK、Oracle JDK oracle jdk(sun公司=>oracle公司收购)
open jdk(完全免费的jdk环境、Linux操作系统默认的JDK就是openjdk)
第一步:上传JDK与MyCAT到MyCAT服务器端
第二步:安装JDK软件
shell > tar xvf jdk-8u192-linux-x64.tar.gz
shell > mkdir /usr/local/java
shell > mv jdk1.8.0_192 /usr/local/java/
结构:
/usr/local/java
|----- jdk1.8.0_192
|----- jdk1.11.******
配置环境变量:非常重要,MyCAT => 环境变量 (JDK)
shell > vim /etc/profile
export PATH=$PATH:/usr/local/java/jdk1.8.0_192/bin
----------------------------华丽的分割线 -------------------
-------
shell > source /etc/profile
shell > java -version
MyCAT目录介绍
bin :mycat二进制文件目录
conf:配置文件目录
logs:目录可以查看到错误日志
# tar xvf Mycat-server-1.6.5-release-20180122220033-
linux.tar.gz -C /usr/local
默认不进行任何配置,mycat也是可以启动的:
shell > /usr/local/mycat/bin/mycat console
#确认mycat是否真的启动,查看它的端口 9066 8066
shell > ss -naltp |grep 8066
8066:MyCAT客户端
9066:MyCAT管理端
要进行MyCAT软件的配置,只需要了解两个文件:
conf/server.xml:对外提供的用户等的设置
conf/schema.xml:配置后端数据库服务器相关信息
server.xml文件(不需要修改)
默认情况下,MyCAT中server.xml已经配置完毕。无需任何修改,我们需 要做的就是了解其对外提供的信息有哪些?
IP地址:10.1.1.15
端口:8066
数据库名称?用户名和密码?
由以上图解运行可知,Web01与Web02 => MyCAT
conf/server.xml:对外提供的用户等的设置
conf/schema.xml:配置后端数据库服务器相关信息
# vim conf/server.xml
这里要注意一下,如果需要将Mycat连接的数据库和主从里面的数据库包处一致的话,需要同时修改server.xml中的schemas和schema.xml中的dataNode节点
由以上图解运行可知,Web01与Web02 => MyCAT
IP地址:10.1.1.15
端口:8066
数据库名称:TESTDB
用户名:root
密码:123456
扩展:xml文件格式
...
...
...
schema.xml文件(需要修改)
schema.xml文件面向的是后端真实的数据库(MySQL01与MySQL02), 所以需要进行配置。
第一步:删除这个文件中的所有注释
第二步:删除schema标签中的所有table标签(全部删除)
第三步:dataNode节点只保留一个dn1
第四步:writeHost节点只保留一个
分析schema.xml文件的大致结构:
...
writeHost:写服务器=>MySQL01
readHost:读服务器=>MySQL02
select user()
sqlMaxLimit配置默认查询数量
database为真实数据库名
balance="0", 不开启读写分离机制,所有读操作都发送到当前可用的writeHost 上。
balance="1",全部的 readHost 与 stand by writeHost 参与 select 语句的负载均衡,简单的说,当双主双从模式(M1 ->S1 , M2->S2,并且 M1 与 M2 互为主备),正常情况下, M2,S1,S2 都参与 select 语句的负载均衡。
balance="2",所有读操作都随机的在 writeHost、 readhost 上分发。
balance="3", 所有读请求随机的分发到 wiriterHost 对应的 readhost 执行,writerHost 不负担读压力,注意 balance=3 只在 1.4 及其以后版本有, 1.3 没有。
writeType="0", 所有写操作发送到配置的第一个 writeHost,第一个挂了切到还生存的第二个writeHost,重新启动后已切换后的为准,切换记录在配置文件中:dnindex.properties .
writeType="1",所有写操作都随机的发送到配置的 writeHost。
writeType="2",没实现。
-1 表示不自动切换
1 默认值,自动切换
2 基于MySQL 主从同步的状态决定是否切换
第五步:在标签中添加dataNode节点
4
第六步:在dataNode节点中,指定database真实的数据库(重要)
6
第七步:设置writeHost与readHost(读写两台服务器信息) 到
到此读写数据库的信息配置完毕了!
第八步:开启读写分离,balance="1"
到此读写分离就全部配置完毕了!
shell > /usr/local/mycat/bin/mycat start
shell > ss -naltp |grep 8066
shell > ss -naltp |grep 9066
如果没有正常启动,只能有一个原因:就是schema.xml文件编写错误。(主要是语法)