MYSQL主从复制与读写分离

防伪码:曾总想穿过那段最无暇的时光,去实现所有缤纷的梦想。

                                第八章 MYSQL主从复制与读写分离 

前言:又快到双十一网购狂欢节了,试想,当天那么多的朋友上网购物,单单一台或几台数据库服务器肯定是不够的。恰好今天使用的软件amoeba也是阿里巴巴自己员工开发出来的,经过淘宝这么多用户的验证,效果不用怀疑。在实际的生产环境中,对数据库的读和写都在同一个数据库服务器中,是不能满足实际需求的。无论是在安全性、高可用性还是高并发等各个方面都是完全不能满足实际需求的。因此,通过主从复制的方式来同步数据,再通过读写分离来提升数据库的并发负载能力。有点类似于前面我们学习过的rsync,但是不同的是rsync是对磁盘文件做备份,而mysql主从复制是对数据库中的数据、语句做备份。

如图所示:

wKiom1ghsBnzeV_OAADmPGxhuAs725.png-wh_50

一、 案例前置知识点

1、 mysq支持的复制类型

1) 基于语句的复制。在服务器上执行sql语句,在从服务器上执行同样的语句,mysql默认采用基于语句的复制,执行效率高。

2) 基于行的复制。把改变的内容复制过去,而不是把命令在从服务器上执行一遍。

3) 混合类型的复制。默认采用基于语句的复制,一旦发现基于语句无法精确复制时,就会采用基于行的复制。

2、 复制的工作过程

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

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

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

如图所示:

wKioL1ghsOWgXg3qAABv13ob7-Y071.png-wh_50

 

3、 mysql读写分离原理

读写分离就是在主服务器上修改,数据会同步到从服务器,从服务器只能提供读取数据,不能写入,实现备份的同时也实现了数据库性能的优化,以及提升了服务器安全。

wKioL1ghsR7RxjR4AADEsMgjl00181.png-wh_50

前较为常见的Mysql读写分离分为以下两种:

 1)基于程序代码内部实现

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

 2) 基于中间代理层实现

        代理一般介于应用服务器和数据库服务器之间,代理数据库服务器接收到应用服务器的请求后根据判断后转发到,后端数据库,有以下代表性的程序。

(1)mysql_proxy。mysql_proxy是Mysql的一个开源项目,通过其自带的lua脚本进行sql判断。

(2)Atlas。是由 Qihoo 360, Web平台部基础架构团队开发维护的一个基于MySQL协议的数据中间层项目。它是在mysql-proxy 0.8.2版本的基础上,对其进行了优化,增加了一些新的功能特性。360内部使用Atlas运行的mysql业务,每天承载的读写请求数达几十亿条。支持事物以及存储过程。

(3)Amoeba。由阿里巴巴集团在职员工陈思儒使用序java语言进行开发,阿里巴巴集团将其用户生产环境下,但是他并不支持事物以及存数过程。

 经过上述简单的比较,不是所有的应用都能够在基于程序代码中实现读写分离,像一些大型的java应用,如果在程序代码中实现读写分离对代码的改动就较大,所以,像这种应用一般会考虑使用代理层来实现,那么今天就使用Amoeba为例,完成主从复制和读写分离。

 二、 实验案例:mysql主从复制和读写分离

1、 实验拓扑

wKiom1ghsmqB_XdMAADTpW7SgmE649.png-wh_50

2、 实验环境

在amoeba上安装amoeba和jdk,在其它的机器上安装mysql,ip地址如上图所示

 三、 主从复制的实验步骤

1、搭建时间NTP服务器,同步时间

1) 建立时间同步环境,在主节点上搭建时间同步服务器

wKioL1ghtWbg0EVbAAAiAgM0qCM686.png-wh_50

2) 配置NTP时间服务器

Vim  /etc/ntp.conf

wKiom1ghtYijxRrdAACbpm35jNk605.jpg-wh_50

3) 重启ntpd服务

wKiom1ghtaiwgfwbAAAtLX-kj-s638.png-wh_50

4) 在防火墙上开启指定端口

wKioL1ghtdSw8jMdAAArgZ4vkK8638.png

5) 在从节点上进行时间同步

wKioL1ghte7B5bogAAAhJCaki1Y882.png-wh_50

wKiom1ghtf2hWqKUAAAu0h8I9uk419.png-wh_50

在另一台从服务器上执行相同操作

wKiom1ghthDgsPiPAAAvRnnS7nw533.png-wh_50

2、 在mysql主和两台从服务器上安装mysql,我以其中一台为例。

(1) 安装mysql并创建程序用户

[root@centos4 ~]# tar  zxf cmake-2.8.6.tar.gz

[root@centos4 ~]# cd cmake-2.8.6

[root@centos4 cmake-2.8.12]# ./configure  &&  gmake  &&  gmake install

[root@centos4 ~]# tar zxf mysql-5.5.38.tar.gz

[root@centos4 ~]# cd mysql-5.5.38

[root@centos4 mysql-5.5.38]# cmake  -DCMAKE_INSTALL_PREFIX=/usr/local/mysql  -DSYSCONFDIR=/etc/ -DDEFAULT_CHARSET=utf8  -DDEFAULT_COLLATION=utf8_general_ci -DWITH_EXTRA_CHARSETS=all  && make  &&  make install

[root@centos4 mysql-5.5.38]# useradd  -M -s /sbin/nologin  mysql  -g  mysql

 (2)优化程序执行路径

[root@centos4 mysql-5.5.38]# echo  "PATH=$PATH:/usr/local/mysql/bin" >> /etc/profile

(3)创建主配置文件

[root@centos4 mysql-5.5.38]# cp support-files/my-medium.cnf.sh  /etc/my.cnf

cp:是否覆盖"/etc/my.cnf"? y

[root@centos4 mysql-5.5.38]#

 (4)创建服务脚本并添加为系统服务

[root@centos4 mysql-5.5.38]# cp support-files/mysql.server /etc/init.d/mysqld

[root@centos4 mysql-5.5.38]# chkconfig  --add mysqld

[root@centos4 mysql-5.5.38]# chkconfig  mysqld on

[root@centos4 mysql-5.5.38]# chmod  +x  /etc/init.d/mysqld

 (5)初始化数据库

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

[root@centos4 mysql-5.5.38]#

 (6)修改安装目录权限

[root@centos4 mysql-5.5.38]# chown -R mysql:mysql  /usr/local/mysql/

 (7)启动服务

[root@centos4 mysql-5.5.38]# service mysqld start

 (8)为用户root设置密码

[root@centos4 mysql-5.5.38]# mysqladmin  -u root -p password  '123-abc’

默认没有密码,直接在确认旧密码处回车即可。

 (9)登录mysql数据库

[root@centos4 mysql-5.5.38]# mysql -u root -p

3、 配置mysql主服务器(MASTER)

1)修改/etc/my.cnf配置文件

server-id       = 11                        //mysql数据的唯一标示(不能重复)

log-slave-updates=true                        //允许连级复制  (增加)

log-bin=master-bin                         //二进制文件名(修改)

wKioL1ghtnKD0IO6AADbheRNCU8310.jpg-wh_50

2) 重启MySQL服务

wKiom1ghtpeyPPYZAAAu1wbjluo506.png-wh_50

3) 登录mysql程序,给从服务器授权

mysql  -u  root  -p

wKioL1ghttqDGymoAAEOSaFzr0c437.jpg-wh_50

注:上图中File列显示日志名,Position列显示偏移量,这两个值在后面配置从服务器

的时候需要。

4、 配置从服务器

1) 在/etc/my.cnf中修改以下内容

[root@centos3 ~]# vim /etc/my.cnf

server-id       = 22                                                //不能与其他实例重复

log-bin=mysql-bin                                                        //二进制日志文件名 修改

relay-log=relay-log-bin                                        //复制过来的二进制文件名,增加

relay-log-index=slave-relay-bin.index                //中继日志存放的文件名称,增加

wKioL1ght4bA4lYpAACbB6S7Zbs393.jpg-wh_50

注意server-id不能与主服务器相同,但是从服务器要相同。

2) 重启mysql服务

wKioL1ght8DAOJomAAAxGjwnmuQ593.png-wh_50

3) 登录mysql,配置同步(按照主服务器结果更改下面命令中

master_file和master_log_pos参数

wKioL1ghuBygA-dEAAA0tEBhFoA576.png-wh_50

4)启动同步

wKiom1ghuDnxwsOFAAAnK_Dh8yM932.png-wh_50

5) 查看slave状态,确保以下两个值为YES

wKiom1ghuE-z0ER9AAEY0V9lPgg980.jpg-wh_50

5、 验证主从复制效果

1) 在主服务器上新建数据库“IT”

wKioL1ghuHqQEHZyAADvaPQIM4M586.jpg-wh_50

2) 在从服务器上查看数据库,如果和主服务器相同,说明主从复制成功。

wKiom1ghuIzwkLHMAACo3v8W64E897.jpg-wh_50

四、 搭建MySQL读写分离

1、 安装java环境(amoeba软件基于java平台运行)

1)运行jdk

wKioL1ghvA_i4-TxAAA33WDFv4U585.png

安装过程中提示(yes/no),我们要选择yes安装

2) 修改/etc/profile配置文件,增加以下配置

wKiom1ghvb2BvWkzAAAgRLofEO0034.png-wh_50

export JAVA_HOME=/usr/local/jdk1.6  //设置jdk的根目录

export CLASSPATH=$CLASSPATH:$JAVA_HOME/lib:$JAVA_HOME/jir

e/lib //将jdk的程序文件赋予CLASSPATH变量

export PATH=$JAVA_HOME/lib:$JAVA_HOME/jre/bin:$PATH:$HOME

/bin  //将jdk的程序文件赋予PATH变量

export AMOEBA_HOME=/usr/local/amoeba         //定义AMOEBA的根目录

export PATH=$PATH:$AMOEBA_HOME/bin  将amoeba的程序文件复制给PATH变量

wKiom1ghvH3B7PmrAAD-7VJcrD8569.jpg

3) 执行脚本

wKiom1ghvJbxa2c7AAAwicxeMUg551.png-wh_50

2、 安装并配置Amoeba软件

官方解释:Amoeba(变形虫),这个软件致力于MySQL的分布式数据库前端代理层,主要为应用层访问MySQL的时候

充当SQL路由功能,并具有负载均衡、高可用性、SQL过滤、读写分离、可路由相关的到目的数据库,可并发

请求多台数据库。

wKiom1ghvfrgQfkcAADOpL64p1c259.jpg-wh_50

3、 配置amoeba读写分离,两个slave读负载均衡

1) 在主从服务器上开放权限给amoeba访问(三台服务器上都做相同设置,这里我就以其中一台为例)

wKioL1ghvkiCLyS2AAAvTfxrNBc980.png-wh_50

2) 修改amoeba.xml文件

注意:所有配置文件注释都是以 <!-- 内容 -->,再删除注释时请将内容也一并删除,最好是删除正行,

但是有些时候只需要删除头和尾即可,里面的配置项是可以直接使用的。这个配置文件需要定义两

个配置,第一是应用程序使用什么用户连接amoeba访问到后端的mysql数据库,第二个是定义默认写池以及读池。

vi /usr/local/amoeba/conf/amoeba/amoaba.xml

wKioL1ghvtbTlJcxAAEYrnStZMQ166.jpg

接下来修改

wKiom1ghvrygQB-MAAGiaFfGwEM575.jpg

3) 编辑dbServers.xml文件

vi /usr/local/amoeba/conf/dbServers.xml

wKioL1ghv2SjC2UhAAEUi8v-PD8256.jpg

接下图

wKiom1ghv4aBjmY0AAHnRrbIE_w515.jpg

4) 启动amoeba软件(默认端口为tcp 8066)

wKioL1ghv-bhHK3kAAHAI9oOKzQ651.jpg-wh_50

4、 测试读写分离

1) 打开一台客户端192.168.1.10,也需要安装mysql,作为测试机,可以使用yum -y install mysql安装。

2)建立防火墙规则

[root@centos1 ~]# iptables -I INPUT -p tcp --dport 8066 -j ACCEPT

wKioL1ghwDagiP0sAAAopAFd7wI024.png

master、slave1、slave2都需要开放3306端口入站

[root@centos2 ~]# iptables -I INPUT -p tcp --dport 3306 -j ACCEPT

[root@centos2 ~]# service iptables save

另外两台从服务器也是一样的配置,或者直接将iptables stop掉

3)在客户端登录

wKioL1ghwGmiB5ngAAEv6z7uuy4406.jpg-wh_50

4) 在主服务器master上创建一个数据库YZZG(一盏烛光,嘿嘿),同步到各从服务器上,然后关掉从服务器的slave功能,再插入数据。

wKioL1ghwJ3h65zDAAA7yNk7pEM597.png-wh_50

5) 查看在从服务器已经同步

wKioL1ghwOOhqtNSAACqXk3_W5s182.jpg-wh_50

6) 然后在主服务器上写入数据

wKioL1ghwP-yMAyiAAAqqH0QCPk075.png-wh_50

7) 从服务器上也同步了表

wKiom1ghwSCwUruQAAAwu9BKvec304.png-wh_50

8)在两台从服务器上执行stop slave, 分别在从服务器上写入不同的数据

wKiom1ghwUvDcLTGAAA6UQYHSRI542.png

wKiom1ghwYezSYCEAAAy5EDyCPM967.png

9) 在客户端上查询

wKioL1ghweShMiy7AADxMjKLOLY380.jpg

10) 在客户机上写入一条语句

wKioL1ghwgHilk03AAAp9EEizyE730.png-wh_50

11) 在客户端上查不到刚写入的数据,最终只有在master主服务器上才能看到,因为写操作只有master有,另外两台负责读取数据。

wKiom1ghwjKSTBGIAACZiPml10E080.jpg

wKiom1ghwlTwiKgMAAChM1Nnj6w952.jpg

总结:到此为止主从复制和读写分离都已完成,写操作都在主服务器上,实现数据的统一更新,从服务器只负责读取,负载均衡分担了数据库压力。其实在我们生活中有很多主从复制的应用,例如有很多连锁超市,总部负责产品的名称和价格等信息的录入,而所有的超市都会同步更新,做到了统一价格。而像淘宝的服务器,主要是为了分担负载,提升查询的性能,最后补充一句,Mysql主从复制与我们以前学习的sqlserver复制是一样的作用。

谢谢观看,真心的希望能帮到您。

相关文章
相关标签/搜索