0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299  MySQL主从复制+读写分离原理及配置实例
英语文化交流 > 技术博客 > MySQL主从复制+读写分离原理及配置实例
MySQL主从复制+读写分离原理及配置实例
时间: 分类:技术博客

博文大纲:
一、MySQL主从复制原理
二、MySQL读写分离原理
三、搭建MySQL主从复制及读写分离

一、MySQL主从复制原理:

MySQL的主从复制和MySQL的读写分离两者不分家,基于主从复制的架构才可实现数据的读写分离。

1、MySQL支持的复制类型:
(1)基于语句的复制。顾名思义就是在主服务器上执行的SQL语句,在从服务器上执行同样的语句。MySQL默认采用这种方式的复制,效率比较高。
(2)基于行的复制。把改变的内容复制过去,而不是把命令再从主服务器上执行一遍。
(3)混合类型的复制。默认采用基于语句的复制,一旦发现基于语句无法精确复制时,就会采用基于行的复制。

以上三种复制类型,不需要人为干预,MySQL数据库会自动控制。

2、复制的工作过程,如下图所示:

MySQL主从复制+读写分离原理及配置实例

(1)在每个事物更新数据完成之前,master在二进制日志记录这些改变。写入二进制日志完成后,master通知存储引擎提交事务。

(2)slave将master的Binary log复制到其中继日志。首先slave开始一个工作线程——I/O线程,I/O线程在master上打开一个普通的连接,然后开始Binlog dump process(Binlog转储过程),Binlog dump process从master的二进制日志中读取事件,如果已经跟上master,它会睡眠并等待master产生新的事件。I/O线程将这些事件写入中继日志。

(3)SQL slave thread(SQL从线程)处理该过程的最后一步。SQL线程从中继日志读取事件,并重放其中的事件而更新slave的数据,使其与master中的数据一致。只要该线程与I/O现场曾保持一致,中继日志通常存在系统的缓存中,所以中继日志的开销很小。

复制过程有一个很重要的限制,就是在slave上的复制是串行化的,master上时并行化的。说白了就是,有可能一些数据更新是多条SQL语句同时在master上进行的,但slave进行复制时,只能一条一条的执行SQL语句进行数据同步。

二、MySQL读写分离原理:

简单来说,就如下图一样,就是只在主服务器上写,只在从服务器上读。基本的原理是让主数据库处理数据写入、更新操作,而从数据库处理select查询操作。

MySQL主从复制+读写分离原理及配置实例

较为常见的MySQL读写分离分为两种:

1、基于程序代码内部实现:在代码中根据select、insert语句进行路由分类,这类方法目前在生产环境中应用最广泛。优点是性能较好,因为在程序代码中实现,不需要增加额外的设备作为硬件开支;缺点是需要开发人员来实现,我们运维无从下手。

2、基于中间代理实现:代理位于客户端和MySQL服务器之间,代理服务器接到客户端的请求后通过判断后转发到后端数据库。中间代理有两个代表性程序:MySQL-Proxy和amoeba(变形虫)。

二者区别如下:

MySQL-Proxy是MySQL开源项目,通过自带的lua脚本进行SQL判断,虽然是MySQL官方产品,但是MySQL官方并不建议将其应用到生产环境。

amoeba使用Java语言进行开发,阿里巴巴将其用于生产环境,它不支持事务和存储过程。

虽然通过程序代码实现MySQL读写分离是一个很好的选择,但并不是所有的应用都适合在程序代码中实现读写分离,一些大型复杂的Java应用,如果在程序代码中实现读写分离对代码的改动就比较大。所以,大型复杂的应用一般都会考虑使用代理层来实现。

三、搭建MySQL主从复制及读写分离

环境如下:

MySQL主从复制+读写分离原理及配置实例

1、部署前准备:

(1)我这里所有服务器均使用centos 7。
(2)下载部署MySQL所需软件包:下载链接,提取码:2z5k
(3)准备系统映像,自行配置本地yum仓库。下载搭建读写分离所需软件:下载amoeba及JDK链接,提取码:ulz3 。
(4)应用客户端为了测试效果,必须可以使用mysql命令,所以也需要安装mysql,为了方便,安装系统映像自带的mysql即可。
(5)自行配置网络环境,确保网络互通,防火墙放行相关端口的流量,我这里为了方便,直接关闭了防火墙。

2、部署MySQL数据库(在主/从节点共三台服务器上都需要部署MySQL数据库,将以下部署过程分别在三台服务器上执行一遍)

(1)为了避免发生程序冲突、端口冲突等问题,可以先执行以下命令,进行删除系统自带的mysql程序:


[root@localhost ~]# yum -y erase mysql

(2)挂载centos系统盘,安装ncurses-devel包:

[root@localhost ~]# mount /dev/cdrom /media
[root@localhost ~]# cd /media/Packages/
[root@localhost Packages]# rpm -ivh ncurses-devel-5.9-14.20130511.el7_4.x86_64.rpm 

(3)由于mysql 5.x系列版本需要cmake编译安装,所以继续安装cmake包:


[root@localhost media]# tar zxf cmake-2.8.6.tar.gz -C /tmp                 #解包
[root@localhost media]# cd /tmp/cmake-2.8.6/
[root@localhost cmake-2.8.6]# ./configure && gmake && gmake install      #配置,编译安装

(4)创建专门用来运行mysql服务的用户,此用户不需要直接登录到系统:

[root@localhost cmake-2.8.6]# groupadd mysql
[root@localhost cmake-2.8.6]# useradd -M -s /sbin/nologin mysql -g mysql

(5)将下载的mysql源码包解压,并进行配置,编译及安装(千万要注意大小写,不要打错配置项,就算错误也可以继续后续的安装,但是,最后服务是无法启动的,千万不要打错字母,千万不要打错字母,千万不要打错字母,重要的事情说三遍):

[root@localhost media]#tar zxf mysql-5.6.36.tar.gz -C /tmp              #解压至/tmp目录
[root@localhost cmake-2.8.6]# cd /tmp/mysql-5.6.36             #切换至展开后的源码目录
[root@localhost mysql-5.6.36]# cmake -DCMAKE_INSTALL_PREFIX=/usr/local/mysql 
-DSYSCONFDIR=/etc -DDEFAULT_CHARSET=utf8 
-DDEFAULT_COLLATION=utf8_general_ci -DWITH_EXTRA_CHARSETS=all
[root@localhost mysql-5.6.36]# make && make install          #编译并安装

(6)对数据库目录进行权限设置:

[root@localhost mysql-5.6.36]# chown -R mysql:mysql /usr/local/mysql

(7)建立配置文件:

centos 7系统下默认支持MariaDB数据库,因此系统默认的/etc/my.cnf配置文件中是MariaDB的配置文件,而在mysql的源码目录中提供了mysql数据库默认的样本配置文件,在启动mysql数据库之前,需要先将原有的my.cnf文件替换为mysql提供的配置文件内容。

[root@localhost mysql-5.6.36]# rm -rf /etc/my.cnf              #删除原有配置文件
[root@localhost mysql-5.6.36]# cp support-files/my-default.cnf /etc/my.cnf     
#复制源码包中的配置文件到/etc/下

(8)初始化数据库(若数据库初始化时配置错误的话,将mysql安装目录中的data目录删掉后重新初始化即可):

[root@localhost mysql-5.6.36]# /usr/local/mysql/scripts/mysql_install_db --user=mysql 
--basedir=/usr/local/mysql --datadir=/usr/local/mysql/data 

(9)设置环境变量(为了方便在任何目录下使用mysql命令):

[root@localhost mysql-5.6.36]# echo "PATH=$PATH:/usr/local/mysql/bin" >> /etc/profile
[root@localhost mysql-5.6.36]# .  /etc/profile             #立即生效

(10)当对/usr/local/mysql/bin/mysqld.sh 赋予执行权限后,继续以下操作:

[root@localhost mysql-5.6.36]# cp support-files/mysql.server /usr/local/mysql/bin/mysqld.sh   
#复制到安装目录中
[root@localhost mysql-5.6.36]# chmod +x /usr/local/mysql/bin/mysqld.sh         
#赋予执行权限
[root@localhost mysql-5.6.36]# cp /usr/local/mysql/bin/mysqld.sh /etc/init.d/mysqld
[root@localhost mysql-5.6.36]# vim /etc/init.d/mysqld 

MySQL主从复制+读写分离原理及配置实例

修改后,保存退出。继续执行如下命令:

[root@localhost mysql-5.6.36]# chkconfig --add mysqld            #添加为系统服务

11、启动服务并查看mysql服务器状态:

[root@localhost mysql-5.6.36]# systemctl start mysqld                #启动服务
[root@localhost mysql-5.6.36]# systemctl status mysqld             #查看服务状态是否正常

3、开始搭建MySQL主从复制:

(1)建立时间同步环境:

①在MySQL主服务器上搭建时间同步服务器(关于ntp时间同步,安装系统时,一般都安装了该服务,可以在执行下面的yum操作之前,主服务器使用rpm -qa | grep ntp进行查询,从服务器使用rpm -qa | grep ntpdate查询,若已安装,则可省略下面的yum安装步骤)。

[root@master ~]# yum -y install ntp            #安装ntp
#若服务器可连接Internet,直接yum安装即可;
#若无法连接,自行配置本地yum仓库,系统盘有相关软件包。
[root@master ~]# vim /etc/ntp.conf     #添加下面两行配置,从而设置时区。
server 127.127.1.0            #添加到任意位置即可
fudge 127.127.1.0 stratum 8
#添加后,保存退出即可。
[root@master ~]# systemctl restart ntpd                   #重启服务
[root@master ~]# systemctl enable ntpd                  #设置开机自启动

②在slave1和slave2分别执行以下操作,从而配置时间同步。(由于两台从节点有很多相同的配置,为了方便,我会将两台从节点一样的配置,只写一遍,自行在两台服务器上分别配置即可)。

[root@slave1 ~]# yum -y install ntpdate           #安装ntpdate。
[root@slave1 ~]# ntpdate 192.168.1.1

(2)配置MySQL master主服务器:

[root@master ~]# vim /etc/my.cnf       #编辑MySQL主配置文件,修改或增加下面配置
log_bin = master-bin           #修改
log-slave-updates = true     #增加
server_id = 11              #修改
[root@master ~]# systemctl restart mysqld
[root@master ~]# mysql -u root -p                 #登录MySQL
Enter password:               #输入密码
mysql> grant replication slave on *.* to 'myslave'@'192.168.1.%' identified by '123456';
#授权一个账户,以便从服务器连接使用
mysql> flush privileges;
mysql> show master status;
+-------------------+----------+--------------+------------------+-------------------+
| File              | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+-------------------+----------+--------------+------------------+-------------------+
| master-bin.000001 |      410 |              |                  |                   |
+-------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

#其中file列显示日志名,Position列显示偏移量,这两个值在后面配置从服务器时使用。
#这两个值还需根据自己查询出来的实际来变,你们可能和我这里查询出的不一样。

(3)分别配置slave1和slave2从服务器(两台slave服务器都执行一遍以下的操作):

[root@slave1 ~]# vim /etc/my.cnf                #更改或增加以下内容
server_id = 22 #修改,该id号不可和其他主/从服务器重复,另一从服务器我配置成“33”了
relay-log=relay-log-bin                #增加
relay-log-index=slave-relay-bin.index               #增加
#编辑好上面三号,保存退出即可。
[root@slave1 ~]# systemctl restart mysqld           #重启MySQL
[root@slave1 ~]# mysql -u root -p            #登录到数据库
Enter password:          #输入密码
mysql> change master to master_host='192.168.1.1',master_user='myslave',master_password='123456',master_log_file='master-bin.000001',master_log_pos=410;
#指定主服务器及日志文件位置,并指定使用哪个用户连接主服务器。
Query OK, 0 rows affected, 2 warnings (0.01 sec)
mysql> start slave;               #启动同步
Query OK, 0 rows affected (0.01 sec)
mysql> show slave status\G               #查看slave状态,确保下面两个值为“yes”。
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.1.1
                  Master_User: myslave
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: master-bin.000001
          Read_Master_Log_Pos: 410
               Relay_Log_File: relay-log-bin.000002
                Relay_Log_Pos: 284
        Relay_Master_Log_File: master-bin.000001
             Slave_IO_Running: Yes            #这个值要为“yes”。
            Slave_SQL_Running: Yes           #这个值也要为“yes”。
              Replicate_Do_DB: 
          Replicate_Ignore_DB: 
                           ...........................  #省略部分内容

至此,主从复制已经完成了,现在测试下主从复制的效果:

(1)登录MySQL主服务器创建一个库:

mysql> create database db_test;         #创建db_test库
Query OK, 1 row affected (0.00 sec)

(2)在主、从服务器上分别查看数据库,显示的数据库相同,则主从复制没有问题。

mysql> show databases;                 #查看所有库
+--------------------+
| Database           |
+--------------------+
| information_schema |
| db_test            |
| mysql              |
| performance_schema |
| test               |
+--------------------+
5 rows in set (0.00 sec)

4、开始搭建MySQL读写分离:

(1)接着上面配置好主从复制的环境,现在需要配置amoeba服务器(将下载的相关软件上传到amoeba服务器):

[root@localhost ~]# mount amoeba.iso /mnt              #挂载下载的.iso文件
mount: /dev/loop0 写保护,将以只读方式挂载
[root@localhost ~]# cd /mnt
[root@localhost mnt]# cp * /usr/src/                   #将文件内的所有安装包复制到指定目录
[root@localhost mnt]# cd /usr/src/
#接下来的操作是在配置java环境,由于amoeba是基于jdk1.5开发的,
#所以官方推荐使用jdk1.5或1.6版本,高版本不建议使用
[root@localhost src]# chmod +x jdk-6u14-linux-x64.bin             #添加执行权限
[root@localhost src]# ./jdk-6u14-linux-x64.bin   #执行该文件,执行后,按空格进行翻页
     ....................#省略部分内容,该内容像是Windows安装软件时的协议条款,不管它
Do you agree to the above license terms? [yes or no]
yes                     #输入“yes”
Press Enter to continue.....           #按回车键

Done.                 #完成
[root@localhost src]# mv jdk1.6.0_14/ /usr/local/jdk1.6
[root@localhost src]# 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@localhost src]# source /etc/profile       #更新环境变量
[root@localhost src]# java -version       #查询Java版本,显示如下说明Java安装成功。
java version "1.6.0_14"
Java(TM) SE Runtime Environment (build 1.6.0_14-b08)
Java HotSpot(TM) 64-Bit Server VM (build 14.0-b16, mixed mode)
[root@localhost src]# mkdir /usr/local/amoeba
[root@localhost src]# tar zxf amoeba-mysql-binary-2.2.0.tar.gz -C /usr/local/amoeba/
#解包
[root@localhost src]# chmod -R 755 /usr/local/amoeba/      #调整amoeba目录权限
[root@localhost src]# /usr/local/amoeba/bin/amoeba      #执行
amoeba start|stop                 #显示此内容说明amoeba安装成功

(2)现在配置amoeba读写分离,两个slave读负载均衡。

①master、slave1、slave2数据库中分别执行以下语句,以便开放权限给amoeba访问。

#三台数据库服务器都执行该语句。
mysql> grant all on *.* to test@'192.168.1.%' identified by '123.com';
Query OK, 0 rows affected (0.00 sec)

②编辑amoeba服务器的amoeba.xml配置文件(以下改动比较零散,仔细看下面的注释,根据注释提示进行操作):

[root@localhost src]# cd /usr/local/amoeba/
[root@localhost amoeba]# vim conf/amoeba.xml         <!--编辑amoeba.xml文件-->
          .......................<!--省略部分内容-->
 <!--在末行模式执行“/user”,以便定位到下面内容-->
<property name="authenticator">
      <bean class="com.meidusa.amoeba.mysql.server.MysqlClientAuthenticator">

      <property name="user">amoeba</property> 
       <!--将上面配置默认的“root”改为amoeba,这是客户端连接时使用的用户名-->
   <property name="password">123456</property> 
                  <!--“123456”是用户名amoeba对应的密码-->
                   <property name="filter">
                   <bean class="com.meidusa.amoeba.server.IPAccessController">
              <property name="ipFile">${amoeba.home}/conf/access_list.conf</property>
                        </bean>
                   </property>
               </bean>
           </property>

               .....................#省略部分内容
 <!--继续在末行模式执行“/defaultPool”,以便定位到下面位置-->                                
<property name="LRUMapSize">1500</property>

                <property name="defaultPool">master</property>
<!--将下面两项中默认的“server1”分别改为“master”和“slaves”,如下:-->
               <property name="writePool">master</property>
                <property name="readPool">slaves</property>
<!--默认上面两行是被注释掉的,记得把注释符号删除,以便配置生效。-->
<!--改完以后,保存退出即可。-->

③编辑dbServers.xml配置文件:

[root@localhost amoeba]# vim conf/dbServers.xml          #编辑该配置文件
                ...............<!--省略部分内容-->
<!--在末行模式执行“/user”,以便定位到下面内容-->
 <!-- mysql user -->
<!--将下面配置默认的“root”改为test,这是amoeba连接时数据库时使用的用户名-->
                        <property name="user">test</property>

<!--“将默认的“password”改为“123.com”,这是刚才在数据库上创建的用户密码-->
                        <property name="password">123.com</property>
<!--默认上面的密码配置项是被注释的,记得删除注释符号。-->
                ...............<!--省略部分内容-->
    <!--在末行模式下执行“/ipAddress”来定位到以下部分-->
    <!--将下面的name值改为“master”,如下所示-->
    <dbServer name="master"  parent="abstractServer">
                <factoryConfig>
                        <!-- mysql ip -->
                        <property name="ipAddress">192.168.1.1</property>
            <!--上面的IP地址192.168.1.1,为主服务器的IP地址-->
                </factoryConfig>
        </dbServer>
<!--将下面的name值改为“slave1”,如下所示-->
        <dbServer name="slave1"  parent="abstractServer">
                <factoryConfig>
                        <!-- mysql ip -->
                        <property name="ipAddress">192.168.1.2</property>
<!--上面的IP地址192.168.1.2,为从服务器的IP地址-->
                </factoryConfig>
        </dbServer>
  <!--
默认配置文件中只有上面两段配置模板,所以要复制一下上面slave1的配置,
我这里是复制了上面6行内容,粘贴到了下面
           -->
<!--将下面的name值改为“slave2”,如下所示-->
        <dbServer name="slave2"  parent="abstractServer">
                <factoryConfig>
                        <!-- mysql ip -->
                        <property name="ipAddress">192.168.1.3</property>
        <!--上面的IP地址192.168.1.3,为从服务器的IP地址-->
                </factoryConfig>
        </dbServer>
<!--将下面的name值改为“slaves”,如下所示-->                        
        <dbServer name="slaves" virtual="true">
                <poolConfig class="com.meidusa.amoeba.server.MultipleServerPool">
                        <!-- Load ......ROUNDROBIN , 2=WEIGHTBASED , 3=HA-->
                        <property name="loadbalance">1</property>
<!-- Separated by commas,such as: server1,server2,server1 -->
   <!--
将下面默认的内容改为“slave1,slave2”,如下所示:
这里引用的是上面两个定义的slave1/2的配置项
        -->
                        <property name="poolNames">slave1,slave2</property>
                </poolConfig>
        </dbServer>
    <!--更改完成后,保存退出即可。-->

④配置无误后,可以启动amoeba软件,其默认监听端口为tcp 8066。

[root@localhost amoeba]# bin/amoeba start & 
#启动服务,一定要加“&”符号,到后台执行,否则将一直占用前台命令行
[1] 5384
[root@localhost amoeba]# log4j:WARN log4j config load ............
        ...............#省略一部分提示信息,再按一下回车键即可。
[root@localhost init.d]# netstat -anpt | grep java     #查询端口8066是否在监听
tcp6       0      0 127.0.0.1:49276         :::*            LISTEN      5384/java           
tcp6       0      0 :::8066  #OK,在监听  :::*            LISTEN      5384/java           
tcp6       0      0 192.168.1.4:41938  192.168.1.2:3306   ESTABLISHED 5384/java           
tcp6       0      0 192.168.1.4:34712  192.168.1.3:3306   ESTABLISHED 5384/java           
tcp6       0      0 192.168.1.4:34002  192.168.1.1:3306   ESTABLISHED 5384/java  

5、现在已经主从复制+读写分离配置完毕了,开始在应用客户端连接amoeba服务器进行测试:

①应用客户端连接amoeba服务器:

[root@client ~]# yum -y install mysql         
#安装系统映像中的MySQL即可,以便可以使用mysql命令
[root@client ~]# mysql -u amoeba -p 123456 -h 192.168.1.4 -P 8066
#连接amoeba服务器的8066端口
Enter password:           
#输入在amoeba服务器的amoeba.xml文件配置中“amoeba”用户对应的密码
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MySQL connection id is 494299142
Server version: 5.1.45-mysql-amoeba-proxy-2.2.0

Copyright (c) 2000, 2016, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MySQL [123456]>                       #连接成功
MySQL [123456]> use db_test;             #切换至之前测试主从复制时创建的库
No connection. Trying to reconnect...
Connection id:    494299142
Current database: *** NONE ***

Database changed
MySQL [db_test]> create  table test (id int(10),name varchar(10));   #新建一个表
Query OK, 0 rows affected (0.04 sec)

②分别在三台数据库服务器上查看是否有刚才创建的表:

mysql> use db_test;             #切换至db_test库
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> show tables;         #查看所有表,可以看到刚才创建的表,OK。
+-------------------+
| Tables_in_db_test |
+-------------------+
| test              |
+-------------------+
1 row in set (0.00 sec)

③关闭两台从服务器上的同步功能:

mysql> stop slave;              #两台slave服务器上都需执行一下该命令
Query OK, 0 rows affected (0.00 sec)

④在主服务器上写入以下数据:

mysql> insert into test values('1','zhangsan');
Query OK, 1 row affected (0.00 sec)

⑤在从服务器上分别写入以下数据:

slave1:
mysql> insert into test values('2','lisi');
Query OK, 1 row affected (0.00 sec)

slave2:
mysql> insert into test values('3','wangwu');
Query OK, 1 row affected (0.01 sec)

⑥在应用客户端测试读操作:

MySQL [db_test]> select * from test;             #第一次读test表
+------+------+
| id   | name |
+------+------+
|    2 | lisi |
+------+------+
1 row in set (0.00 sec)

MySQL [db_test]> select * from test;              #第二次读test表
+------+--------+
| id   | name   |
+------+--------+
|    3 | wangwu |
+------+--------+
1 row in set (0.01 sec)
MySQL [db_test]> select * from test;             #第三次读test表
+------+------+
| id   | name |
+------+------+
|    2 | lisi |
+------+------+
1 row in set (0.03 sec)

不管进行读多少次,都不会读到主服务器上的数据,说明读操作是在slave1/2上进行的。

⑦测试写操作:

MySQL [db_test]> insert into test values('666','lvjianzhao');      
Query OK, 1 row affected (0.01 sec)
#在应用服务器写入一条数据

但是在应用客户端上继续查询该表,是查不到上面刚刚写入的数据的,说明写到了主服务器上,去主服务器查询就可以查到刚才写入的数据了,如下:

#在主服务器上再查询test表
mysql> mysql> select * from test;
+------+------------+
| id   | name       |
+------+------------+
|    1 | zhangsan   |
|  666 | lvjianzhao |
+------+------------+
2 rows in set (0.00 sec)

主服务器能查到刚才在应用客户端写入的数据,但是两个从服务器是查不到的:

mysql> mysql> select * from test;              #在slave1进行查询
+------+------+
| id   | name |
+------+------+
|    2 | lisi |
+------+------+
1 row in set (0.00 sec)
mysql> mysql> select * from test;              #在slave2进行查询
+------+--------+
| id   | name   |
+------+--------+
|    3 | wangwu |
+------+--------+
1 row in set (0.00 sec)

由此反复验证,已经实现了MySQL的读写分离,目前所有的写操作都会在master(主服务器)上,用来避免数据的不同步;所有的读操作都分摊给了slave(从服务器),用来分担数据库压力,当然,在这个案例环境中还有一个问题:负责写入数据的服务器只有一台,那么这台服务器一旦宕掉了呢?不就是完蛋了么?关于这个问题,我将在以后的博文写出解决办法,暂时先从网上搜罗一篇关于MySQL高可用方案的文章,有需要的话可以参考一下:MySQL高可用方案

终于写完了这篇博文,希望可以给更多的人做一下参考吧!!!

随机阅读

Copyright © 2017 英语文化交流 All Rights Reserved.