1.什么是读写分离
-
数据库使用较多时,且查询的操作多,更新操作少会使用读写分离;
-
作用:分担数据库压力,提高性能,避免数据库写入影响查询效率;
-
主从复制 就是对数据库二进制日志数据,语句作备份复制;
二进制日志格式:
-
statement: 效率高,但高并发高负载可能会出现复制误差(无法精确复制)
-
row: 基于行记录; 精确度较高,效率较低,占用空间比较大;
-
mixed: 默认基于sql语句记录,高并发,负载时会采用基于行记录;
-
读写分离时基于主从复制实现的;
2.为什么要读写分离
数据库写入,影响查询效率,解决高并发问题
3.什么时候要读写分离
读多写少,高并发的时候。
4.主从复制与读写分离
主从:同步数据(对bin-log中数据,语句做备份)
读写:提升并发能力
5.mysql支持的复制类型
row
statement
mixed
6.主从复制工作过程(3线程2日志)
步骤:
-
主服务器二进制日志如果改变数据会写到二进制日志
-
从服务器会使用IO线程请求二进制事件
-
master服务器开启dump线程二进制日志发送;
-
保存到中继日志中,从服务器sql线程从rely-log读取解析SQL语句,存放..结束后io,sql线程会进入睡眠,等待下一次被唤醒。
-
中继日志位于缓存中
7.主从复制的搭建过程:
master服务器:192.168.6.170
slave服务器:192.168.6.188 , 192.168.6.169
amoeba服务器:192.168.6.156
客户端服务器:192.168.6.151
1.时间同步
expire logs days = 7 exyire loga days=7 #设置二进制日志文件过期时间,默认值为0,表示lcg:不过期
max_bin_size = 500M
#设置二进制日志限制大小,如果超出给定值,日志就公发生滚动,默认值是1GB
2.设置权限
IO线程NO原因
1.网络:
2.配置文件
3.从配置
4.防火墙
主服务器配置:
[root@yuji ~]# vim /etc/my.cnf
[mysqld]
......
server-id = 1 #指定服务ID号,master和两台slave都要不同
log-bin=mysql-bin #添加,主服务器开启二进制日志
binlog_format = MIXED #指定二进制日志(binlog)的记录格式为MIXED
log-slave-updates=true #添加,允许slave从master复制数据时可以写入到自己的二进制日志
expire_logs_days = 7 #设置二进制日志文件过期时间,默认值为0,表示logs不过期
max_binlog_size = 500M #设置二进制日志限制大小,如果超出给定值,日志就会发生滚动,默认值是1GB
#重启服务
[root@yuji ~]# systemctl restart mysqld
[root@yuji ~]# mysql -u root -p123456
#给从服务器授权
grant replication slave on *.* to 'myslave'@'192.168.6.%' identified by '123123';
flush privileges; #刷新权限
show master status; #查看主服务器状态
//显示如下
+-------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+-------------------+----------+--------------+------------------+
| mysql-bin.000001 | 602 | | |
+-------------------+----------+--------------+------------------+
1 row in set (0.00 sec)
#File 列显示日志名,Position 列显示偏移量。
主服务器配置:
配置Slave服务器:
#修改配置文件
[root@s1 ~]# vim /etc/my.cnf
[mysqld]
......
server-id = 2 #修改,注意id与Master的不同,两个Slave的id也要不同
relay-log=relay-log-bin #添加,开启中继日志,从主服务器上同步日志文件记录到本地
relay-log-index=slave-relay-bin.index #添加,定义中继日志索引文件的位置和名称,一般和relay-log在同一目录
relay_log_recovery = 1 #选配项
#当 slave 从库宕机后,假如 relay-log 损坏了,导致一部分中继日志没有处理,则自动放弃所有未执行的 relay-log,并且重新从 master 上获取日志,这样就保证了 relay-log 的完整性。默认情况下该功能是关闭的,将 relay_log_recovery 的值设置为 1 时, 可在 slave 从库上开启该功能,建议开启。
#重启服务
[root@s1 ~]# systemctl restart mysqld
#登录数据库,进行同步设置
[root@s1 ~]# mysql -u root -p
CHANGE master to master_host='192.168.6.170',master_user='myslave',master_password='123123',master_log_file='mysql-bin.000001',master_log_pos=602;
#配置同步,注意 master_log_file 和 master_log_pos 的值要与Master查询的一致
start slave; #启动同步,如有报错执行 reset slave;
show slave status\G #查看 Slave 状态
##确保 IO 和 SQL 线程都是 Yes,代表同步正常。
Slave_IO_Running: Yes #负责与主机的IO通信
Slave_SQL_Running: Yes #负责自己的slave mysql进程
##一般 "Slave_IO_Running: No" 的可能原因:
1. 网络不通
2. my.cnf配置有问题(server-id重复)
3. 密码、file文件名、pos偏移量不对
4. 防火墙没有关闭
slave服务器配置都一样sever id不同
保证两个从服务器IO线程都开启
主从复制效果展示:
二.读写分离
1.mysql读写分离原理:
1.主写从读
2.主处理事务性操作(增删改操作),,从查询(select)
3.主操作变更同步到集群当中
2.mysql读写分离分为两种:
1.基于程序代码内部
性能好,不需要额外的硬件开支
大型复杂java应用对代码改动较大
2.基于中间代理层
3.MySQL中间件
mysql-proxy(lua脚本开发)
Atlas(奇虎360)支持事务(一致性),存储过程
mycat(java开发)分库分表 市场用的多
Amoeba(阿米巴变形虫java开发)市场用的多
4.amoeba应用
1.jdk环境
2.安装amoeba
3.主从授权
4.修改配置文件
Amoeba服务器配置:
1)安装 Java 环境
#因为 Amoeba 基于是 jdk1.5 开发的,所以官方推荐使用 jdk1.5 或 1.6 版本,高版本不建议使用。
#先将jdk的二进制文件上传到/opt/目录下,之后复制到/usr/local/目录下
[root@Amo ~]# cd /opt/
[root@Amo opt]# cp jdk-6u14-linux-x64.bin /usr/local/
[root@Amo opt]# cd /usr/local/
[root@Amo local]# chmod +x jdk-6u14-linux-x64.bin #为二进制文件增加执行权限
[root@Amo local]# ./jdk-6u14-linux-x64.bin
##按yes,按enter
[root@Amo local]# mv jdk1.6.0_14/ /usr/local/jdk1.6 #将jdk目录重命名
#添加环境变量
[root@Amo local]# vim /etc/profile
export JAVA_HOME=/usr/local/jdk1.6
export CLASSPATH=.:$JAVA_HOME/lib:$JAVA_HOME/jre/lib
export PATH=$JAVA_HOME/bin:$JAVA_HOME/jre/bin:$PATH
export AMOEBA_HOME=/usr/local/amoeba
export PATH=$PATH:$AMOEBA_HOME/bin
[root@Amo local]# source /etc/profile #刷新文件,使立即生效
[root@Amo local]# java -version #查看jdk版本
2)安装 Amoeba软件
-------1、安装 Amoeba软件---------
#创建Amoeba的解压目录
[root@Amo ~]# mkdir /usr/local/amoeba/
#将Amoeba安装包上传到/opt/目录,解压安装包
[root@Amo opt]# cd /opt/
[root@Amo opt]# tar zxvf amoeba-mysql-binary-2.2.0.tar.gz -C /usr/local/amoeba/
#增加目录权限
[root@Amo opt]# chmod -R 755 /usr/local/amoeba/
#开启Amoeba
[root@Amo opt]# /usr/local/amoeba/bin/amoeba #如显示amoeba start|stop说明安装成功
-------2、配置 Amoeba读写分离,两个 Slave 读负载均衡----------
#先在Master、Slave1、Slave2 的mysql上开放权限给 Amoeba 访问。注意:这里授权的用户名和密码,会在下一步写入数据库配置文件。
grant all on *.* to zhangsan@'192.168.6.%' identified by 'abc123';
#再回到amoeba服务器配置amoeba服务:
[root@Amo opt]# cd /usr/local/amoeba/conf/
#备份配置文件,修改amoeba配置文件
[root@Amo conf]# cp amoeba.xml amoeba.xml.bak
[root@Amo conf]# vim amoeba.xml
--30行--
<property name="user">amoeba</property> #30行和32行,授权客户端用于登录amoeba的账号和密码
--32行--
<property name="password">123456</property>
--115行--
<property name="defaultPool">master</property> #设置默认服务器池
--117-去掉注释-
<property name="writePool">master</property> #定义写的服务器池名称
<property name="readPool">slaves</property> #定义读的服务器池名称
#备份数据库配置文件,之后修改数据库配置文件dbServers.xml
[root@Amo conf]# cp dbServers.xml dbServers.xml.bak
[root@Amo conf]# vim dbServers.xml
--23行--注释掉 作用:默认进入test库,注释掉以防mysql中没有test库时,会报错
<!-- <property name="schema">test</property> -->
##26-30行,此用户就是之前在3台主从服务器上授权的用户,授权amoeba服务器用来登录mysql数据库的用户和密码。
--26行--修改
<property name="user">zhangsan</property>
--28-30行--去掉注释
<property name="password">abc123</property>
--45行--修改,设置主服务器的名称master和地址
<dbServer name="master" parent="abstractServer">
--48行--修改,设置主服务器的地址
<property name="ipAddress">192.168.6.170</property>
--52行--修改,设置从服务器1的名称slave1
<dbServer name="slave1" parent="abstractServer">
--55行--修改,设置从服务器1的地址
<property name="ipAddress">192.168.6.169</property>
--58行--复制上面6行粘贴,设置从服务器2的名称slave2和地址
<dbServer name="slave2" parent="abstractServer">
<property name="ipAddress">192.168.6.188</property>
--65行--修改
<dbServer name="slaves" virtual="true">
--71行--修改
<property name="poolNames">slave1,slave2</property>
[root@Amo conf]# /usr/local/amoeba/bin/amoeba start & #后台启动Amoeba软件,按ctrl+c 返回
[root@Amo conf]# netstat -anpt | grep java #查看8066端口是否开启,默认端口为TCP 8066
客户端安装mariadb数据库
[root@yuji ~]# yum install -y mariadb-server mariadb #安装mariadb数据库
[root@yuji ~]# systemctl start mariadb.service #启动mariadb
#客户端通过amoeba服务器登录数据库,之后向库中写入数据:
mysql -u amoeba -p123456 -h 192.168.6.156 -P8066
create table class(id int,name char(10)); #通过amoeba服务器代理访问mysql ,再通过客户端连接mysql后写入的数据只有主服务会记录,然后同步给从--从服务器出处。
5.实现效果:
1.主服务器进行写操作
2.从服务器进行读操作
3.关闭slave机,即关掉了主从复制,就不会同步主机的数据
客户端读取时,会只读取slave的数据,主机写的数据也不会读到,关掉从服务器会根据轮询调度算法进行读取从服务器数据。