mysql的主从复制和读写分离
Posted 遙遙背影暖暖流星
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了mysql的主从复制和读写分离相关的知识,希望对你有一定的参考价值。
主从复制和读写分离
一,mysql的主从分离
主从同步的工作原理:主服务器一定要开启的binog 二进制日志,当一台服务器被设置为从服务器时,则会默认的开启I/O线程和SQL ,dump线程检测binlog日志的变化,线程I/O负责将主服务器binarylog日志中的sql语句,拷贝到本服务器中的relaylog中继日志中,再由从服务器的sql线程读取执行中继日志的sql命令,写到从服务器中。
构建思路
-主:启用binlog日志,授权用户,查看binlog日志信息
-从:确保与主服务器数据一致,配置从服务器,配置server.id,开启中继日志,启动slave程序
实验环境
主:192.168.100.7
从1:192.168.100.5
从2:192.168.100.6
三台机器都安装了mysql5.7版本,并初步优化(具体查看:https://blog.csdn.net/lv74134/article/details/118149487?spm=1001.2014.3001.5501 中mysql安装步骤)
同步时间
主服务器:
systemctl stop firewalld.service
systemctl disable firewalld.service
setenfoce 0
#关闭防火墙
yum install -y ntp
yum install -y ntpdate
vim /etc/ntp.conf
......................
fudge 127.127.1.0 stratum 10
#设置本机的时间层级为10级,0级表示时间层级为0级,是向其他服务器提供时间同步源的意思,不要设置为0级
server 127.127.1.0 #设置本机为时间同步源
wp
.......................
systemctl start ntpd #开启ntpd
ntpdate ntp.aliyun.com #与网络同步时间
从服务器:
systemctl stop firewalld.service
systemctl disable firewalld.service
setenfoce 0
#关闭防火墙
yum install -y ntp
yum install -y ntpdate
vim /etc/ntp.conf
......................
fudge 127.127.1.0 stratum 10
#设置本机的时间层级为10级,0级表示时间层级为0级,是向其他服务器提供时间同步源的意思,不要设置为0级
server 127.127.1.0 #设置本机为时间同步源
wp
.......................
systemctl start ntpd #开启ntpd
ntpdate 192.168.100.7 #与主服务器同步时间
crontab -e
*/30 * * * * /usr/sbin/ntpdate 192.168.100.7
#定时同步时间,避免数据同步时时间发生错乱,但数据写入大的时候可缩短时间间隔
1、配置三台主机的配置文件
主:vim /etc/my.info
server-id = 7 #id为7,注意不要和其他服务器重复
log-bin=master-bin
log_slave-updates=true #插入这三行,开启binlog日志
systemctl restart mysql.service
从1:vim /etc/my.info
server-id = 5
log_bin=mysql-bin
relay-log=relay-log-bin
relay-log-index=slave-relay-bin.index #开启了中继日志
systemctl restart mysql.service
从2:vim /etc/my.info
server-id = 6
log_bin=mysql-bin
relay-log=relay-log-bin
relay-log-index=slave-relay-bin.index #开启了中继日志
systemctl restart mysql.service
2、主服务创建和授权用户
主:
[root@slave1 mysql-5.6.26]# mysql -uroot -p
Enter password:
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000001 | 154 | | | |
+------------------+----------+--------------+------------------+-------------------+
mysql> change master to master_host='192.168.100.7',master_user='myslave',master_password='123456',master_log_file='master-bin.000001',master_log_pos=154;
#添加主服务器
3、开启服务主服务器
主:
mysql>grant replication slave on *.* to 'myslave'@'192.168.100.%' identified by '123456'; #建设用户myslave用户,并设置权限
mysql>flush privileges; #刷新权限表
mysql> show master status;
+-------------------+----------+--------------+------------------+-------------- -----+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid _Set |
+-------------------+----------+--------------+------------------+-------------- -----+
| master-bin.000001 | 604 | | | |
+-------------------+----------+--------------+------------------+-------------- -----+
# 日志节点是604!
5、同步旧数据库
假如三台机子都是刚安装的可以省略这一步,跳到下一步;
[root@master ~]#mysqldump -u root -p123456 --all-databases > /opt/all-databases
#主服务机上完全备份所有库
[root@slave ~]#spc root@192.168.100.7:/opt/all-databases /opt/ #在服务器下载到/opt/下
mysql -u root -p
->source /opt/all-databases; #生成所有表
6、开启从服务器的内容
从1和从2上
mysql> change master to master_host='192.168.100.7',master_user='myslave',master_password='123456',master_log_file='master-bin.000001',master_log_pos=604;
#添加主服务器
mysql> start slave; #开启
Query OK, 0 rows affected (0.01 sec)
mysql> show slave status\\G; #查收服务状态是否开启
mysql> show slave status\\G;
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.100.7
Master_User: myslave
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: master-bin.000001
Read_Master_Log_Pos: 604
Relay_Log_File: relay-log-bin.000002
Relay_Log_Pos: 321
Relay_Master_Log_File: master-bin.000001
Slave_IO_Running: 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: 604
Relay_Log_Space: 526
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: 7
Master_UUID: 66bc9052-d3bc-11eb-8aad-000c29d54c7a
Master_Info_File: /usr/local/mysql/data/master.info
SQL_Delay: 0
SQL_Remaining_Delay: NULL
Slave_SQL_Running_State: Slave has read all relay log; waiting for more upda
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)
7,开启测试
主:
mysql> show databases; #查看现有的库
+--------------------+
| Database |
+--------------------+
| information_schema |
| bbc |
| bbs |
| class |
| kgc |
| mysql |
| performance_schema |
| shcool |
| sys |
| xiyou |
| yidong |
+--------------------+
mysql> create database yyds; #创建一个表
Query OK, 1 row affected (0.00 sec)
在从上看是否同步
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| bbc |
| bbs |
| class |
| kgc |
| mysql |
| performance_schema |
| shcool |
| sys |
| xiyou |
| yidong |
| yyds |
+--------------------+
12 rows in set (0.00 sec)
二、读写分离
一台客户端,一台amoeba作为代理服务器(实现读写分离),三台主从复制的服务器
原理:
读写分离就是只在主服务器上写,只在从服务器上读。基本的原理是让主数据库处理事务性查询,而从数据库处理select查询。数据库主从复制被用来把主数据库上事务性查询导致的变更同步到集群中的从数据库。
问题来了,为什么要数据库的读写分离呢?
因为数据库的"写”(写10000条数据可能要3分钟)操作是比较耗时的。但是数据库的"读”(读10000条数据可能只要5秒钟)。
所以读写分离,解决的是,避免数据库的写入,影响了查询的效率
那什么时候用到读写呢?
其实数据库不一定都要执行读写分离,如果程序使用数据库较多,且更新少查询多的情况下可以使用。理由数据库的主从同步,再通过读写分离分担数据的压力,提高性能
实现方式:
常见的MysQL读写分离分为以下两种:
1基于程序代码内部实现
在代码中根据select、insert进行路由分类,这类方法也是目前生产环境应用最广泛的。
优点是性能较好,因为在程序代码中实现,不需要增加额外的设备为硬件开支;缺点是需要开发人员来实现,运维人员无从下手。
但是并不是所有的应用都适合在程序代码中实现读写分离,像一些大型复杂的Java应用,如果在程序代码中实现读写分离对代码改动就较大。
2、通过中间代理层实现
代理一般位于客户端和服务器之间,代理服务器接到客户端请求后通过判断后转发到后端数据库,有以下代表性程序。
(1) MySQL-Proxy。MySQL-Proxy为 MySQL开源项目,通过其自带的 lua脚本进行SQL判断。
(2) Atlas是由奇虎360的web平台部基础架构团队开发维护的一个基于MysoL协议的数据中间层项目。它是在mysql-proxy0.8.2版本的基础上,对其进行了优化,增加了一些新的功能特性。360内部使用Atlas运行的mysql业务,每天承载的读写请求数达几十亿条。支持事物以及存储过程。
(3) Amoeba。由陈思儒开发,作者曾就职于阿里巴巴。该程序由Java语言进行开发,阿里巴巴将其用于生产环境。但是它不支持事务和存储过程。
amoeba的介绍:
Amoeba:是一个以Mysql为底层数据存储,并对应提供MysQL协议接口的proxy(代理),外号变形虫读取请求发送给从服务器是,采用轮询调度算法
amoeba使用的java语言编写,配置文件为xml
amoeba主要负责对外的一个代理IP,访问这个IP时,发送的请求为"写"请求,则会转给主服务器,读则通过轮询算法,轮流转发到两台从服务器。
amoeba还可以视为的的调度器,结合MHA解决的主服务器单点故障问题
实验环境:
主:192.168.100.7
从1:192.168.100.5
从2:192.168.100.6
三台机器都安装了mysql5.7版本,并初步优化(具体查看:https://blog.csdn.net/lv74134/article/details/118149487?spm=1001.2014.3001.5501 中mysql安装步骤)
客户端:192.168.100.3 #安装了mariadb
amoeba代理服务器:192.168.100.8 #安装了amoeba
一、安装
1、安装java环境
jdk-6u14-linux-x64.bin和amoeba-mysql-binary-2.2.0.tar.gz上传的到/opt 下
[root@amoeba opt]# cp jdk-6u14-linux-x64.bin /usr/local/
[root@amoeba opt]# cd /usr/local/
[root@amoeba local]# chmod +x jdk-6u14-linux-x64.bin
[root@amoeba local]# ./jdk-6u14-linux-x64.bin
Sun Microsystems, Inc. Binary Code License Agreement
for the JAVA SE DEVELOPMENT KIT (JDK), VERSION 6
SUN MICROSYSTEMS, INC. ("SUN") ....
Do you agree to the above license terms? [yes or no]
Press Enter to continue.....
Done.
#阅读完说明,输入yes,然后回车
[root@amoeba local]# mv jdk1.6.0_14/ /usr/local/jdk1.6 #改个名字,便于管理
[root@amoeba local]# ls
bin games jdk1.6 lib libexec sbin src
etc include jdk-6u14-linux-x64.bin lib64 mysql share
2、优化环境变量
[root@amoeba local]# vim /etc/profile
export JAVA_HOME=/usr/local/jdk1.6
export CLASSPATH=$CLASSPATH:$JAVA_HOME/lib:$JAVA_HOME/jre/lib
export PATH=$JAVA_HOME/lib:$JAVA_HOME/jre/bin/:$PATH:$HOME/bin
export AMOEBA_HOME=/usr/local/amoeba
export PATH=$PATH:$AMOEBA_HOME/bin
[root@amoeba local]# source /etc/profile
[root@amoeba local]# echo $PATH
/usr/local/jdk1.6/lib:/usr/local/jdk1.6/jre/bin/:/usr/java/jdk1.8.0_201-amd64/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin:/root/bin:/usr/local/amoeba/bin
3、安装amoeba
[root@amoeba local]# mkdir /usr/local/amoeba
[root@amoeba local]# cd /opt
[root@amoeba opt]# tar zxvf amoeba-mysql-binary-2.2.0.tar.gz -C /usr/local/amoeba/
[root@amoeba opt]# chmod -R 755 /usr/local/amoeba/
[root@amoeba opt]# /usr/local/amoeba/bin/amoeba
amoeba start|stop
说明安装成功
4,修改配置
4.1三台数据库服务器进行提权
mysql> grant all on *.* to test@'192.168.100.%' identified by '123.com';
Query OK, 0 rows affected (0.01 sec)
#放权给amoeba进行访问
myslave ——》用于slave来同步
test ——》用于amoeba访问数据库
amoeba ——》用于client端访问amoeba的身份
4.2 修改amoeba主配置文件
[root@amoeba conf]# cd /usr/local/amoeba/conf
[root@amoeba conf]# cp amoeba.xml amoeba.xml.bak #修改配置文件记得先备份
[root@amoeba conf]# ls
access_list.conf amoeba.xml dbserver.dtd function.dtd log4j.dtd rule.dtd rule.xml
amoeba.dtd amoeba.xml.bak dbServers.xml functionMap.xml log4j.xml ruleFunctionMap.xml
[root@amoeba /opt]# cd /usr/local/amoeba/conf/
[root@amoeba amoeba]# vim conf/amoeba.xml
<property name="user">amoeba</property>
#30行,这里是外部访问amoeba服务器时使用的账号
<property name="password">123123</property>
#32行,这里是数据库或者外部访问amoeba服务器时使用账号时用的密码
<property name="defaultPool">master</property> #修改默认池
<!-- --> #17添加-->,删掉下面那个-->,取消注释的作用
<property name="writePool">master</property>
<property name="readPool">slavesMySQL主从复制及读写分离实际部署与验证