文章目录
一、MySQL主从复制与读写分离概述
1.1 MySQL使用主从复制与读写分离的原因
- 在企业应用中,成熟的业务通常数据量都比较大
- 单台MySQL在安全性、高可用性和高并发方面都无法满足实际的需求
(myisam基于表级锁定;innodb基于行级锁定 --存储引擎不能满足并发读、写的需求) - 配置多台主从数据库服务器以实现读写分离
1.2 MySQL主从复制原理
- 基于语句的复制
- 基于行的复制
- 混合类型的复制(语句、行、日志文件)
1.3 MySQL读写分离原理
- 只在主服务器上写,只在从服务器上读
- 主数据库处理事务性查询,从数据库处理select查询
- 数据库复制用于将事务性查询的变更同步到集群中的从数据库
- 复制的基本过程如下:
- Master将用户对数据库更新的操作以二进制格式保存到Binary Log日志文件中;
- Slave上面的IO进程连接上Master,并请求从指定日志文件的指定位置(或者从最开始的日志)之后的日志内容;
- Master接收来自Slave的IO进程的请求后,通过负责复制的IO进程根据请求信息读取制定日志指定位置之后的日志信息,返回给Slave的IO进程。返回信息中除了日志所包含的信息之外,还包括本次返回的信息已经到Master端的bin-log文件的名称以及bin-log的位置;
- Slave的IO进程接收到信息后,将接收到的日志内容依次添加到Slave端的relay-log文件的最末端,并将读取到的Master端的bin-log的文件名和位置记录到master-info文件中,以便在下一次读取的时候能够清除的告诉Master“我需要从某个bin-log的哪个位置开始往后的日志内容,请发给我”;
- SlaveSql进程检测到relay-log中新增了内容后,会马上解析relay-log的内容称为在Master端真实执行时候的那些可执行的内容,并在自身执行。
二、MySQL读写分离配置过程
2.1 时间同步
在其中一台服务器上面做时间同步服务
systemctl stop firewalld
setenforce 0
yum -y install ntpdate
ntpdate ntp.aliyun.com
vi /etc/ntp.conf
:8 restrict default nomodify
:17 restrict 192.168.1.0 mask 255.255.255.0 nomodify notrap
:21 #server 0.centos.pool.ntp.org iburst # 21-24可以直接删除 4dd
:22 #server 1.centos.pool.ntp.org iburst
:23 #server 2.centos.pool.ntp.org iburst
:24 #server 3.centos.pool.ntp.org iburst
server 127.127.1.0 # 在上面删除的下面直接添加该两行
fudge 127.127.1.0 stratum 8 # 设置本机的时间层级为8,最小为0,不要设置0级
systemctl restart ntpd
-
另外的服务器可以通过命令ntpdate 192.168.10.15来同步时间日期
-
因为需要定时同步,所以最好使用任务计划来定时同步时间
crontab -e */10 * * * * /usr/sbin/ntpdate net.aliyun.com # 在时间同步服务器上面设置 */10 * * * * /usr/sbin/ntpdate 192.168.10.15 # 在时间同步的其他主机上设置
2.2 主从同步
-
主服务器上面需要配置以下内容:
vi /etc/my.cnf server-id = 1 # id需要不同 log_bin = master-bin # 主服务器日志文件 log_slave_update = true # 允许中继日志读取主服务器的二进制日志 systemctl restart mysqld cd /usr/local/mysql/date/ ll
mysql -uroot -p123456
mysql> grant replication slave on *.* to 'myslave'@'192.168.10.%' identified by '123456';
mysql> flush privileges;
mysql> show master status;
需要记下Filetid_Set值与Position值,方便后面的使用。
-
每台从服务器上面的配置:
vi /etc/my.cnf server-id = 2 relay-log=relay-log-bin ##从主服务器上同步日志文件记录到本地中继日志 relay-log-index=slave-relay-bin.index ##定义中继日志的索引 mysql -uroot -p123456 mysql> change master to master_host='192.168.10.15',master_user='myslave',master_password='123456',master_log_file='master-bin.000001',master_log_pos=603; mysql> start slave; mysql> show slave status\G
此时完成了主从复制的功能:
而从服务器上面关闭了slave服务后,输入的内容将不再复制到从服务器上。
2.3 读写分离
-
部署java环境
tar zxf jdk-8u91-linux-x64.tar.gz cp -rv jdk1.8.0_91/ /usr/local/java vi /etc/profile export JAVA_HOME=/usr/local/java export JRE_HOME=/usr/local/java/jre export PATH=$PATH:$JAVA_HOME/bin:$JRE_HOME/bin export CLASSPATH=./:$JAVA_HOME/lib:$JRE_HOME/lib source /etc/profile #导入到环境变量中,使其生效 echo $PATH echo $CLASSPAYH java -version #查看版本
-
部署amoeba代理
unzip amoeba-mysql-3.0.5-RC-distribution.zip mv amoeba-mysql-3.0.5-RC /usr/local/amoeba chmod -R 755 /usr/local/amoeba/ chmod -R 755 /usr/local/amoeba/ vi /usr/local/amoeba/jvm.properties :32 #JVM_OPTIONS="-server -Xms256m -Xmx1024m -Xss196k -XX:PermSize=16m -XX:MaxPermSize=96m" JVM_OPTIONS="-server -Xms1024m -Xmx1024m -Xss256k"
-
在MySQl服务器上面为amoeba赋予权限
mysql> grant all on *.* to 'test'@'192.168.10.%' identified by '123456'; # 赋予权限 mysql> flush privileges; # 更新权限 mysql> show grants for 'test'@'192.168.10.%'; # 查看赋予给指定用户,主机的权限
-
修改amoeba主配置文件 amoeba.xml 文件
vi /usr/local/amoeba/conf/amoeba.xml :28 <property name="user">amoeba</property> :30 <property name="password">123456</property> :83 <property name="defaultPool">master</property> :85 <!-- # 为注释,需要删除行 :86 <property name="writePool">master</property> :87 <property name="readPool">slaves</property> :88 -- > # 为注释,需要删除行
-
修改 dbServer.xml 文件
vi /usr/local/amoeba/conf/dbServer.xml :23 <!-- mysql schema --> :24 <property name="schema">mysql</property> # 5.7版本没有默认的test数据库,需要手动指定mysql数据库 :26 <!-- mysql user --> :27 <property name="user">test</property> :41 </dbServer> <dbServer name="master" parent="abstractServer"> <factoryConfig> <!-- mysql ip --> <property name="ipAddress">192.168.10.15</property> </factoryConfig> </dbServer> <dbServer name="slave1" parent="abstractServer"> <factoryConfig> <!-- mysql ip --> <property name="ipAddress">192.168.10.16</property> </factoryConfig> </dbServer> <dbServer name="slave2" parent="abstractServer"> <factoryConfig> <!-- mysql ip --> <property name="ipAddress">192.168.10.19</property> </factoryConfig> </dbServer> <dbServer name="slaves" virtual="true"> …… <property name="poolNames">slave1,slave2</property>
-
启动amoeba服务器进行测试
/usr/local/amoeba/bin/launcher [root@server1 conf]# netstat -anpt | grep 8066 tcp6 0 0 :::8066 :::* LISTEN 1961/java yum -y install mariadb* systemctl start mariadb.service systemctl status mariadb.service mysql -uamoeba -p123456 -h 192.168.10.11 -P8066
-
2.4 实验验证
- 在amoeba服务器上面添加的表,是写入到主服务器上的,不会写到从服务器上面,但是因为主从复制的原因,所以如果从服务器上面开启了slave,则可以在上面读取到数据;
- 读写分离
我们可以再从服务器上面分别输入不同的表数据,通过amoeba服务器上面查看,可以查看到不同的结果,看出读取的数据来自于从服务器,写入的数据写入到主服务器上面。