主从复制以及主从复制的做用:
在实际的生产环境中,对数据库的读和写都在同一个数据库服务器中,是不能知足实际需求的,经过主从复制的方式来同步数据,再经过读写分离来提高数据库的并发负载能力java
.mysql
mysql主从复制
mysq支持的复制类型linux
基于语句的复制。在服务器上执行sql语句,在从服务器上执行一样的语句,mysql默认采用基于语句的复制,执行效率高。sql
基于行的复制。把改变的内容复制过去,而不是把命令在从服务器上执行一遍。数据库
Slave将master的binary log复制到其中继日志。首先slave开始一个工做线程(I/O),I/O线程在master上打开一个普通的链接,而后开始binlog dump process。binlog dump process从master的二进制日志中读取事件,若是已经跟上master,它会睡眠并等待master产生新的事件,I/O线程将这些事件写入中继日志。vim
MySQL读写分离原理
读写分离就是在主服务器上修改,数据会同步到从服务器,从服务器只能提供读取数据,不能写入,实现备份的同时也实现了数据库性能的优化,以及提高了服务器安全。后端
前较为常见的Mysql读写分离分为如下两种:
.centos
基于程序代码内部实现缓存
在代码中根据select 、insert进行路由分类,这类方法也是目前生产环境下应用最普遍的。优势是性能较好,由于程序在代码中实现,不须要增长额外的硬件开支,缺点是须要开发人员来实现,运维人员无从下手。
.安全
基于中间代理层实现
代理通常介于应用服务器和数据库服务器之间,代理数据库服务器接收到应用服务器的请求后根据判断后转发到,后端数据库,有如下表明性的程序。
.
环境介绍;
安装mysql过程不作解释
(mysql。主)
[root@centos1 ]# mount /dev/cdrom /media/ [root@centos1 ]# yum -y install ntp
.
[root@centos1 ]# vim /etc/ntp.conf #restrict 192.168.1.0 mask 255.255.255.0 nomodify notrap server 127.127.1.0 /添加 fudge 127.127.1.0 stratum 8 /添加 .
重启ntpd服务 [root@centos1 ]# service ntpd restart
.
防火墙开例外 [root@centos1 ]# iptables -I INPUT -p udp --dport 123 -j ACCEPT [root@centos1 ]# iptables -I INPUT -p udp --dport 3306 -j ACCEPT
在(节点A)进行时间同步 [root@centos1 ]# yum -y install ntpdate [root@centos1 ]# /usr/sbin/ntpdate 192.168.1.30
在(节点B)进行时间同步 [root@centos1 ]# yum -y install ntpdate [root@centos1 ]# /usr/sbin/ntpdate 192.168.1.30
.
(mysql。主)
修改/etc/my.cnf配置文件 [root@centos1 ]# vim /etc/my.cnf
server-id = 11 //mysql数据的惟一标示(不能重复) log-slave-updates=true //容许连级复制 (增长) log-bin=master-bin //二进制文件名(修改)
.
重启mysql服务 [root@centos1 ]# service mysqld restart
.
登录mysql给从服务器受权 [root@centos1 ]# mysql -u root -p . mysql> GRANT REPLICATION SLAVE ON *.* TO 'lijialiang'@'192.168.1.%' IDENTIFIED BY '123456'; . mysql> FLUSH PRIVILEGES;
.
mysql> show master status; +-------------------+----------+--------------+------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | +-------------------+----------+--------------+------------------+ | master-bin.000001 | 558 | | | +-------------------+----------+--------------+------------------+ 1 row in set (0.03 sec)
.
(节点B,C)
在/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服务 [root@centos1 ]# service mysql restart
.
登陆mysql 配置同步
[root@centos1 ]# mysql -u root -p mysql> change master to master_host='192.168.1.30',master_user='lijialiang',master_password='123456',master_log_file='master-bin.000001',master_log_pos=558; IP地址、用户、密码都master的数据库信息
.
启动同步 mysql> start slave;
.
查看slave状态确保如下两个值为YES . mysql> show slave status\G *************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: 192.168.1.30 Master_User: lijialiang Master_Port: 3306 Connect_Retry: 60 Master_Log_File: master-bin.000001 Read_Master_Log_Pos: 558 Relay_Log_File: relay-log-bin.609531 Relay_Log_Pos: 254 Relay_Master_Log_File: master-bin.000001 Slave_IO_Running: Yes Slave_SQL_Running: Yes
.
(mysql。主)
.
mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | test | +--------------------+ 5 rows in set (0.11 sec)
.
mysql> create datebase IT; . mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | IT | | mysql | | performance_schema | | test | +--------------------+ 5 rows in set (0.11 sec)
.
(节点B,C)
mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | IT | | mysql | | performance_schema | | test | +--------------------+ 5 rows in set (0.27 sec)
.
读写分离
(amoeba)
读写分离安装java环境(amoeba软件基于java平台运行)
运行jdk
[root@centos1 ]# umount /dev/cdrom /media/ [root@centos1 ]# mount /dev/cdrom /media/ [root@centos1 ]# cp jdk-6u14-linux-x64.bin /usr/local/ [root@centos1 ]# cd /usr/local/ [root@centos1 ]# chmod +x jdk-6u14-linux-x64.bin [root@centos1 ]# ./jdk-6u14-linux-x64.bin 安装过程当中提示(yes/no),咱们要选择yes安装
.
修改/etc/profile配置文件,增长如下配置 [root@centos1 ]# mv jdk1.6.0_14/ /usr/local/jdk1.6 [root@centos1 ]# vim /etc/profile
.
export JAVA_HOME=/usr/local/jdk1.6 //设置jdk的根目录 export CLASSPATH=$CLASSPATH:$JAVA_HOME/lib:$JAVA_HOME/jre/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变量
.
执行脚本
[root@centos1 ]# source /etc/profile [root@centos1 ]# java -version
.
安装并配置Amoeba软件
安装
[root@centos1 ]# mkdir /usr/local/amoeba [root@centos1 ]# cd /media/ [root@centos1 ]# ls [root@centos1 ]# tar zxf amoeba-mysql-binary-2.2.0.tar.gz -C /usr/local/amoeba/ [root@centos1 ]# chmod -R 755 /usr/local/amoeba/
.
出现如下内容说明安装成功了
[root@centos1 ]# /usr/local/amoeba/bin/amoeba amoeba start|stop .
配置amoeba读写分离,两个从节点读负载均衡 在主从服务器上开放权限给amoeba(三台服务器上都作相同设置,这里以一台为例) mysql> grant all on *.* to liang@'192.168.1.%' identified by '123456';
.
修改amoeba.xml文件
注意:全部配置文件注释都是以 <!-- 内容 -->,再删除注释时请将内容也一并删除,最好是删除正行,可是有些时候只须要删除头和尾便可,里面的配置项是能够直接使用的。这个配置文件须要定义两个配置,第一是应用程序使用什么用户链接amoeba访问到后端的mysql数据库,第二个是定义默认写池以及读池。
[root@centos1 ]# cd /usr/local/amoeba/ [root@centos1 ]# vim conf/amoeba.xml <bean class="com.meidusa.amoeba.mysql.server.MysqlClientAuthenticator"> <property name="user">amoeba</property> //这里的账户名和密码在后面连接amoeba使用 <property name="password">123456</property> <property name="filter"> ....................................................................... <property name="LRUMapSize">1500</property> <property name="defaultPool">master</property> //修改成master //注意:这里原有注释,须要删除 <property name="writePool">master</property> //修改成master <property name="readPool">slaves</property> //修改成slaves <property name="needParse">true</property> . 编辑dbServers.xml [root@centos1 ]# vim conf/dbServers.xml <!-- mysql schema --> <property name="user">liang</property> //以前设置开放权限的用户名和密码 //注意删掉此位置的注释 <property name="password">123456</property> //注意删掉此位置的注释 </factoryConfig>
.............................................................................
<dbServer name="master" parent="abstractServer"> //修改成master <factoryConfig> <!-- mysql ip --> <property name="ipAddress">192.168.1.30</property> //修改IP </factoryConfig> </dbServer> <dbServer name="slave1" parent="abstractServer"> //修改成slave1 <factoryConfig> <!-- mysql ip --> <property name="ipAddress">192.168.1.40</property> //修改IP </factoryConfig> </dbServer> <dbServer name="slave2" parent="abstractServer"> //复制一份,修改成slave2 <factoryConfig> <!-- mysql ip --> <property name="ipAddress">192.168.1.50</property> //修改IP </factoryConfig> </dbServer> <dbServer name="slaves" virtual="true"> //修改成slaves <poolConfig class="com.meidusa.amoeba.server.MultipleServerPool"> <!-- Load balancing strategy: 1=ROUNDROBIN , 2=WEIGHTBASED , 3=HA--> <property name="loadbalance">1</property> <!-- Separated by commas,such as: server1,server2,server1 --> <property name="poolNames">slave1,slave2</property> //修改成slave1,slave2 </poolConfig> </dbServer> </amoeba:dbServers>
.
.
启动amoeba软件
[root@centos1 ]# bin/amoeba start& [root@centos1 ]# netstat -anpt | grep java
.
测试读写分离
打开一台客户端192.168.1.10,也须要安装mysql,做为测试机,可使用yum -y install mysql安装。
.
创建防火墙规则 [root@centos1 /]# iptables -I INPUT -p tcp --dport 8066 -j ACCEPT . amoeba,主服务器和两个从节点,都须要开放3306端口入站 [root@centos1 /]# iptables -I INPUT -p tcp --dport 3306 -j ACCEPT [root@centos1 /]# service iptables save
.
也可修改amoeba的amoeba.xml配置文件的第一个8066改成3306以后创建一条防火墙规则为容许3306端口入站而且从新启动amoeba服务
<property name="port">3306</property> //在11行
这样一来测试机访问的时候后方就不用跟 P 8066 了
.
重启服务 [root@centos1 ]# bin/amoeba restart&
测试阶段
(客户端)
[root@centos1 ]# mysql -u amoeba -p 123456 -h 192.168.1.20 P 8066 密码123456,为:以前登录amoeba设置的密码
在主服务器master上建立一个数据库WLZS,同步到各从服务器上,而后关掉从服务器的slave功能,再插入数据。
(主服务器)
mysql> create database WLGCSZS; Query OK, 1 row affected (0.84 sec)
mysql> use WLGCSZS; Database changed
mysql> create table student(id int,name char(10)); Query OK, 0 rows affected (1.39 sec)
.
(从服务器查看同步)
mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | WLGCSZS | | IT | | mysql | | performance_schema | | test | +--------------------+ 5 rows in set (0.27 sec)
.
(主服务器写入数据)
mysql> insert into student values(1,'li'); Query OK, 1 row affected (0.48 sec)
.
(从服务器也同步了)
mysql> use WLGCSZS; Database changed mysql> select * from student; +------+------+ | id | name | +------+------+ | 1 | li | +------+------+ 1 row in set (0.45 sec)
.
在两台从服务器执行stop slave
分别在两台从服务器写入不一样数据
(节点A)
mysql> stop slave; Query OK, 0 rows affected (0.05 sec) mysql> use WLGCSZS; Database changed mysql> insert into student values(5,'jia'); Query OK, 1 row affected (0.07 sec)
.
(节点B)
mysql> stop slave; Query OK, 0 rows affected (0.05 sec) mysql> use WLGCSZS; Database changed mysql> insert into student values(6,'liang'); Query OK, 1 row affected (0.07 sec)
(客户端查询)
mysql> use WLGCSZS; Database changed mysql> select * from student; //第一次查询显示第一台从服务器的用户 +------+------+ | id | name | +------+------+ | 1 | li | | 4 | jia | +------+------+ 2 rows in set (0.00 sec)
mysql> select * from student; //第一次查询显示第二台从服务器的用户,说明负载均衡成功 +------+----------+ | id | name | +------+----------+ | 1 | li | | 5 | liang | +------+----------+ 2 rows in set (0.00 sec)
(客户端写入一条语句)
mysql> insert into student values(6,'asdf'); Query OK, 1 row affected (0.05 sec)
.
查询不到刚写入的语句,只有在主服务器能够查到由于写操做只有master有另外两台负责读取数据
mysql> select * from student; +------+------+ | id | name | +------+------+ | 1 | jia | | 4 | abcd | +------+------+ 2 rows in set (0.00 sec)
(客户端查询)
mysql> use WLGCSZS; mysql> select * from student; +------+-------+ | id | name | +------+-------+ | 1 | li | | 5 | jia | | 6 | liang | +------+-------+ 4 rows in set (0.00 sec)