MySQL主从复制与读写分离
    前言:我们前面搭建过LAMP和LNMP,做过了web服务器群集和热备,web服务器坏了我们是不怕了,但是我们要知道,网站的数据有很多是存储在数据库里面的,例如注册的会员,发的文章,购物的订单等信息。当然我们可以给数据库做备份,但是如果每天00:00做一次备份,那么如果在23:59数据丢失了,那么就会丢失一天的数据,有没有一种方法能实现实时备份,就是说有数据产生就立即备份,答案当然是有,也就是今天我们要学习的mysql主从复制。有点类似于前面我们学习过的rsync,但是不同的是rsync是对磁盘文件做备份,而mysql主从复制是对数据库中的数据,语句做备份。另外读写分离主要是为了优化数据库。下面把实验给大家做一遍。

    1. mysql主从复制的工作原理
    2. mysq支持的复制类型
    3. 基于语句的复制。在服务器上执行sql语句,在从服务器上执行同样的语句,mysql默认采用基于语句的复制,执行效率高。
    4. 基于行的复制。把改变的内容复制过去,而不是把命令在从服务器上执行一遍。
    5. 混合类型的复制。默认采用基于语句的复制,一旦发现基于语句无法精确复制时,就会采用基于行的复制。

    6. 复制的工作过程

    第八章:mysql主从复制与读写分离 - 图1

    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缓存中,所以中继日志的开销很小。

    4. mysql读写分离原理

    读写分离就是在主服务器上修改,数据会同步到从服务器,从服务器只能提供读取数据,不能写入,实现备份的同时也实现了数据库性能的优化,以及提升了服务器安全。第八章:mysql主从复制与读写分离 - 图2
    目前较为常见的Mysql读写分离分为两种

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

    1. 基于中间代理层实现

      代理一般介于应用服务器和数据库服务器之间,代理数据库服务器接收到应用服务器的请求后根据判断后转发到,后端数据库,有以下代表性的程序。
      (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为例,完成主从复制和读写分离。

    1. 实验案例:mysql主从复制和读写分离
    2. 实验拓扑

    第八章:mysql主从复制与读写分离 - 图3

    1. 实验环境

    第八章:mysql主从复制与读写分离 - 图4

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

    1. 主从复制的实验步骤

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

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

    第八章:mysql主从复制与读写分离 - 图5

    1. 配置NTP时间服务器

    Vim /etc/ntp.conf
    第八章:mysql主从复制与读写分离 - 图6

    1. 重启ntpd服务

    第八章:mysql主从复制与读写分离 - 图7

    1. 在防火墙上开启例外

    第八章:mysql主从复制与读写分离 - 图8

    1. 在从节点上进行时间同步

    第八章:mysql主从复制与读写分离 - 图9

    第八章:mysql主从复制与读写分离 - 图10

    在另一台从服务器上执行相同操作
    第八章:mysql主从复制与读写分离 - 图11

    1. 在mysql主和两台从服务器上安装mysql,这三台的安装方法完全一样,我就以一台为例。
    2. 安装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

    1. 配置mysql主服务器(MASTER)

    1)修改/etc/my.cnf配置文件
    server-id = 11 //mysql数据的唯一标示(不能重复)
    log-slave-updates=true //允许连级复制 (增加)
    log-bin=master-bin //二进制文件名(修改)

    第八章:mysql主从复制与读写分离 - 图12

    1. 重启MySQL服务

    第八章:mysql主从复制与读写分离 - 图13

    1. 登录主mysql程序,给从服务器授权

    Mysql -u root -p
    grant replication slave on . to ‘gao’@’192.168.1.%’ identified by ‘123456’;
    第八章:mysql主从复制与读写分离 - 图14

    1. 配置从服务器
    2. 在/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 //中继日志存放的文件名称,增加

    第八章:mysql主从复制与读写分离 - 图15
    注意server-id不能与主服务器相同,但是从服务器要相同。

    1. 重启mysql服务

    第八章:mysql主从复制与读写分离 - 图16

    1. 登录mysql,配置同步

    第八章:mysql主从复制与读写分离 - 图17

    1. change master to master_host='192.168.1.2',master_user='gao',master_password='123456',master_log_file='master-bin.000001',master_log_pos=107;

    注:需要查看主mysql的值

    第八章:mysql主从复制与读写分离 - 图18
    IP地址、用户、密码都master的数据库信息

    1. 启动同步

    第八章:mysql主从复制与读写分离 - 图19

    1. 查看slave状态,确保以下两个值为YES

    第八章:mysql主从复制与读写分离 - 图20

    1. 验证主从复制效果
    2. 在主服务器上新建数据库“IT”

    第八章:mysql主从复制与读写分离 - 图21

    1. 在从服务器上查看数据库,如果和主服务器相同,说明成功。

    第八章:mysql主从复制与读写分离 - 图22

    第八章:mysql主从复制与读写分离 - 图23

    注意从服务器的配置和主服务器完全一样,注意Id也要完全一样

    1. 读写分离的实验步骤
    2. 安装java环境(amoeba软件基于java平台运行)

    1)运行jdk
    第八章:mysql主从复制与读写分离 - 图24

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

    1. 修改/etc/profile配置文件,增加以下配置

    第八章:mysql主从复制与读写分离 - 图25

    export JAVA_HOME=/usr/local/jdk1.6 //设置jdk的根目录
    export CLASSPATH=$CLASSPATH:$JAVA_HOME/lib:$JAVA_HOME/jir/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变量

    第八章:mysql主从复制与读写分离 - 图26

    1. 执行脚本

    第八章:mysql主从复制与读写分离 - 图27

    1. 安装并配置Amoeba软件
    2. 安装

    第八章:mysql主从复制与读写分离 - 图28

    1. 出现以下内容说明安装成功了

    第八章:mysql主从复制与读写分离 - 图29

    1. 配置amoeba读写分离,两个slave读负载均衡
    2. 在主从服务器上开放权限给amoeba(三台服务器上都做相同设置,这里我就以其中一台为例)

      grant all on . to test@’192.168.1.%’ identified by ‘123@abc’;
      第八章:mysql主从复制与读写分离 - 图30

    3. 修改amoeba.xml文件

    注意:所有配置文件注释都是以 ,再删除注释时请将内容也一并删除,最好是删除正行,但是有些时候只需要删除头和尾即可,里面的配置项是可以直接使用的。这个配置文件需要定义两个配置,第一是应用程序使用什么用户连接amoeba访问到后端的mysql数据库,第二个是定义默认写池以及读池。

    Vi /usr/local/amoeba/conf/amoeba.xml
    第八章:mysql主从复制与读写分离 - 图31

    接下来修改
    ${amoeba.home}/conf/functionMap.xml

    1500
    master //定义默认的写池
    master //定义写池
    slaves //定义读池,以上名字随便 true

    如下图所示:
    第八章:mysql主从复制与读写分离 - 图32
    注意

    1. 编辑 vim /usr/local/amoba/dbServers.xml 文件

    第八章:mysql主从复制与读写分离 - 图33

    第八章:mysql主从复制与读写分离 - 图34
    接下图
    第八章:mysql主从复制与读写分离 - 图35

    1. 启动amoeba软件

    第八章:mysql主从复制与读写分离 - 图36
    第八章:mysql主从复制与读写分离 - 图37

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

    2)建立防火墙规则
    [root@centos1 ~]# iptables -I INPUT -p tcp —dport 8066 -j ACCEPT
    master、slave1、slave2都需要开放3306端口入站
    [root@centos2 ~]# iptables -I INPUT -p tcp —dport 3306 -j ACCEPT
    [root@centos2 ~]# service iptables save
    iptables:将防火墙规则保存到 /etc/sysconfig/iptables: [确定]
    [root@centos2 ~]#
    另外两台从服务器也是一样的配置,或者直接将iptables stop掉

    3)修改amoeba的amoeba.xml配置文件的第一个8066改为3306之后建立一条防火墙规则为允许3306端口入站并且重新启动amoeba服务
    3306 //在11行
    第八章:mysql主从复制与读写分离 - 图38
    [root@centos1 ~]# amoeba stop
    [root@centos1 ~]# amoeba start&
    [root@centos1 ~]# iptables -I INPUT -p tcp —dport 3306 -j ACCEPT
    在进行登录amoeba
    [root@web ~]# mysql -u amoeba -p 123.abc -h 192.168.1.1
    第八章:mysql主从复制与读写分离 - 图39

    1. 在主服务器master上创建一个数据库WLZS,同步到各从服务器上,然后关掉从服务器的slave功能,再插入数据。

    第八章:mysql主从复制与读写分离 - 图40

    1. 查看在从服务器已经同步

    第八章:mysql主从复制与读写分离 - 图41

    1. 然后在主服务器上写入数据

    第八章:mysql主从复制与读写分离 - 图42

    1. 从服务器上也同步了表

    第八章:mysql主从复制与读写分离 - 图43

    1. 在两台从服务器上执行stop slave

    2. 分别在从服务器上写入不同的数据

    第八章:mysql主从复制与读写分离 - 图44

    第八章:mysql主从复制与读写分离 - 图45

    1. 在客户端上查询

    第八章:mysql主从复制与读写分离 - 图46

    1. 在客户机上写入一条语句

    第八章:mysql主从复制与读写分离 - 图47

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

    第八章:mysql主从复制与读写分离 - 图48

    第八章:mysql主从复制与读写分离 - 图49

    总结:到此为止主从复制和读写分离都已完成,写操作都在主服务器上,实现数据的统一更新,从服务器只负责读取,负载均衡分担了数据库压力。其实在我们生活中有很多主从复制的应用,例如有很多连锁超市,总部负责产品的名称和价格等信息的录入,而所有的超市都会同步更新,做到了统一价格。而像淘宝的服务器,主要是为了分担负载,提升查询的性能,又快到双11了,当天那么多人同时购物,如果只有一台mysql定是不够的,恰好今天使用的软件amoeba也是阿里巴巴自己员工开发出来的,经过淘宝这么多用户的验证,效果不用怀疑。最后补充一句,Mysql主从复制与我们以前学习的sqlserver复制是一样的作用。